Yahoo Groups archive

AVR-Chat

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

Thread

Some C help please !

Some C help please !

2007-03-13 by kernels_nz

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

Re: Some C help please !

2007-03-13 by kernels_nz

Hi Alex,

Thanks for the quick response, I understand what the code does, just
not why a bitwise AND is performed and what (1<<UDRE) "means". In my
baby-C, I would probably have written 

while (UCSRA.x != 0); 

where x is the UDRE bit. Any advantages to the way it's done below ?

cheers
Hein B


--- In AVR-Chat@yahoogroups.com, "Alex Shepherd" <lists06@...> wrote:
>
> > while ((UCSRA & (1<<UDRE))==0);
> 
> Loop around checking the state of the UDRE bit in the UCSRA port
until the
> bit value is NOT 0
>

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

RE: [AVR-Chat] Some C help please !

2007-03-13 by Alex Shepherd

> while ((UCSRA & (1<<UDRE))==0);

Loop around checking the state of the UDRE bit in the UCSRA port until the
bit value is NOT 0

Re: [AVR-Chat] Re: Some C help please !

2007-03-13 by np np

<< is a lshift left
>> is a shift right

www.ckp-railways.talktalk.net/pcbcad21.htm


kernels_nz <kernels@slingshot.co.nz> wrote:                                  Hi Alex,
 
 Thanks for the quick response, I understand what the code does, just
 not why a bitwise AND is performed and what (1<<UDRE) "means". In my
 baby-C, I would probably have written 
 
 while (UCSRA.x != 0); 
 
 where x is the UDRE bit. Any advantages to the way it's done below ?
 
 cheers
 Hein B
 
 --- In AVR-Chat@yahoogroups.com, "Alex Shepherd" <lists06@...> wrote:
 >
 > > while ((UCSRA & (1<<UDRE))==0);
 > 
 > Loop around checking the state of the UDRE bit in the UCSRA port
 until the
 > bit value is NOT 0
 >
 
 
     
                       

 		
---------------------------------
 New Yahoo! Mail is the ultimate force in competitive emailing. Find out more at the Yahoo! Mail Championships. Plus: play games and win prizes.

[Non-text portions of this message have been removed]

RE: [AVR-Chat] Re: Some C help please !

2007-03-13 by Alex Shepherd

> Thanks for the quick response, I understand what the code 
> does, just not why a bit wise AND is performed and what 
> (1<<UDRE) "means". In my baby-C, I would probably have written 

(1<<UDRE)

Means:

	The integer value 1, bit shifted left by the integer value of UDRE
(5) as defined in the header file.

This will give a binary value of 00010000 or 0x10 which is then ANDed with
the UCSRA port to mask off the value of the UDRE bit, then loop while it is
not set.

> while (UCSRA.x != 0); 
> 
> where x is the UDRE bit. Any advantages to the way it's done below ?

Well, I think some other compilers may do this sort of thing and there was
some discussion a while ago about this approach with AVR-GCC but AFAICT the
(1<<UDRE) approach is the current preferred way of doing this with AVR-GCC.

Alex

Re: [AVR-Chat] Re: Some C help please !

2007-03-13 by David VanHorn

>
>
>   Which is perfectly fine if UCSRA is defined to work that way.  I
> often define structs for SFRs so that I'd do something like:
>
> while (UCSRAbits.UDRE != 0)


This certainly is a lot easier to read.
I try to avoid reversed inversions of negative logic inverted.

I would also hope that the compiler would end up with the same asm for both
cases, but maybe I'm being too optimistic?   If it's not something that
executes a lot then I wouldn't worry about it.


[Non-text portions of this message have been removed]

Re: [AVR-Chat] Some C help please !

2007-03-13 by Ivan Vernot

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 ----- 
Show quoted textHide quoted text
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
>
>
>
>

Re: [AVR-Chat] Re: Some C help please !

2007-03-13 by Dennis Clark

See below:

kernels_nz wrote:
> Hi Alex,
> 
> Thanks for the quick response, I understand what the code does, just
> not why a bitwise AND is performed and what (1<<UDRE) "means". In my

   It means shift the '1' to the left UDRE places.  It is common short 
hand in C.

> baby-C, I would probably have written 
> 
> while (UCSRA.x != 0); 

   Which is perfectly fine if UCSRA is defined to work that way.  I 
often define structs for SFRs so that I'd do something like:

while (UCSRAbits.UDRE != 0)

> where x is the UDRE bit. Any advantages to the way it's done below ?

Do it each way and see which one compiles to a smaller assembly block, 
and use that one. :)

DLC

> cheers
> Hein B
> 
> 
> --- In AVR-Chat@yahoogroups.com, "Alex Shepherd" <lists06@...> wrote:
> 
>>>while ((UCSRA & (1<<UDRE))==0);
>>
>>Loop around checking the state of the UDRE bit in the UCSRA port
> 
> until the
> 
>>bit value is NOT 0
>>
> 
> 
> 
> 
> 
> 
>  
> Yahoo! Groups Links
> 
> 
> 

-- 
---------------------------------------
Dennis Clark    TTT Enterprises
---------------------------------------

Re: [AVR-Chat] Re: Some C help please !

2007-03-13 by Dave Hylands

Hi Hein,

> Thanks for the quick response, I understand what the code does, just
> not why a bitwise AND is performed and what (1<<UDRE) "means". In my
> baby-C, I would probably have written
>
> while (UCSRA.x != 0);
>
> where x is the UDRE bit. Any advantages to the way it's done below ?

Bitfields aren't portable across compilers. The order of the bits
within the bytes, and exactly how many bits are needed, and other
details are all defined as implementation specific.

It isn't even required that they be the same from one version of the
compiler to the next.

Using bitmasks, though, is extremely portable, and you get exactly
what you want. You can also initialize several fields simulataneously
using bitmasks.

I'll often do stuff like:

#define UART0_DATA_BIT_8  (( 1 << UCSZ01 ) | ( 1 << UCSZ00 ))
#define UART0_PARITY_NONE (( 0 << UPM01 )  | ( 0 << UPM00 ))
#define UART0_STOP_BIT_1  ( 1 << USBS0 )

    UCSR0C = ( UART0_DATA_BIT_8 | UART0_PARITY_NONE | UART0_STOP_BIT_1 );

which would require 3 separate assignments with bitfields.

-- 
Dave Hylands
Vancouver, BC, Canada
http://www.DaveHylands.com/

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.