Port initialization with ATMEGA16

Microcontroller Topics
Post Reply
Ibanitescu
Corporal
Corporal
Posts: 7
Joined: Mon Jun 28, 2010 10:25 pm

Port initialization with ATMEGA16

Post by Ibanitescu » Tue Jun 29, 2010 12:06 pm

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.
User avatar
Magneto
Major
Major
Posts: 430
Joined: Wed Jul 15, 2009 1:52 pm
Location: London

Re: Port initialization with ATMEGA16

Post by Magneto » Wed Jun 30, 2010 10:47 am

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
SukhdeepMankoo
Lieutenant
Lieutenant
Posts: 92
Joined: Tue Oct 27, 2009 7:50 pm

Re: Port initialization with ATMEGA16

Post by SukhdeepMankoo » Wed Jun 30, 2010 3:55 pm

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.
Post Reply

Return to “Microcontrollers”