2313 UART full speed problems

Go To Last Post
4 posts / 0 new
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Has anyone noticed unusual behavior of the UART in the AVR 2313?
I am getting garbage characters when receiving data at full speed, but not when sending individual characters as keystrokes. The only way I can receive multiple chars correctly is to put a 25millisecond pause between them.
I have a buffer in the SRAM where characters are placed by the RXCIE (UART receive interrupt) when they arrive.
Using an ICE200, I can see the bytes in the SRAM. When I send a series of bytes (say, "012345") as a file only the first character appears correctly in the SRAM buffer unless there is a 25 millisecond delay between chars. When I type these numbers using a terminal program, they appear fine in the buffer which means that the baud rate, parity, bit count, ect are all OK.
The Framing Error and Overrun error bits are not set after the normal speed transfer, only the data is incorrect.
Connecting two PCs together using a crossover cable between their RS232 ports shows no problems with the host terminal program (RealTerm 1.99.27).
Might anyone have any suggestions or similar unusal experience with the AVR 2313 UART?

This is the code for the ReceiveIRQ that gives errors after the first byte has been received:
The bytes from the UART are going into the correct buffer locations, but the data is incorrect.
Could it be that the AVR requires a slight delay after receiving each character before it can start receiving another one?

; RXcomplete - Interrupt routine executed when finished receiving a new byte from RS232. The main
; program maintains the Output pointer of the queue. When the in and out ptrs don't match,
; the main program transmits the char referred to by the out ptr at a different baud rate.
; This program is an RS232 (38.4K baud - PC) to MIDI (31.25K baud - music synthesizer) convertor.
; Or, it would be if I could read bytes from the PC into the AVR2313 correctly.
; UART setup code in main reset initialization section
; ldi temp,UB38_36864 ; setup baud rate for 38.4K with 3.6864MHz crystal (value 0x05)
; out UBRR,temp
; sbr temp,(1<<RXEN) | (1<<TXEN) | (1<<RXCIE) ; UART receive and transmit enabled, Rx Complete IRQ
; out UCR,temp ; setup UART control register
; clr InputPtr
; clr OutputPtr

RXcomplete: ; UART FIFO queue - Received char baudrate is faster than transmit baudrate, so must queue new arrivals.
push irqtemp ; scratch upper register only used in IRQ routines
in irqtemp,SREG ; preserve system register status because Z flag is used in this routine
push irqtemp ; reg saved because this routine may happen when in another IRQ that is also using irqtemp
in irqtemp,UDR ; get the newly arrived byte
clr YH ; find the current position of the SRAM input buffer for storing character
ldi YL,BUFFER_START ; 0x60 start of SRAM
add YL,InputPtr ; initialized to 00 by the reset code at the very beginning
st Y,irqtemp
inc InputPtr
mov irqtemp,InputPtr ; Input buffer pointer is a lower register. Must copy to upper reg for CPI
cpi irqtemp,BUFFER_SIZE ; Buffer size is 0x70 to leave room for the stack (which doesn't go below 0xD8)
breq RX0
RXout: pop irqtemp ; restore system register flags before leaving
out SREG,irqtemp ; can't pop directly to SREG
pop irqtemp
RX0: clr InputPtr ; reset buffer pointer to beginning of SRAM when BUFFER_SIZE is reached
rjmp RXout ; use only one reti exit point for an IRQ routine

Thank you,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Quick question - from the code comments it sounds like you are doing other stuff (namely sending out the data you recieve at a different baud-rate). Does that use interrupts that could mess up your code (sonuds like the answer may be yes).

You don't disable interrputs in that code as far as I can see, so your may be getting another interrupt that pauses your routine long enough for the data to be over-written. Try disabling interrupts (cli instruction).


  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You're using Y (and inputPtr, but I suppose that could be dedicated(?))
but you don't save/restore it in the ISR. If the Tx side (spin loop? I
don't see UDRIE) is using Y there's a high probability that it would get
corrupted by the RXC interrupt.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also, I notice that you're using SBR to put the control bits into UCR
(nee temp). If temp already has 0x05 in it, it looks as though you're
setting CHR9, requesting 9-bit characters. It wouldn't surprize me if
this resulted in some muddle with the stop bit, leading to an out-of-
sync on the second and subsequent characters.

Suggestion would be to use "ldi temp,(1<<RXEN)|...". Or did you mean
to "in temp, UCR" before the SBR?