Write a Program to Toggle All the Bits of Portb and Portd Continuously

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 ?

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.

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.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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? ;)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

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.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

theusch wrote:

IMO save the effort for more important things.

Agreed. I thought the smilie gave it away...

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

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 .

Asking - you need to read the bit manipulation tutorial methinks. See the tutorial section.

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?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

Quote:


#define TOGGLE_STATUS_LED() (PINB=1<<5)

Arghhhh...! A MACRO! My eyes, my eyes...! :wink:

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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:

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.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

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)

epperlyalich1965.blogspot.com

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

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel