Awesome, thanks for the responses, makes perfect sense now, never
occurred to me that 1 << 5 is just 0x20.
Cheers
Hein B
--- In AVR-Chat@yahoogroups.com, "Ivan Vernot" <ivernot@...> wrote:
>
> 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@...>
> 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.Show quoted textHide quoted text
> >
> > 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
> >
> >
> >
> >
>