[Wiltshire] Random C coding question...
RobertCL at iname.com
Tue Apr 22 14:40:29 BST 2008
On Tue, April 22, 2008 2:09 pm, David Fletcher wrote:
> At 13:50 22/04/2008, you wrote:
>>Fairly random question, kind of related to linux, I'm hoping someone on
>>here might be able to answer as it is C-related (and lots of linux things
>>are C) and I can't think how to google for the answer or where else to
>>ask. (putting "1<<" into google isn't helpful!)
>>Can someone explain to me the significance of 1<<PB1 in the following
>> // gerneral purpose LED
>> /* set output to Vcc, red LED off */
>> #define LED1OFF PORTB|=(1<<PB1)
>> /* set output to GND, red LED on */
>> #define LED1ON PORTB&=~(1<<PB1)
>>What is it doing? Why "1" and what does << do / mean / what is going on.
>>A bit of background may be required I guess, I'm not a C programmer, but
>>do recall from a C++ book I once read things like 'cout << "some text"',
>>so I'm guessing it's some kind of redirect or pipe type thing.
>>The code extract is from some AVR code I'm playing with and I know what
> Thought it looked like embedded code.
> See page 49 of "The C Programming Language" second edition by Brian W
> Kernighan and Dennis M Ritchie.
> There you will see that << is the leftwards bit shifting operator, so
> if PB1 has value 0 the result is 1. If PB1 has the value 3 the result
> will be 8 i.e. bit 3 set. PORTB| performs a logical OR of the value
> of portB with the bit shift result to switch off the LED. As I
> recall, the AVR pins can sink current nicely but not source it, hence
> the LED will be connected via a resistor to Vcc, and setting the port
> high will therefore switch off the LED.
> PORTB& performs a logical AND with the inverted bit shifted result.
> The ~ inverts all the bits of the shift operation. So the selected
> bit of the port is set low, switching on the LED.
So PORTB can be thought of as eight 1's or 0's depending on the state of
the various inputs / outputs. eg all off PORTB "=" 00000000
If we assume PBx = x, so PB1 = 1 then,
(1<<PB1) "=" 00000010
then PORTB |= (1<<PB1) results in PORTB set to 00000010 - the OR will
leave any existing bits set to their current value and the 1 will be set
to 1 regardless of the current state of the bit before hand.
~(1<<PB1) "=" 11111101
so and-ing that to PORTB "=" 00000010 definitely clears the 1 and any
others that are 1 will remain as 1 and those that are 0 will stay 0.
Hmm, yes, that makes sense now :-) Thats basically what I guessed was
going on - with the eight 1's and 0's and somehow bits being switched on
and off, I just couldn't quite see how the code was achieving it or where
"1" fitted in!
Thanks David and Pete.
I might ask some more questions later when I come across something else
that I don't understand :-)
More information about the Wiltshire