Pages: 1 [2]   Go Down
Author Topic: Arduino - Coding without delays using program Ticks  (Read 1223 times)
0 Members and 1 Guest are viewing this topic.
Westbrook, CT
Offline Offline
Full Member
***
Karma: 2
Posts: 139
"Why should I bother with made-up games when there are so many real ones going on." (c) Kurt Vonnegut
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I like how this post became into a "hot" post  smiley-razz  smiley
Logged

Arduino Uno R3
Mac OSX Lion


SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 106
Posts: 6367
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Code:
PINB = PINB | _BV (5);
What if input zero is already high?  We end up with this...
  :
...which toggles two pins!
This is actually a really interesting question.
Code:
PORTB |= _BV(5);
is well-known to compile down to a single "set bit in IO register" (sbi) instruction.  If it didn't, the assembler-lovers would gloat too much.
The sbi instruction, theoretically, does a read-modify-write of the bytewide port, down at the hardware level (which is why it takes two cycles rather than just one.)
But the datasheet EXPLICITY says that "the SBI instruction can be used to toggle one single bit in a port", so it's not quite as straightforward as that.
PROBABLY, the statement above will compile to a single sbi instruction (at least with optimization on), and probably it will only toggle the single bit.

But wait - not all of PINx registers are reachable by "sbi."  If you were working with PINL on a MEGA, the compiler would have to generate a read, or, and out instructions.  And it would behave DIFFERENTLY...

What fun!
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 176
Posts: 12285
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What fun!

No doubt!

So, to illustrate the problem on an Uno we need to cripple the optimizer.  This may do it...
Code:
#define ALT_PINB  (*((uint8_t volatile *)0x23))
...
  ALT_PINB = ALT_PINB | _BV(5);
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 176
Posts: 12285
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've been searching my history for where I got that "  PINB |= _BV (5) is better than PINB = _BV (5) " technique from.

It is not a question of which is better.  It is a question of which is correct.  This is simply not correct...
Code:
PINB |= _BV (5);

As @westfw described, that it works at all is an accident (a side-effect of the compiler's optimization, the AVR instruction set, and the location of the PIN register in the I/O space).
Logged

Pages: 1 [2]   Go Up
Jump to: