1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

Atmega8 Sleep mode doesn't work with USART

Discussion in 'Embedded' started by ilovecpp, Jul 20, 2005.

  1. ilovecpp

    ilovecpp Guest

    Hi.

    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)
    {
    Hardware_Init();

    while(1)
    {
    Uart_Put_Char('A');
    __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 ?

    thx.
     
    ilovecpp, Jul 20, 2005
    #1
    1. Advertisements

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

    Meindert
     
    Meindert Sprang, Jul 20, 2005
    #2
    1. Advertisements

  3. ilovecpp

    ilovecpp Guest

    Thank you Meindert Sprang.

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

    void main(void)
    {
    Hardware_Init();

    while(1)
    {
    Uart_Put_Char('A');
    __asm volatile ("sleep");
    Uart_Put_Char('B');
    }
    }

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

    I think something wrong.
    Do you know why ?
     
    ilovecpp, Jul 20, 2005
    #3
  4. 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.

    Meindert
     
    Meindert Sprang, Jul 20, 2005
    #4
  5. ilovecpp

    Ken Scharf Guest

    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!)
     
    Ken Scharf, Oct 15, 2005
    #5
  6. ilovecpp

    David Howard Guest

    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
     
    David Howard, Oct 15, 2005
    #6
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.