Atmega8 Sleep mode doesn't work with USART

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View


I'd like to use sleep operation with USART but when I use USART with
sleep operation, the system was crashed.

my code like this.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <stdio.h>

void Uart_Put_Char(unsigned char data)
    while ( !( UCSRA & (1<<UDRE)) );
    UDR = data;

void Hardware_Init(void)
    MCUCR = 0xb0;
    UBRRL = 16;
    UCSRA = 0x00;
    UCSRB = 0x18;


void main(void)

        __asm volatile ("sleep");

but when I comment like this

// __asm volatile ("sleep");

my code works fine.

I really wanna use sleep with USART.
Could you tellme why ?


Re: Atmega8 Sleep mode doesn't work with USART

Quoted text here. Click to load it

If you go to sleep mode, something has to happen to make the AVR wake up
from sleep mode. This is usually a reset or an interrupt. In your code, you
don't use interrupts on the UART, so when you enter sleep mode, the AVR
stays there.


Re: Atmega8 Sleep mode doesn't work with USART

Thank you Meindert Sprang.

But It's a little bit different. In my case, I fix code like below.

void main(void)

                __asm volatile ("sleep");

and My system doesn't print even "A".

I think something wrong.
Do you know why ?

Re: Atmega8 Sleep mode doesn't work with USART

Quoted text here. Click to load it

That is most likely because you put the AVR to sleep before the "A" has left
the UART. Your Uart_Put_Char() first checks the UDRE bit, then it loads a
new byte in the UDR register. If you then call "sleep", the AVR goes to
sleep before the UART has  finished shifting the byte out. Checking for UDRE
*after* the write to UDR doesn't help either because the UART is double
buffered. UDRE flags the state of the UDR register and not the shift
register. To test this, insert

    while ( !( UCSRA & (1<<TXC)) );

before the "sleep" instruction. This will test if the shifter is really
empty and thus you have seen the "A" appear.


Re: Atmega8 Sleep mode doesn't work with USART

Quoted text here. Click to load it
If his uart transmit routine were interrupt driven then the avr
might go to sleep and wake up in the transmit routine.  Note that
there are different sleep modes you can specify, and some of them
will NOT allow the uart to run, there is a mode that WILL allow the
uart to receive data while the cpu is asleep and you need to use
that mode to wake up on a character received.  Of course the power
savings isn't as great with this mode.....

BTW, I'm working on a project with a mega128 avr using external
ram.  In putting this one to sleep I first disabled external memory
mode so the chip select of the ram (wired to A15) would go high to
save the current pulled by the selected ram chip (dropped about
30ma!).  But to do this I first had to relocate the stack to internal
ram (I'll leave the reason for this as an excerise for the reader!).
The stack is restored after the cpu wakes up.  The cpu is put to sleep
in mainline code, ANY interrupt will wake up the cpu, and after
returning from interrupt we are at the instruction AFTER the sleep
instruction.  NOTE that the interrupt code must NOT access any data
in external ram!  (think of all the fun I am having with this!)

Re: Atmega8 Sleep mode doesn't work with USART

You have to wait for the characyter to lkeave the uart --- then goto sleep.
I use ATMEGA128 with UART and also with external 32KHz xtal on
timer 0 for power save modes.  So far I'm down to 35uA.  Be careful
with external pull-ups, make sure ports are configured for input lest the
chew up power while in sleep.  Shut everything else off --- including
JTAG debug interface, analog comparator, and watchdog timer
(can be done in software), otherwise you will not get anywhere near
10's of uA.

David Howard

Quoted text here. Click to load it

Site Timeline