Cornell University
Electrical Engineering 476
RS232 serial communications
with AVR microcontrollers


Most of the AVR mcus have a hardware UART. You can use the UART in CodevisionC with the usual stdio library functions, plus a few designed for this small mcu. You should note that all of the CodevisionC stdio functions are blocking. This means that any cooperative multitasking scheme you use will halt if you use stdio functions. A couple of approachs to solving this problem will be outlined below.

Near the bottom of the page there is code for using the UART in assembler.

If you use the UART to talk to a PC, the UART should be connected to a COM port of the PC. You should use a simple terminal program, such as Hyperterminal, on the PC. The terminal program should be set to 9600 baud, no parity, one stop bit, and no flow control. The connection to the PC for the AVR development board assumes a RS232 cable with straight-through connection. The STK500 board requires a jumper from port pins D0 and D1 to the RS232-spare header.

Using C stdio library

In C, you need to specifically enable the UCR (UCSRB on Mega163 and Mega32) to transmit and receive, and define the baud rate in UBRR (UBRRL on Mega32). These two lines must preceed any of the higher-level serial i/o commands. Setting the UCR (UCSRB) to 0x18 enables serial transmit and receive. Setting the UBRR to 51 implies 9600 baud with an 8 MHz crystal. See the MCU data sheet for other baud rates.

//For 8515:
UCR = 0x10 + 0x08 ; //turn on serial transmit/receive
UBRR = 51 ; //using a 8 MHz crystal
//For Mega163:
UCSRB = 0x10 + 0x08 ;
UBRR = 51 ; //using a 8 MHz crystal
//For Mega32:
UCSRB = 0b00011000 ; //hex 0x18
UBRRL = 103 ; //using a 16 MHz crystal (9600 baud)
In addition if you want to enable the receive-complete interrupt you must instead set
USCRB = 0b10011000; //hex 0x98
Bit 7 enables the interrupt, bit 4 enables the receiver, and bit 3 the transmitter.

Printf and scanf are supplied. Floating point conversion support costs you a lot of code space if you use it. There are also put-string and get-string commands (puts, gets), as well as putsf, which means put-string-from-flash-memory. The lower-level commands putchar and getchar are also available. Since there are 32 kbytes of flash memory and only 2 kbytes of RAM, you should always store constant strings in flash. In the following example, the fragment of code prompts the user with a string from flash memory, then waits for an 's' from the serial port. All quoted literal strings used as parameters are automatically stored in flash.

putsf("Press s to stop\r"); 
sflag = 0;
while(sflag!='s') sflag = getchar() ;

The input function, scanf, does not echo characters back to hyperterm. You can do this, and have a backspace function, by using something similar to this code.

Avoiding Blocking Input in C

Usually you can tolerate a blocking stdio function when it is used for output (e.g. printf) because you can estimate the length of time the transmission will take and because embedded applications tend to sent short strings. However, if you are waiting for input from a user, an input function (e.g. scanf) could wait for a very long time. This will cause a cooperative multitasking program organization to fail. You can work around this problem in two fundamentally different ways:

Serial communication in ASM

There are at least two ways of handling serial i/o in assembly language:

Copyright Cornell University Jan 2004