Till now we have seen the basics of RS232 communication, the function of level
converter and the internal USART of AVR micro. After understanding the USART
of AVR we have also written a easy to use function
to initialize the USART. That was the first step to use RS232. Now we will see
how we can actually send/receive data via rs232. As this tutorial is intended
for those who are never used USART we will keep the things simple so as to just
concentrate on the "USART" part. Of course after you are comfortable
with usart you can make it more usable my using interrupt driven mechanism rather
than "polling" the usart.

So lets get started! In this section we will make two functions :-

  • USARTReadChar() : To read the data (char) from the USART buffer.
  • USARTWriteChar(): To write a given data (char) to the USART.

This two functions will demonstrate the use of USART in the most basic and
simplest way. After that you can easily write functions that can write strings
to USART.

Reading From The USART : USARTReadChar() Function.

This function will help you read data from the USART. For example if you use
your PC to send data to your micro the data is automatically received by the
USART of AVR and put in a buffer and bit in a register (UCSRA) is also set to
indicate that data is available in buffer. Its now your duty to read this data
from the register and process it, otherwise if new data comes in the previous
one will be lost. So the funda is that wait until the RXC bit (bit no 7) in
UCSRA is SET and then read the UDR register of the USART.

(See
the full description of USART registers
)


char USARTReadChar()
{
   //Wait untill a data is available

   while(!(UCSRA & (1<<RXC)))
   {
      //Do nothing
   }

   //Now USART has got data from host
   //and is available is buffer

   return UDR;
}

Writing to USART : USARTWriteChar()

This function will help you write a given character data to the USART. Actually
we write to the buffer of USART and the rest is done by USART, that means it
automatically sends the data over RS232 line. One thing we need to keep in mind
is that before writing to USART buffer we must first check that the buffer is
free or not. It its not we simply wait until it is free. If its not free it
means that USART is still busy sending some other data and once it finishes
it will take the new data from buffer and start sending it.

Please not that the data held in the buffer is not the current data which the
USART is busy sending. USART reads data from the buffer to its shift register
which it starts sending and thus the buffer is free for your data. Every time
the USART gets it data from buffer and thus making it empty it notifies this
to the CPU by telling "USART
Data Register
Ran Empty" (UDRE) . It does
so by setting a bit (UDRE bit no 5) in UCSRA register.

So in our function we first wait until this bit is set (by the USART ), once
this is set we are sure that buffer is empty and we can write new data to it.

(See
the full description of USART registers
)


void USARTWriteChar(char data)
{
   //Wait until the transmitter is ready

   while(!(UCSRA & (1<<UDRE)))
   {
      //Do nothing
   }

   //Now write the data to USART buffer

   UDR=data;
}


Note: Actually their are two separate buffers,
one for transmitter and one for receiver. But they share common address. The
trick is that all "writes" goes to the Transmitter’s buffer while
any "read" you performs comes from the receiver’s buffer.

That means if we read UDR we are reading from receivers buffer and when we
are writing to UDR we are writing to transmitters buffer.

UDR=some_data; //Goes to transmitter

some_data=UDR; //Data comes from receiver

(See
the full description of USART registers
)

Sample program to use AVR USART

The following program makes use of the two functions we developed. This program
simply waits for data to become available and then echoes it back via transmitter
but with little modification. For example if you send "A" to it, it
will send you back "[A]" that is input data but surrounded by square
bracket. This program is enough to test the USART yet easy to understand.


/*

A simple program to demonstrate the use of USART of AVR micro

*************************************************************

See: www.eXtremeElectronics.co.in for more info

Author : Avinash Gupta
E-Mail: me@avinashgupta.com
Date : 29 Dec 2008

Hardware:
   ATmega8 @ 16MHz

   Suitable level converter on RX/TX line
   Connected to PC via RS232
   PC Software :  Hyper terminal @ 19200 baud
               No Parity,1 Stop Bit,
               Flow Control = NONE

*/

#include <avr/io.h>
#include <inttypes.h>

//This function is used to initialize the USART
//at a given UBRR value
void USARTInit(uint16_t ubrr_value)
{

   //Set Baud rate

   UBRRL = ubrr_value;
   UBRRH = (ubrr_value>>8);

   /*Set Frame Format


   >> Asynchronous mode
   >> No Parity
   >> 1 StopBit

   >> char size 8

   */

   UCSRC=(1<<URSEL)|(3<<UCSZ0);


   //Enable The receiver and transmitter

   UCSRB=(1<<RXEN)|(1<<TXEN);


}


//This function is used to read the available data
//from USART. This function will wait untill data is
//available.
char USARTReadChar()
{
   //Wait untill a data is available

   while(!(UCSRA & (1<<RXC)))
   {
      //Do nothing
   }

   //Now USART has got data from host
   //and is available is buffer

   return UDR;
}


//This fuction writes the given "data" to
//the USART which then transmit it via TX line
void USARTWriteChar(char data)
{
   //Wait untill the transmitter is ready

   while(!(UCSRA & (1<<UDRE)))
   {
      //Do nothing
   }

   //Now write the data to USART buffer

   UDR=data;
}

void main()
{
   //This DEMO program will demonstrate the use of simple

   //function for using the USART for data communication

   //Varriable Declaration
   char data;

   /*First Initialize the USART with baud rate = 19200bps
   
   for Baud rate = 19200bps

   UBRR value = 51

   */

   USARTInit(51);    //UBRR = 51

   //Loop forever

   while(1)
   {
      //Read data
      data=USARTReadChar();

      /* Now send the same data but but surround it in
      square bracket. For example if user sent 'a' our
      system will echo back '[a]'.

      */

      USARTWriteChar('[');
      USARTWriteChar(data);
      USARTWriteChar(']');

   }
}

Download
Sample Program

Running the USART Demo

You can run the above program in a ATmega8, ATmega16, ATmega32 cpu running
at 16MHz without any modification. If you are using different
clock frequency you have to change the UBRR value that we are passing to USARTInit()
function. See previous
tutorial
for calculating UBRR value. AVR running the USART demo program
can be interface to PC using following three ways.

  • Connect to a Physical COM Port.

    If you are lucky and own a really old PC then you may find a Physical COM
    port on your PC’s back. It is a 9 pin D type male connector. In this case
    you have to make a RS232
    to TTL converter
    and connect the MCU to COM port via it.

  • Connect to a Virtual COM Port.

  • Those who are not so lucky may buy a Virtual
    COM port
    . Again in this case too you need to built a RS232
    to TTL converter
    and connect the MCU to COM port via it.

    USB to Serial Adapter

    Fig. USB to Serial Converter

     

  • Connect Via a Chip CP2102.

    CP2102
    is single chip USB to UART Bridge by SiLabs.
    This chip can be used to connect your embedded applications to USB port
    and enable them to transfer data with PC. It is the easiest path to build
    PC interfaced projects, like a PC controlled robot. We have a very good
    CP2102
    module
    that can be used right out of the box. We have done all PCBs
    and fine SMD soldering for you.

    cp2102 usb to usart converter

    CP2102 Based Module.

     

    6 pin burg wire

    Female sides provide easy connection to headers.

     

    xboard mini v2.0

    xBoard MINI v2.0 with ATmega8 MCU

     

    ATmega8 Connected to CP2102

     

  • Connect via Chip PL2303

    PL2303 is yet another low cost chip for USB to serial (TTL Level) conversion. We also have a complete board for it too !

    pl2303 module

    PL2303 based USB to USART Module

Finding the COM port number of Serial Port

A PC can have several COM ports, each may have some peripheral connected to
it like a Modem. Serial Ports on PC are numbered like COM1, COM2 … COMn etc.
You first need to figure out in which COM port you have connected the AVR. Only
after you have a correct COM port number you can communicate with the AVR using
tools such as Hyperterminal. The steps below shows how to get COM port number
in case of Virtual COM Ports.

Right Click on "My Computer" icon in Windows
Desktop.

my computer icon

My Computer Icon on Windows Desktop

Select "Properties"

right click on my computer

System Context Menu

The System Properties will open up. Go to the "Hardware"
Tab.

System Properties.

In Hardware tab select "Device Manager"
button. It will open up device manager.

Open Device Manager

In Device Manager Find the Node "Ports (COM & LPT)"

Expand the PORT node in Device Manager

Depending on whether you are using a "USB to Serial Converter" or
"CP2102 USB/USART Bridge Module" you have to find the port with following
name.

Note down the COM port number next to the port name. You need to open this
Port in Hyperterminal.

com port number

COM Port Number

 

com port number

COM Port Number

Communication using a Terminal Program on PC.

Since this is the introductory article about serial communication, we won’t
be going in much detail on PC end COM port programming. For this reason we will
be using a ready made software for sending and receiving serial data. I will
be showing how to use two different terminal program to exchange data with embedded
application.

Windows Hyperterminal

This is a default terminal program shipped with Windows OS. You can start it
from

Start Menu->All Programs->Accessories->Communication->Hyperterminal.

Hyperterminal is not available in Windows Vista or Windows 7 so you have to
use other terminal programs like RealTerm.

On startup it will ask for a connection name. Here we will enter AVR

Create New Connection

After that select a COM port you want to use. If you are using USB to serial
adaptor please confirm which COM port number it is using. Other COM ports are
usually connected to some device say an Internal modem etc. While some others
are Bluetooth COM ports. Don’t use them. If you have a physical com port then
most probably it will be COM1. If you select wrong COM port during this step
you won’t be able to communicate with the AVR MCU and won’t get expected results.

hyperterminal setup for pic18f4520

Select COM Port

Now setup the COM port parameters as follows.

  • Bits per second: 19200
  • Data bits: 8
  • Parity: None
  • Stop bits: 1
  • Flow Control: None

com port setup

Setting up the COM port

HyperTerminal is ready for communication now! If everything went right HyperTerminal
and AVR will talk happily and AVR will send the following message as we have
programmed it.

avr atmega8 hyperterminal

Screenshot of Hyperterminal Showing the message received from AVR

If the screen shows similar message then you have successfully created a link
between PC and your AVR micro. It shows that PC can read the data sent by AVR.
To test if the AVR can also read Hyperterminal, press some keys on PC keyboard.
Hyperterminal will send them over COM port to the AVR mcu where AVR will process
the data. In the simple test program this processing includes returning the
same data but enclosed inside [ and ], so if you press ‘k
then AVR will return [k]. If you are able to see this on PC
screen then you are sure that AVR is receiving the data correctly.

That’s it! It fully tests the Serial Communication Routine and your hardware
setup.

Setting Up Realterm and using it to communicate with AVR

If you are running Windows Vista or Windows 7 then the Hyperterminal Program
may not be available. So in place of it you can use Realterm.
It can be downloaded from here.

Start Realterm from its Desktop Icon. You will get a screen similar to this.
Increase the Value of Row to 40 to see whole message.

avr atmega8 realterm

Screenshot of Realterm Showing the message received from AVR

Setup Realterm as follows. Go to the Port Tab and set it as
follows.

  • Baud: 19200
  • Port: Port where you have connected the AVR
  • Data bits: 8
  • Parity: None
  • Stop bits: 1
  • Hardware Flow Control: None

 

avr atmega8 realterm

Screenshot of Realterm Setup

After setting up Realterm connect the AVR board with COM port and switch it
on. Rest process is same as given above for Hyperterminal.

See Also