Hein,
The line while ((UCSRA & (1<<UDRE))==0); 'decodes' as follows
Somewhere in you compilers include files there will be a definition like
#define UDRE 5
thus 1<<UDRE is actually 1<<5
You should know that << means shift right in C. So
1 = 0000 0001
1<<5 = 0010 0000 = 0x20
so the statement evaluates to 'UCSRA & 0x20'
which means - read the UCSRA register and perform a logical AND with the
value 0x20
so.
if UCSRA = 0x10 then 0x10 & 0x20 = 0x00
if UCSRA = 0x20 then 0x20 & 0x20 = 0x20
so,
while ((UCSRA & (1<<UDRE))==0);
means
loop while bit 5 in UCSRA is 0
ie. wait for bit 5 in UCSRA to go high.
Why do you care abut bit 5 high? Well you'll need to look at the data sheet
as it depends on how UCSRA and UDRE are defined for YOUR micro.
Having said that, it is most probably that you are simply waiting for the
UART Receive Register to be filled
ie For a byte to be received by the uart. :-)
Although it may look complicated this construct is common and a decent
compiler will generate a very compact 'bit test then branch' code sequence
You can use a similar construct to Set and Clear bit in a byte value in
compact and elegant manner.
For example I have macros like
#define SET_BIT(reg,bit) ( (reg) |= (1<<(bit)) )
#define CLR_BIT(reg,bit) ( (reg) &= ~(1<<(bit)) )
Which allows me to set and clear bit in a more intuitive manner
i.e. You can do something like
SET_BIT(PORTA,3)
CLR_BIT(PORTC,0)
An event better approach is to use the technique to 'abstract' the control
of I/O doe the hardware specifics
#define LED_PKT_RXD() (CLR_BIT(PORTC,3)) // turn on green
led - active low drive)
#define LED_LINK_FAIL() (CLR_BIT(PORTD,0)) // turn on RED
led - active low drive)
#define LED_LINK_GOOD() (SET_BIT(PORTD,0)) // turn OFF RED
led - active low drive)
#define MOTOR_ON() (SET_BIT(PORTA,7)) // active
high drive)
#define IS_BUTTON_PRESSED() ((PINA & (BIT(1))== 0) // true when button
is pressed - active low)
so in my code is have
if(IS_BUTTON_PRESSED())
{
MOTOR_ON();
}
if(pkt_received ==TRUE)
{
LED_PKT_RXD() ;
LED_LINK_GOOD();
}
else
{
LED_LINK_FAIL();
}
Thus if the hardware I/O changes I change the macros in an include file and
no more search and replace looking for individual bit sets and bit clears
Finally a comment on 'style'
IMO having a ; at the end of the while() is to prone to error
Consider the fragment
while ((UCSRA & (1<<UDRE))==0);
{
i++;
printf("Waiting:%d\n",i);
}
one has to look very carefully to realise that we will not be printing lots
of 'Waiting N' lines!!!
When a while() is just 'spinning busy' I much prefer to explicitly show it -
ie
while ((UCSRA & (1<<UDRE))==0)
{
// do nothing
}
HTH
Ivan Vernot
----- Original Message -----
From: "kernels_nz" <kernels@slingshot.co.nz>
To: <AVR-Chat@yahoogroups.com>
Sent: Wednesday, March 14, 2007 8:52 AM
Subject: [AVR-Chat] Some C help please !
> Hi guys, Ive been programming in C for a while now, but my C tends to
> be "baby C", in that I probably don't write things as simple as they
> can be written. . . Could someone please explain the entire purpose of
> the following line, particularly the 1<<UDRE and why a bitwise AND is
> being performed with UCSRA. I understand what the code does in the
> microcontroller, just not what the statement in the brackets is saying.
>
> while ((UCSRA & (1<<UDRE))==0);
>
> Please dont be afraid to insult me by explaining it simple, im very
> keen to improve my coding level as my jobs become more complex.
>
> Thanks
> Hein B
> Auckland, NZ
>
>
>
>
>
> Yahoo! Groups Links
>
>
>
>Message
Re: [AVR-Chat] Some C help please !
2007-03-13 by Ivan Vernot
Attachments
- No local attachments were found for this message.