Apr 11, 2009
Bit operations with AVR-GCC
Bit operations are used when interfacing with digital out such as switching pins On/Off. Programming with bit operations enable following functions to control digital out.
- Switching pins on (for example, turning on LED)
- Switching pins off (for example, turning off LED)
- Toggling pins (for example, Turning of LED if it is on and vice versa)
Bit operations: &, |, ^, >>, <<, ~
& – bitwise AND
DDRB = 0b11110000;
DDRB &= 0b00010000;
-> DDRB = 00010000
| – bitwise Inclusive OR (Switch on bit)
DDRB = 0b00000000;
DDRB |= 0b00010000;
-> DDRB = 00010000
Example a:
PORTB |= (1<<PB5); //Put Port B bit 5 HIGH
Example b:
PORTB = (1<<PB2)|(1<<PB5); //Put Port B bit 2 and 5 HIGH
– >
00000000
AND
00000100
OR
00100000
=
00100100
^ – bitwise Inclusive OR (Toggle bits on/off)
DDRB = 0b0001001;
DDRB ^= ob00010000;
-> DDRB = 00000001
Example:
PORTD ^= (1<<PD6); // Toggle PortD bit 6
<< – Left shift
DDRB = ob10000000;
DDRB |= (1<<5);
-> DDRB = 10010000
~ – One’s complement (Switch off bits)
DDRB = 0b11111111;
DDRB &= ~(1<<5);
-> DDRB = 11101111
Example:
PORTD &= ~(1<<PD5); // Put PortD bit 5 LOW
This code is for excersizing bit operations to manage digital output.
main.c
// Title: Experiencing switching and toggle pins on/off
// Description:
// Each Arduino pin 5, 6 and 7 pin is connected to a LED.
// This code is for excersizing bit operations to manage digital output.
// AVR-GCC uses bit operations heavily to interface I/O.
// Atmega8 PortD bit | Arduino pin
// 5 | 5
// 6 | 6
// 7 | 7
#include <avr/io.h>
#include <util/delay.h>
void delay(int);
int main(void){
// put PortD bit 5, 6 and 7 as output
DDRD = (1<<PD5)|(1<<PD6)|(1<<PD7);
for(;;){
//***** Exercising HIGH and LOW
PORTD |= (1<<PD5); // Put PortD bit 5 HIGH
delay(1000);
PORTD = PORTD | (1<<PD6) | (1<<PD7); // Put PortD bit 6 and 7 HIGH
delay(1000);
PORTD &= ~(1<<PD5); // Put PortD bit 5 LOW
delay(1000);
PORTD = PORTD & ~(1<<PD6) & ~(1<<PD7); // Put PortD bit 6 and 7 LOW
delay(3000);
//***** Exercising TOGGLE
PORTD ^= (1<<PD6); // Toggle PortD bit 6
delay(1000);
PORTD = PORTD ^ (1<<PD5) ^ (1<<PD7); // Toggle PortD bit 5 and 7
delay(1000);
PORTD = PORTD ^ (1<<PD5) ^ (1<<PD6) ^ (1<<PD7); // Toggle PortD bit 5, 6 and 7
delay(5000);
// Result shows following LED flow
// Aruduion pin | 5 | 6 | 7
// | | | Exercise HIGH and LOW
// | * | |
// | * | * | *
// | | * | *
// | | | Exercise TOGGLE
// | | * |
// | * | * | *
// | | |
}
return 0;
}
void delay(int ms) {
ms /= 100;
char i;
for(i = 0; i < ms; i++){
_delay_ms(100); // max is 262.14 ms / F_CPU in MHz
}
}
I learned quite a bit, very good post!