Dec-12th-2008

Using the USART of AVR Microcontrollers.


Welcome to the third part of my RS232 serial communication tutorial. Till now we saw the basics of RS232 communication and made our level converter. Now its time to understand the USART of AVR microcontroller and write the code to initialize the USART and use it to send and receive data.

Like many microcontrollers AVR also has a dedicated hardware for serial communication this part is called the USART - Universal Synchronous Asynchronous Receiver Transmitter. This special hardware make your life as programmer easier. You just have to supply the data you need to transmit and it will do the rest. As you saw serial communication occurs at standard speeds of 9600,19200 bps etc and this speeds are slow compared to the AVR CPUs speed. The advantage of hardware USART is that you just need to write the data to one of the registers of USART and your done, you are free to do other things while USART is transmitting the byte.

Also the USART automatically senses the start of transmission of RX line and then inputs the whole byte and when it has the byte it informs you(CPU) to read that data from one of its registers.

The USART of AVR is very versatile and can be setup for various different mode as required by your application. In this tutorial I will show you how to configure the USART in a most common configuration and simply send and receive data. Later on I will give you my library of USART that can further ease you work. It will be little complicated (but more useful) as it will have a FIFO buffer and will use interrupt to buffer incoming data so that you are free to anything in your main() code and read the data only when you need. All data is stored into a nice FIFO(first in first out queue) in the RAM by the ISR.

USART of AVR Microcontrollers.

The USART of the AVR is connected to the CPU by the following six registers.

  • UDR - USART Data Register : Actually this is not one but two register but when you read it you will get the data stored in receive buffer and when you write data to it goes into the transmitters buffer. This important to remember it.
  • UCSRA - USART Control and status Register A : As the name suggests it is used to configure the USART and it also stores some status about the USART. There are two more of this kind the UCSRB and UCSRC.
  • UBRRH and UBRRH : This is the USART Baud rate register, it is 16BIT wide so UBRRH is the High Byte and UBRRL is Low byte. But as we are using C language it is directly available as UBRR and compiler manages the 16BIT access.

So the connection of AVR and its internal USART can be visualized as follows.

AVR USART Registers

Fig- AVR USART registers.

Registers Explained

In order to write programs that uses the USART you need to understand what each register's importance. The scheme behind using the AVR USART is same as with any other internal peripheral (say ADC). So if you are new to this topic please see this tutorial, it shows you the basic idea of using peripherals.

I am not going to repeat what is already there in the datasheets, I will just tell about what is required for a quick startup. The datasheets of AVR provides you with all the details of every bit of every register so please refer to it for detailed info. Note bit names with RED background are of our interest here.

UDR: Explained above.

UCSRA: USART Control and Status Register A

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

Bit No
7
6
5
4
3
2
1
0
Name
RXC
TXC
UDRE
FE
DOR
PE
U2X
MPCM
Initial Val
0
0
1
0
0
0
0
0

RXC this bit is set when the USART has completed receiving a byte from the host (may be your PC) and the program should read it from UDR

TXC This bit is set (1) when the USART has completed transmitting a byte to the host and your program can write new data to USART via UDR

 

UCSRB: USART Control and Status Register B

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

Bit No
7
6
5
4
3
2
1
0
Name
RXCIE
TXCIE
UDRIE
RXEN
TXEN
UCSZ2
RXB8
TXB8
Initial Val
0
0
0
0
0
0
0
0

RXCIE: Receive Complete Interrupt Enable - When this bit is written one the the associated interrupt is enabled.

TXCIE: Transmit Complete Interrupt Enable - When this bit is written one the the associated interrupt is enabled.

RXEN: Receiver Enable - When you write this bit to 1 the USART receiver is enabled. The normal port functionality of RX pin will be overridden. So you see that the associated I/O pin now switch to its secondary function,i.e. RX for USART.

TXEN: Transmitter Enable - As the name says!

UCSZ2: USART Character Size - Discussed later.

For our first example we won't be using interrupts so we set UCSRB as follows

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

 

UCSRC: USART Control And Status Register C

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

Bit No
7
6
5
4
3
2
1
0
Name
URSEL
UMSEL
UPM1
UPM0
USBS
UCSZ1
UCSZ0
UCPOL
Initial Val
0
0
0
0
0
0
0
0

IMPORTANT : The UCSRC and the UBRRH (discussed below) register shares same address so to determine which register user want to write is decided with the 7th(last) bit of data if its 1 then the data is written to UCSRC else it goes to UBRRH. This seventh bit is called the

URSEL: USART register select.

UMSEL: USART Mode Select - This bit selects between asynchronous and synchronous mode. As asynchronous mode is more popular with USART we will be using that.

UMSEL
Mode
0
Asynchronous
1
Synchronous

USBS: USART Stop Bit Select - This bit selects the number of stop bits in the data transfer.

USBS
Stop Bit(s)
0
1 BIT
1
2 BIT

UCSZ: USART Character size - These three bits (one in the UCSRB) selects the number of bits of data that is transmited in each frame. Normally the unit of data in MCU is 8BIT (C type "char") and this is most widely used so we will go for this. Otherwise you can select 5,6,7,8 or 9 bit frames!

UCSZ2
UCSZ1
UCSZ0
Character Size
0
0
0
5Bit
0
0
1
6Bit
0
1
0
7Bit
0
1
1
8Bit
1
0
0
Reserved
1
0
1
Reserved
1
1
0
Reserved
1
1
1
9Bit

So we set UCSRC as follows

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

UBRR: USART Baud Rate Register:

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

This is the USART Baud rate register, it is 16BIT wide so UBRRH is the High Byte and UBRRL is Low byte. But as we are using C language it is directly available as UBRR and compiler manages the 16BIT access. This register is used by the USART to generate the data transmission at specified speed (say 9600Bps). To know about baud rate see the previous tutorial. UBRR value is calculated according to following formula.

Where fosc is your CPU frequency say 16MHz

Baud Rate is the required communication speed say 19200 bps (see previous tutorial for more info).

Example:

For above configuration our UBRR value comes to be 51.083 so we have to set

UBRR=51;

in our initialization section. Note UBRR can hold only integer value. So it is better to use the baud rates that give UBRR value that are purely integer or very close to it. So if your UBRR value comes to be 7.68 and you decided to use UBRR=8 then it has high error percentage, and communication is unreliable!

Initialization of USART

Before using the USART it must be initialized properly according to need. Having the knowledge of RS232 communication and Internal USART of AVR you can do that easily. We will create a function that will initialize the USART for us.


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

void USARTInit(uint16_t ubrr_value)
{

   //Set Baud rate
   UBRR= ubrr_value;

   /*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);


}

Now we have a function that initializes the USART with a given UBRR value.

That's it for now friends. In next tutorial we will learn how to send and receive data over RS232 channel. Don't forget to post your opinion or doubts or any suggestion I would be very happy to see them. So don't wait post a comment now !


40 Responses to “Using the USART of AVR Microcontrollers.”

  1. 1
    PurpleJesus Says:

    Finally, I’m starting to ‘get it’

  2. 2
    AM Says:

    next will be I2C?? This will be greate…

  3. 3
    Avinash Says:

    Hi AM,

    Ya I will surly come up with a I2C tutorials but before that I will complete USART tutorial by providing fuctions for reading and writing data.Then I will present my library for USART which is slightly complex (internally) but is more relibale and usefull. After that i will go for I2C

  4. 4
    shiv sambhu Says:

    its very very interesting…

  5. 5
    Using the USART of AVR Microcontrollers : Reading and Writing Data | eXtreme Electronics Says:

    [...] 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 go see how we can [...]

  6. 6
    Surya Rajendran Says:

    hi
    I had been doing a project on polygraph with the help of program given by cornell university.but i dont knw which compiler they have used. v tried 2 use code vision but when v r xecuting prgm in proteus professional even if MATLAB is sending charector ’s’,its not working.i would like 2 know which compiler they would have used.The prog is given below

    CODE REMOVED TO SHORTEN THE COMMENT.

  7. 7
    Enrique Says:

    Dear friend, so nice tutorial!!!
    regards:

    Enrique.

  8. 8
    newman Says:

    Hi, I have ATmega8 and standart system clock is 1MHz. What I must change in code? and what baud rate need i set? from datasheet: Fosc=1MHz, Baud rate= 9600, UBRR= 6. Its correct? pls help.

  9. 9
    Avinash Says:

    Formula for calculation of UBRR is clearly given and explained above.
    Also not EVERY baud rate possible. So Baud rate of 9600 on 1MHz CPU gives UBRR=5.51 and since we can use only integer for UBRR, using 6 as UBRR has huge error.

    So go for other baud rates.

    I recommend you to go with BAUD = 19200 which gives UBRR=2.25=2

  10. 10
    newman Says:

    OK and when I use external crystal? 7,3728 MHz UBRR=47 no errors, but i dont know what i must change in code and in avr studio??

  11. 11
    cablet Says:

    Thanks for the handy info. It really helped clear some things up about programming for RS-232.

  12. 12
    Avinash Says:

    Hello Newman,

    The two baud rate you calculated are correct. As you can see the above function we created takes UBRR value as argument, so simply pass the calculated values. Thats it !

    Are you comfortable with c programming ? I mean do u understand what I said above.

    See next tutorial’s code.
    http://extremeelectronics.co.in/avr-tutorials/using-the-usart-of-avr-microcontrollers-reading-and-writing-data/

    In the end I have given a complete demo program

    Have a look at the main() function where we init USART by calling

    USARTInit(51) //UBRR=51

    Here 51 is UBRR value.

    Simply change only this value to one you calculated and complile.

    If you have any more doubts pls post in the forum (see side bar navigation), I will try by best to explain.

    :) Have a nice day !

  13. 13
    Paul from Edmonton, Canada Says:

    Hi Avinash,

    Your website is a recent discovery for me. I am very impressed with your tutorials. They are very clear and easily understood. Thank you!

    I am working with an ATmega32 processor and I am unsure exactly how the UART, baud rate, internal, and external clocks all work together. Can you advise me on this?

    Some colleagues of mine are struggling with the Input Capture function of the same mcu as above. Do you have any information they can read to make this function clearer?

    Cheers,

    Paul

  14. 14
    Avinash Says:

    Hello Paul,

    Thanks you liked my works.:)

    I can’t get

    “I am unsure exactly how the UART, baud rate, internal, and external clocks all work together. Can you advise me on this?”

    please tell in some details so that I can help you.

    Have A Nice Day :)

  15. 15
    newman Says:

    Paul when you use a internal rc oscilator 8MHz uart is no so reliable, when is good use external crystal with 7,3728MHz than is all correct. baud rate is speed sending data, i use 9600 baud rate…

  16. 16
    Paul from Edmonton, Canada Says:

    Why is the internal RC oscillator not so reliable? For the external crystal what size of capacitors should I be using? I could calculate it but if you guys know already then maybe you could save me some time.

  17. 17
    newman Says:

    2x 22pF, look at datasheet atmega32

  18. 18
    Avinash Says:

    Hello,

    I thank newman for helping Paul.
    :)

    Good work.

    As newman has said use 22pF capacitors.

    For complete circuit see
    http://extremeelectronics.co.in/hardwares/home-made-avr-devboard/

    Internal RC is only for not time critical application. Because the frequency change with temperature. And USART is a time critical application. Crystal Oscillators are used in such application because they are very stable over temperature changes.

  19. 19
    apiz Says:

    rs 232 and USART, are they a same method(protocol)?

    sory if my question to sally..

  20. 20
    Avinash Says:

    Hello Apiz :)

    RS232 is the “PROTOCOL” that means the standard “rule” for communication.

    While USART is Universal Synchronous Asynchronous Receiver Transmmiter

    It is a piece of hardware (commonly inside the MCU) that is used for RS232 Communication.

    So now you know RS232 is a “PROTOCOL” while USART is a HARDWARE.

  21. 21
    Pankaj Says:

    wow. now i understand how it actually works.
    thanks

  22. 22
    Dave from USA Says:

    Hey very cool tutorial…is will this code also work with the UART on an ATMega168 MCU?

  23. 23
    kaustubh Says:

    thank you!it was intresting!

  24. 24
    Avinash Says:

    Hello Dave, :)

    It will work with ATmega168 but you have to replace register names. See datasheet for equivalent name. Like UDR becomes UDR0 and UCSRA becomes UCSR0A.

    Thats all

  25. 25
    AVR ATMEGA8535 : USING USART [SERIAL COMM] « My English Blog Says:

    [...] http://extremeelectronics.co.in/avr-tutorials/using-the-usart-of-avr-microcontrollers/ [...]

  26. 26
    Siddharth Dev Says:

    Hello Avinash!

    Great tutorial series. Its a noble work to share knowledge.

    I really enjoy the simplicity of your tutorials.

    Keep Going!!

  27. 27
    Jun Says:

    Best tutorials found online for newbies

    thank you so much
    now I dont have to guess the meaning of the code anymore :)

    great job!

    thanks again

  28. 28
    Lihil Says:

    Hey Avinash,

    Just have a question in regard to the RS232 protocol. Can it be used to transfer entire blocks of data into the Atmega chips memory?

    for example, if we want to store the data line “12345″ in a special matrix in the memory, how should we go about it?

    Thanks

  29. 29
    From extremeelectronics: AVR USART Tutorial | Solder In The Veins Says:

    [...] grips with the black art of AVR USART comms. The guys at extremeelectonics have published  a very comprehensive tutorial on the various registers related to the AVR USART peripherial, how to set them, [...]

  30. 30
    mitul tailor Says:

    for communication with microcontroller through hyper terminal, do v need to give any self & remote remote address

  31. 31
    mitul tailor Says:

    mitul tailor Says:

    for communication with microcontroller through hyper terminal, do v need to give any self & remote remote address in the above given program

  32. 32
    xTech Says:

    i dont know who are u Mr. Avinash,bt tell u have been amazing…so lucid explanation…just unbeleivable…I shal be gladly waitin to receive ur mail if u can kindly let me know about urself…

  33. 33
    Santosh Sahu Says:

    Hello abhinash,i want to communicate 2 ATMEGA16 through RF.if i connect 433mhz reciever and transmitter in RXD and TXD respectively in each ATMEGA16.Then if i’ll transmitt data frm one microcontroller then then,My question is -data will be receive by another ATMEGA16 or the same ATMEGA16?because both ATMEGA16 has 433mhz receiver..plz help me.

  34. 34
    Ganesh Says:

    Hello Avinash!

    These are Great and easily understood tutorial.Thank you very very much!!!!
    In future tutorial can you Plese add some webcam or similer Cam interface to AVR family,I am waiting eagerly,Thanks again

  35. 35
    raj Says:

    Hello Avinash

    Thanks a lot for your excellent articles. This is best place to start with for any AVR or infact any microcontroller beginner.

    The way you explain the concepts is uncanny.

  36. 36
    Vishal G. Mesharm Says:

    Dear Sir
    I am vishal working on a project in which i have interface RF Module with ATMEGA 32L AVR Microcontroller for wireless communication.
    I have already established the communication through wire using USART and adler32 protocol, But when i had connected rf module to the MC, I cannot communicate.
    I had connected rf TX module to the TX PIN of AVR, and RF RX module to the RX pin of MC, Also i had made a common ground with powersupply, Still i cannot transmit the desired signal.
    Should i connect some IC in between, or is there is another problem
    Waiting for the solution
    Regards
    vishal
    (vishalmeshram2007@rediffmailcom)

  37. 37
    hinduja Says:

    sir amazing tutorials i read from a lot of sites but nothing as clear as dis one……
    sir my objective is to create a usart communication between two microcontroller.shld the information transmitted be first converted to binary form before transmitting through tx line or is the conversion internal. similarly if i want to see the data received should i convert the received data from binary to normal form

  38. 38
    Ramesh Says:

    hello avinash
    nice job avinash, this is the best avr beginers forum i found on internet.
    i have a problem with with an usart implementation.
    i tried implementing an usart code using internal RC oscillator at 4MHz using code vision.The hyperterminal displayed junk values(like “..[ “) instead of the chars “1? “2? or “3?,irrespective the value in UDR.
    i even implemented the code given above, but the heyperterminal wasn’t accepting any input or displaying any output.
    what could be the fault in this case?
    is there a way i can rectify it?
    there is also external crystal ocsilator on board but how to use it? as i am using codevision compiler it asks me oscilator frequncy
    thanks

  39. 39
    RF Communication Between Microcontrollers – Part III | eXtreme Electronics Says:

    [...] Using the USART of AVR Microcontrollers. [...]

  40. 40
    rf remote controls Says:

    Thanks for the information! I personally really like your article. This is a great website. I will make sure that I stop back again!.

Leave a Reply

Comments

    • Del Chann: Hello is it possible to use this board to interface with a smoke sensor, motion sensor,...
    • Elijah Nicolia: May I consider part regarding your main guide to my personal site
    • Tifany Wiebusch: I go along with you actually, I believe! Might this become doable for you to have...
    • Sinopteek: When i try to run this software under OpenSuSe 11.2 (x64), i’ll have next error:...
    • kapil: @Dhananjay I used that its working and it can programme 3 to 4 times after that there is a...
    • Dhananjay: Sir, At present I am using progisp to flash AT89SXX with usbasp(with modified firmware)....
    • Shashi Jain: plz dont fight wid each other…k i accept my fault… neway m not a rich person...

Video