Vous êtes sur la page 1sur 3

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 set
USCRB = 0b10011000; //hex 0x98

Bit 7 enables the interrupt, bit 4 enables the receiver, and bit 3 the transmitter.
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
Printf

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:

Be sure that there is actually a character to be read before calling 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.
Write a receive interrupt routine so that 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:

Polled transmit and receive functions. This scheme blocks the cpu while
executing, but is often easier to setup. A demo program shows fairly high-level
string send and receive functions. Another demo program shows one way of
parsing numbers from from an input string.
Interrupt driven transmit and receive functions. This scheme allows the fast cpu to
perfrom other functions while waiting for the slow serial interface. A demo
program shows basic UART transmit and receive interrupt routines for the
AT90S8515 mcu. Note that the 'transmit buffer empty" interrupt is set when the
mcu is reset. This means that you must initialize the message pointer before you
enable interrupts, or you will get garbage sent to the terminal at each reset.

Link: http://instruct1.cit.cornell.edu/courses/ee476/Serialcom/