[Top][All Lists]
[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
smime.p7s
Description: S/MIME cryptographic signature
- [avr-chat] HELP! mega128 USART receive restarts execution,
Rick Mann <=