Hello,
I have some problems with port initialization on ATMEGA16: I have some examples and I seek also in the datasheet and I didn't understand what means to initialize: PORTA (or PORTB, PORTC, PORTD, doesn't matter) or DDRA (or B, C, D) with a hexadecimal value -- I know that every bit means something but I don't understand this: if bit is high "1", what really means, neither for bit low "0" for PORT and DDR.
I have also seen an example with _BV(something), I don't understand basically what function is doing.
//bit 0 of Port B is output, rest are automatically inputs
DDRB = _BV(0);
//bit 0 of Port B is input, rest are automatically outputs
DDRB = ~_BV(0);
//bit 0 and bit 1 of Port B are outputs, rest are automatically inputs
DDRB = _BV(0) | _BV(1);
//bit 0 and bit 1 of Port B are inputs, rest are automatically outputs
DDRB = ~( _BV(0) | _BV(1) );
I guess _BV(0) sets output the bit zero of a port and ~_BV(0) sets input.
_BV(X) ; X=0 -> 7; what is a doubt for me is _BV(X)=pow(2,X) or _BV(X)=~pow(2,X) (bit X is set or is cleared? ).
I want also SBI to be explained SBI and CBI and how can I do the same thing without using these functions.
Thanks in advance.
Thanks in advance.
Port initialization with ATMEGA16
-
- Corporal
- Posts: 7
- Joined: Mon Jun 28, 2010 10:25 pm
Re: Port initialization with ATMEGA16
Dear Friend ,
_BV is a macro used for set and clear bits in registers.
As a example ,
DDRB = _BV(4) ( We write 10000 binary value to DDRB register )
If we want to change the 4th bit only in DDRB register , without effecting to other values in DDRB register
we can write it as DDRB |=_BV(4) ( This means we logical OR the current value of DDRB register with 10000 bits )
So this is the ideal way to set a bit in particular register
And if we want to clear a particular bit in a register , without effecting to other bits in that register we can write it as follows,
DDRB &= ~_BV(4) ( This means we Logical AND the current value of DDRB register with inverse value of 10000
Inverse value (NOT ) of 10000 = 11101111
So DDRB &=~_BV(4) = DDRB AND 11101111
So you can see you can make the 4th bit of DDRB register 0 , without effecting to other values of DDRB
SBI and CBI also some macros
as a example
sbi(PORTA,5) = make 5th bit of PORTA as 1
cbi(PORTA,5) = make 5th bit of PORTA as 0
So this also you can implement in several ways and you can use _BV to implement same thing with out using sbi and cbi
sbi(PORTA,5) can write as PORTA |=_BV(5)
cbi(PORTA,5) can write as PORTA &= ~_BV(5)
And regarding bit setting
You can control the direction of particular port with DDR registers
eg DDRA = 11110000 means 0 to 3rd pins of PORT A are input pins and 4 to 7 pins are output pins
if you write PORTA = 11110000 , then you can make 4 to 7 pins of PORT A register high , that mean if you connect 4 LED bulbs with a resistor for those pins , you can see they are on
I think this explanation answer all your questions , if you have further questions please drop them on robot.lk
Good Luck...
Magneto
_BV is a macro used for set and clear bits in registers.
As a example ,
DDRB = _BV(4) ( We write 10000 binary value to DDRB register )
If we want to change the 4th bit only in DDRB register , without effecting to other values in DDRB register
we can write it as DDRB |=_BV(4) ( This means we logical OR the current value of DDRB register with 10000 bits )
So this is the ideal way to set a bit in particular register
And if we want to clear a particular bit in a register , without effecting to other bits in that register we can write it as follows,
DDRB &= ~_BV(4) ( This means we Logical AND the current value of DDRB register with inverse value of 10000
Inverse value (NOT ) of 10000 = 11101111
So DDRB &=~_BV(4) = DDRB AND 11101111
So you can see you can make the 4th bit of DDRB register 0 , without effecting to other values of DDRB
SBI and CBI also some macros
as a example
sbi(PORTA,5) = make 5th bit of PORTA as 1
cbi(PORTA,5) = make 5th bit of PORTA as 0
So this also you can implement in several ways and you can use _BV to implement same thing with out using sbi and cbi
sbi(PORTA,5) can write as PORTA |=_BV(5)
cbi(PORTA,5) can write as PORTA &= ~_BV(5)
And regarding bit setting
You can control the direction of particular port with DDR registers
eg DDRA = 11110000 means 0 to 3rd pins of PORT A are input pins and 4 to 7 pins are output pins
if you write PORTA = 11110000 , then you can make 4 to 7 pins of PORT A register high , that mean if you connect 4 LED bulbs with a resistor for those pins , you can see they are on
I think this explanation answer all your questions , if you have further questions please drop them on robot.lk
Good Luck...
Magneto
-
- Lieutenant
- Posts: 92
- Joined: Tue Oct 27, 2009 7:50 pm
Re: Port initialization with ATMEGA16
If you know the shift operator in C, you can do this.
For example
you have led connected with PB4 and want to toggle it at 500ms.where led is active low.
#include.........
#define LED PB4
#define LED_PORT PORTB
#define LED_DDR DDRB
void delay_ms(unsigned int);
int main()
{ LED_DDR|=1<<LED;
while(1)
{ LED_PORT|=(1<<LED); // LED is OFF
delay_ms(500);
LED_PORT&=~(1<<LED); // LED is ON
delay_ms(500);
}
}
you can too write the program this way.
For example
you have led connected with PB4 and want to toggle it at 500ms.where led is active low.
#include.........
#define LED PB4
#define LED_PORT PORTB
#define LED_DDR DDRB
void delay_ms(unsigned int);
int main()
{ LED_DDR|=1<<LED;
while(1)
{ LED_PORT|=(1<<LED); // LED is OFF
delay_ms(500);
LED_PORT&=~(1<<LED); // LED is ON
delay_ms(500);
}
}
you can too write the program this way.