avr-chat
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-chat] HELP! mega128 USART receive restarts execution


From: Rick Mann
Subject: [avr-chat] HELP! mega128 USART receive restarts execution
Date: Sun, 12 Feb 2006 00:20:33 -0800

I have a very simple program, which was working great on an ATmega32. But I've ported it to an ATmega128, and I'm having lots of trouble. Aside from the changes required to get the single UART on the '32 working on UART 0 on the '128, I also stripped it down a bit to try to figure out what's going wrong.

My code does this. It sets up the UART to interrupt when a byte comes in. The main code just twiddles some LEDs. The interrupt handler is here:

ISR(SIG_UART0_RECV)
{
        unsigned char c1;
        c1 = UDR0;
        
#if 0
        usart_putc(c1);
        
        unsigned char c = c1 - '0';
        
        if (c == 1)
        {
                PORTC = _BV(kPinBlueLED);
        }
        else if (c == 2)
        {
                PORTC = _BV(kPinRedLED);
        }
        else if (c == 3)
        {
                PORTC = _BV(kPinGreenLED);
        }
#endif
}

In my hardware, RTS is connected to CTS.

Note that I've commented out most of it. When uncommented, the code sends the received byte back out, then sets one of the three LEDs on, depending on what value was received (the main loop eventually changes that, but that's okay). On the '32, this worked just fine. In particular, each character that was sent back to my terminal program would show up and cause the cursor to shift one to the right.

One the '128, if the character is sent back, it stays in the same position (the cursor doesn't advance). Worse, every time a character is received, the RX ISR gets called (I've verified this in gdb and I can see the byte echoed), then appears to return, and then execution continues from the start of main, rather than wherever execution left off.


Here's main:

int
main()
{
        //      Set LED output pins…
        
        DDRC = _BV(kPinGreenLED) | _BV(kPinBlueLED) | _BV(kPinRedLED);
        PORTC = 0;
        
#if 1
        init(); // init USART
        sei();  // enable interrupts
        
        // send initial character
        //usart_putc('C');
        //usart_putc(0x0D);
        
        while(!(UCSR0A & (1 << UDRE0)));
        UDR0 = 0x43; // "C"
        while(!(UCSR0A & (1 << UDRE0)));
        UDR0 = 0x0d;
#endif
        
        //      Show initialization complete…
        
        unsigned long d;
        const unsigned long kD = 3000000;
        
        while (1)
        {
                PORTC = _BV(kPinRedLED);
                d = kD; while (d--);
                PORTC = _BV(kPinBlueLED);
                d = kD; while (d--);
                PORTC = _BV(kPinGreenLED);
                d = kD; while (d--);
                PORTC = _BV(kPinBlueLED);
                d = kD; while (d--);
        }
        return 0;
}


Here's init() (sorry about the formatting):

void
init()
{
        // set baud rate
        UBRR0H = (uint8_t) (UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) >> 8);
        UBRR0L = (uint8_t) UART_BAUD_CALC(UART_BAUD_RATE,F_OSC);

        // Enable receiver and transmitter; enable RX interrupt
// RX int enable TX int disable dtareg intdis RX enable TX enable 8-bit chars
        //                              1                               0       
                        0                               1                       
        1                               0
        
        UCSR0B =        _BV(RXCIE0)
                |       !_BV(TXCIE0)
                |       !_BV(UDRIE0)
                |       _BV(RXEN0)
                |       _BV(TXEN0)
                |       !_BV(UCSZ02);

// asynchronous --- no parity --- 1 stop bit --- 8-bit chars --- unused, write 0
        //                              0                               0       
                        0                               0                       
        1                               1                               1
        
        UCSR0C =        !_BV(UMSEL0)
                |       !_BV(UPM01)
                |       !_BV(UPM00)
                |       !_BV(USBS0)
                |       _BV(UCSZ01)
                |       _BV(UCSZ00)
                |       _BV(UCPOL0);
}

I'm at my wits' end here. I don't know how to use gdb well enough to figure out why main starts from the top each time the RX handler returns from interrupt. Any suggestions would be most appreciated. Thanks!


--
Rick




Attachment: smime.p7s
Description: S/MIME cryptographic signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]