[Top][All Lists]

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

Re: [avr-gcc-list] uart oddity

From: Bruce D. Lightner
Subject: Re: [avr-gcc-list] uart oddity
Date: Fri, 09 Nov 2001 10:20:10 -0800


I can probably guess what's going on, although I'm more of an expert on the

> I have been experimenting with the uart sample code posted here on this
> list (thanks, by the way!) on my mega163, and discovered some "funny"
> behaviour.
> If RXEN and RXCIE are set, and a byte is received, and I either do not
> have a SIG_UART_RECV handler, or if I do have one and it doesn't read
> UDR, then all uart activity hangs. The cpu runs, my blinkenlights keep
> blinken, but no bytes get transmitted, and my SIG_UART_RECV routine does
> not get called ever again no matter how many more characters are received.
> To fix the problem, I have to insert an inb(UDR) into the SIG_UART_RECV
> routine. Of course, I could also turn off RXEN and RXCIE too.
> Now this is simple to fix and will cause no problems in my "real"
> application. But it seems strange to me and was not expected. I have
> read the UART section of the databook several times now, and saw no hint
> of this. I also didn't see anything about it in the avrlibc docs. Maybe
> this is obvious and of course I should expect this behaviour. Or maybe
> I am doing something wrong. in any case I haven't been able to explain
> it and figured it might be worth posting about.
> cheers!
> - -ken

Here's what the datasheet on the AT90S8515 says...

  Bit 7 - RXC: UART Receive Complete

  This bit is set (one) when a received character is transferred from
  the Receiver Shift register to UDR. The bit is set regard-less of any
  detected framing errors. When the RXCIE bit in UCR is set, the UART
  Receive Complete interrupt will be executed when RXC is set(one). RXC is
  cleared by reading UDR. When interrupt-driven data reception is used,
  the UART Receive Complete Interrupt routine must read UDR in order
  to clear RXC, otherwise a new interrupt will occur once the interrupt
  routine terminates.

Note the last sentence...

Assuming that other AVR processors' UARTs behave the same way (a good bet),
I suspect that your processor is in a tight loop servicing the RXC interrupt
precisely because no AVR code is reading the received data from the UART's
UDR register.  If you don't read the UDR, the interrupt will NOT be cleared.

If an interrupt service routine is not provided, you probably get a simple
"return from interrupt" instruction (i.e., "reti") in the default AVR
interrupt vector table...essentially an empty interrupt handler.  If YOU
provide an interrupt handler WITHOUT an "inb(UDR)" statement, then you get
the same behavior.  In both cases, the AVR processor will interrupt
endlessly on receipt of the first character by the UART.  Because you are
guaranteed to execute one AVR instruction AFTER an "reti" instruction, it
looks like the AVR processor is running...and it is...but very slowly!!!  

As for why you can't transmit characters...

If in your case UART transmits are being done with interrupts, both possible
TX interrupt vectors (i.e., TXC and DRE) are of lower priority than the
"RXC" handler, so they will be "held off" by the perpetual "RXC" interrupt. 

Anyway, this is not "strange" behavior...it is probably documented in *your*
Mega163 manual, just like it is in *my* AT90S8515 manual.  (So, I guess the
moral of the story is once again...RTFM! :-)  (Me?  Of course I *always*
RTFM before asking questions! :-)

Best regards,


 Bruce D. Lightner
 La Jolla, California
 Email: address@hidden
 URL: http://www.lightner.net/lightner/bruce/

reply via email to

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