Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

Re: Some C help please !

2007-03-13 by kernels_nz

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

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.