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
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ AVR-chat mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/avr-chat
