Cornell University
Electrical Engineering 476
RS232 serial communications
with AVR microcontrollers
Introduction
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 setUSCRB = 0b10011000; //hex 0x98
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:
getchar().
You can do this by polling the UART status register every few mSec. An example
of this scheme is shown in an example on the Program Organization page.getchar()
is only
called when the receive-done flag is set by hardware. The receive interrupt
routine will also be responsible for collecting the inputted characters into
a string until detecting a enter
keystroke, then null-terminating
the string and setting a flag showing that the string is complete. Also write
a transmit interrupt which sends one character, then enters the ISR when the
transmit-buffer-empty flag is set. An example shows
one way to implement this. Note that you must turn on the printf
feature to print longs
in the project...configure
dialog. Serial communication in ASM
There are at least two ways of handling serial i/o in assembly language:
Copyright Cornell University Jan 2004