piątek, 21 października 2011

How to set a bit(s) [AVR programming]

We want to set pins 0,2,5 to low and 1,3,4,6,7 to high.

How?
  • Binary number (works only on certain gcc compilers)
    PORTD = 0b11011010;
  • Hexadecimal number
    PORTD = 0xDA;
Changing a value of a specific bit to high. Let’s assume, our register looks like PORTD: 11011010 and we want only to change the value of the 2nd bit to one. We can use Boolean algebra disjunction like
PORTD |= (1 << bit_number);
In this case:
// set second bit high
PORTD |= (1 << 2);
11011010
00000100 |
11011110 (result)

We can also change several bits at the same time:
// sets pin 4 and 5 to logical one
PORTD |= (1 << 4) | (1 << 5);
Changing a value of a specific bit to low. It works almost the same as in the example above, except that logical conjunction and negation is used. When changing 3rd bit of PORTD to zero, the pattern looks like:
PORTD &= ~(1 << bit_number);
So: 
//sets third bit low
PORTD &= ~(1 << 3);
11011010
11110111 &
11010010 (result)

To change more than one bit, we use:
// sets pins 6 and 7 to logical zero
PORTD &= ~((1 << 6) | (1 << 7));

How to read a bit state? [AVR programming]

You can accomplish this in two simple ways - by using special functions like bit_is_set(Register,Bit number) / bit_is_clear(Register, Bit number) or by using some basic boolean algebra. First function  examines whether a bit is set, it returns a non-zero value if true. Second, works quite similar – it returns  zero when a bit is set, other values if it has been deleted. When using Boolean algebra, a basic knowledge of ANSI C programming is needed. This way is highly recommend, because any external library isn’t required – just regular C syntax.

Take a look at those examples:
// Check if a third bit of PORTD register is high 
//(instruction below return true if so)
bit_is_set(PORTD,3); // first option
PORTD & (1 << 3); // second option 
How does it works?
Let’s assume that PORTD looks like 11011010. There is high state on pins 1,3,4,6,7 and low on the rest.  If we want to check if pin 3 is active (high state) we must perform left bit shifting like 1 << 3 and examine the logical conjunction of those two.  

    11011010
& 00001000
    00001000

Which equals to decimal 8 (non-zero) – that means the third bit is set.