Write a Program to Toggle All the Bits of Portb and Portd Continuously
Level: Hangaround
Joined: Fri. May 30, 2014
Posted by asking : Thu. Jun 5, 2014 - 06:58 AM
Hi,
I tried to toggle port Bit On / off using
PORTD |= (1<<PORTD7); PORTD |= (0<<PORTD7);
but its not working.
Searching more i found
PORTD |= _BV(PD7); PORTD &= ~_BV(PD7);
Which seems to be working...
is there any other way out to toggle individual port ?
Level: Moderator
Joined: Mon. Jul 18, 2005
Location: (using avr-gcc in) Finchingfield, Essex, England
Posted by clawson : Thu. Jun 5, 2014 - 09:11 AM
Quote:
and check that the compiler actually generates the single SBI opcode for it.
Do you know of any AVR compiler that actually does that? That is it converts:
to
I don't believe any of them perform that particular parlour trick. I would love to be proved wrong.
Level: 10k+ Postman
Joined: Wed. Mar 27, 2002
Location: Lund, Sweden
Posted by JohanEkdahl : Thu. Jun 5, 2014 - 10:43 AM
Darn..
No, I never have investigated this myself.
If the compiler does not do this, then it will be necessary (at least in some cases) to take height for the non-atomicity of the operation. Now some of the point with keeping it tidy (C-wise)(IMO) is lost.
Level: 10k+ Postman
Joined: Tue. Jul 17, 2012
Location: Location, Location
Posted by joeymorin : Thu. Jun 5, 2014 - 05:24 PM
clawson wrote:
I don't believe any of them perform that particular parlour trick. I would love to be proved wrong.
That would tend to violate rules surrounding volatile access, wouldn't it? I'd guess that if you write:
... the compiler is obliged to touch PORTB. It is an feature of the hardware, not the language, which allows you to substitute PINx for PORTx.
Of course the same could be argued regarding the behaviour that replaces:
in r24, PORTB ori r24, (1<<5) out PORTB, r24
... with:
... in this case the result is exactly the same: bit 5 in PORTB is set. There are no side-effects to reading (or not reading) PORTB, nor in writing (or not writing) the adjacent bits.
In the case of toggling:
ldi r25, (1<<5) in r24, PORTB eor r24, r25 out PORTB, r24
... replaced with:
ldi r24, (1<<5) out PINB, r24
... again the result is exactly the same: bit 5 in PORTB is toggled. Again, there are no side-effects.
The difference in the latter case is that a different I/O register is accessed. I expect this is far enough outside the constraints of volatile access for it to be excluded. Given the lack of any side-effects however, it does seem a safe optimisation to make. Do you think a feature request will be well-received? ;)
JohanEkdahl wrote:
If the compiler does not do this, then it will be necessary (at least in some cases) to take height for the non-atomicity of the operation. Now some of the point with keeping it tidy (C-wise)(IMO) is lost.
True, but there is always atomic.h:
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { PORTB ^= (1<<5); }
The down-side is that the ATOMIC_BLOCK wrapper can be dropped if the body of the bock is reduced to a single machine instruction. Another feature request? ;)
Level: 10k+ Postman
Joined: Mon. Feb 19, 2001
Location: Wisconsin USA
Posted by theusch : Thu. Jun 5, 2014 - 06:06 PM
Quote:
Do you think a feature request will be well-received?
I'd have to hunt out the prior threads, but IMO/IME "much ado about nothing".
In any real app,how often do you actually toggle a port bit for important purposes? I tend to only use it for relatively trivial ends, such as toggling a port pin in an ISR for 'scope/LED indication.
IMO save the effort for more important things.
Level: 10k+ Postman
Joined: Mon. Feb 19, 2001
Location: Wisconsin USA
Posted by theusch : Thu. Jun 5, 2014 - 06:11 PM
Quote:
Now some of the point with keeping it tidy (C-wise)(IMO) is lost.
IME as these operations come up rarely...
#define TOGGLE_STATUS_LED() (PINB=1<<5)
...looks like
in the code. One can always make a more elaborate macro.
Level: 10k+ Postman
Joined: Tue. Jul 17, 2012
Location: Location, Location
Posted by joeymorin : Thu. Jun 5, 2014 - 07:06 PM
theusch wrote:
IMO save the effort for more important things.
Agreed. I thought the smilie gave it away...
Level: Raving Lunatic
Joined: Sun. Oct 29, 2006
Posted by skeeve : Thu. Jun 5, 2014 - 07:13 PM
theusch wrote:
In any real app,how often do you actually toggle a port bit for important purposes? I tend to only use it for relatively trivial ends, such as toggling a port pin in an ISR for 'scope/LED indication.
I've done it, in assembly, for high-speed bit-banging.
That said, if one really wants:
#define toggle(p, mask) \ if(HAS_PIN_TOGGLE) PIN ## p =(mask); else PORT ## p ^=(mask); #define atomic_rs_toggle(p, mask) \ if(HAS_PIN_TOGGLE) PIN ## p =(mask); \ else { \ char scratch; \ asm (" IN __tmp_reg__, __SREG__\n" \ " CLI\n" \ " IN #[scratch], #[port]\n" \ " XOR #[scratch], #[mask]\n" \ " OUT __SREG__, __tmp_reg__\n" \ " OUT #[port], #[scratch]" : [scratch] "=r"(scratch) : \ [port] "I" (_SFR_IO_ADDR( PORT ## p )), \ [mask] "r" ((char)(mask)) ); \ } #define atomic_fo_toggle(p, mask) \ if(HAS_PIN_TOGGLE) PIN ## p =(mask); \ else { \ asm( " CLI\n" \ " IN __tmp_reg__, #[port]\n" \ " XOR __tmp_reg__, #[mask] \ " SEI\n" \ " OUT #[port], __tmp_reg__\n" : : [port] "I" (_SFR_IO_ADDR( PORT ## p )), \ [mask] "r"((char)(mask)) ); \ }
'Tis up to the user to #define HAS_PIN_TOGGLE .
Level: 10k+ Postman
Joined: Thu. Dec 30, 2004
Location: Melbourne,Australia
Posted by Kartman : Thu. Jun 5, 2014 - 10:33 PM
Asking - you need to read the bit manipulation tutorial methinks. See the tutorial section.
Level: 10k+ Postman
Joined: Tue. Jul 17, 2012
Location: Location, Location
Posted by joeymorin : Fri. Jun 6, 2014 - 01:04 AM
skeeve wrote:
'Tis up to the user to #define HAS_PIN_TOGGLE .
Now that might be worth a feature request. How hard can it be for AVR Libc to include a single macro in the header files for devices which support it?
Level: 10k+ Postman
Joined: Wed. Mar 27, 2002
Location: Lund, Sweden
Posted by JohanEkdahl : Fri. Jun 6, 2014 - 07:49 AM
Quote:
#define TOGGLE_STATUS_LED() (PINB=1<<5)
Arghhhh...! A MACRO! My eyes, my eyes...! :wink:
Level: 10k+ Postman
Joined: Mon. Feb 19, 2001
Location: Wisconsin USA
Posted by theusch : Fri. Jun 6, 2014 - 01:07 PM
Quote:
I've done it, in assembly, for high-speed bit-banging.
Indeed. then in your bit-bang loop you are well aware of PINx writes for the feature. In fact, you probably tackled the whole thing with the knowlege of the single-instruction toggle. Just do it. (A corollary is bit-banging e.g. I2C -- the bit is turned on/off by manipulating the DDRx bit, not the PORTx bit.)
Quote:
How hard can it be for AVR Libc to include a single macro in the header files for devices which support it?
[flame bait] What AVR8 apps designed fresh in the last 10 years or so use an AVR8 model >>without<< that feature?
Level: Moderator
Joined: Mon. Jul 18, 2005
Location: (using avr-gcc in) Finchingfield, Essex, England
Posted by clawson : Fri. Jun 6, 2014 - 02:54 PM
What would be the point of a one line macro anyway? What? Something like:
#define TOGGLE(p, n) PIN ## p = _BV(n)
or similar? Why wouldn't the programmer just write:
rather than:
What does the macro actually gain you in this circumstance? It's a bit like these:
macros that people use. How does that really help compared to:
Level: 10k+ Postman
Joined: Tue. Jul 17, 2012
Location: Location, Location
Posted by joeymorin : Fri. Jun 6, 2014 - 04:21 PM
clawson wrote:
What does the macro actually gain you in this circumstance?
It can be changed to this for older devices:
#define TOGGLE(p, n) PORT ## p ^= _BV(n)
... or something similar to skeeve's suggestions for atomicity.
Level: Raving Lunatic
Joined: Sun. Oct 29, 2006
Posted by skeeve : Fri. Jun 6, 2014 - 05:16 PM
I over-simplified the macros for ease of exposition.
Instead of ## I would invoke the paste macro
#define xpaste(x, y) x ## y
#define paste(x, y) xpaste(x, y)
That way one could do something like
#define LCD_LETTER B
#define LCD_BIT 3
...
toggle(LCD_LETTER, 1<<LCD_BIT);
even
#define toggle2(x) toggle(paste(x, _LETTER, 1<<paste(x, _BIT))
...
toggle2(LCD)
Source: https://www.avrfreaks.net/forum/toggle-single-port-bit-alternative
0 Response to "Write a Program to Toggle All the Bits of Portb and Portd Continuously"
Post a Comment