Sunday, October 20, 2013

USART with ATmega32

Introduction

The Universal Synchronous and Asynchronous serial Receiver and Transmitter (USART) is a highly flexible serial communication device. It is the easiest way to communicate with a computer. Many softwares such as MATLAB, Scilab, Mathmatica, etc., provide libraries that support serial communication. Real time data logging can be easily done due to its speed and flexibility in features. The USART uses two lines Tx and Rx, the data is transmitted through the Tx line and received through the Rx line. Let's see how to make ATmega32 communicate with a laptop.

Setting up the Hardware

Hardware needed :
  1. CP2102 module or FT232BM module or any of such kind.
  2. Atmega32 with its basic circuitry.
From the ATmega32's data sheet we can see that
  1. PD0 -> RXD
  2. PD1 -> TXD
Connect the data lines of the CP2102 module and ATmega32, then insert the CP2012 module in the USB port of your laptop or PC.

Deciding your System clock


As you can see in the following picture that at some Baud Rate the error percentage is quite high. So if your application needs high accuracy, baud rate should also be taken into account. In the following post the ATmeag32 has a baud rate of 9600 bps and the CPU is clocked at 8 MHz.

Initializing the USART


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
void USART_Init( unsigned int baud )
{
    /* Set baud rate */
    UBRRH = (unsigned char)(baud>>8);
    UBRRL = (unsigned char)baud;
    /* Enable transmitter and receiver */
    UCSRB = (1<<TXEN)|(1<<RXEN);
    /* Set frame format: 8data, 2stop bit */
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

  1. First of all you need to enable the USART transmission and reception line using the UCSRB register or the they will function as normal i/o mode.
  2. Next the format in which the we want to send the data like data bits, stop bits, parity, etc., in the UCSRC register.
  3. Finally, setting the baud rate using the UBBR register. The UBRR value for a certain baud rate for a certain system clock can be found out in the table shown above or by using the following formula.

Sending and Receiving data

Now as our ATmega is initialized to use USART, all we need to do now is send or receive the data we need. The can be done using the USART I/O Data Register.
1
2
3
4
5
6
7
8
void USART_Transmit_char(char txdata )
{
    /* Wait for empty transmit buffer */
    while ( !( UCSRA & (1<<UDRE)) )
    ;
    /* Put data into buffer, sends the data */
    UDR = txdata;
}
The above code can be used to send a character over USART. The explanation of the code can be clearly seen in the comments. In the above code you wait for the transmitter buffer and load the data into the UDR register. Similarly the in the following code you wait for the receiver buffer to get the data and read it from the UDR register.
1
2
3
4
5
6
7
8
unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}
  He is some basic code that returns any data that we send to ATmega32:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <avr/io.h>

void USART_Init( unsigned int baud )
{
    /* Set baud rate */
    UBRRH = (unsigned char)(baud>>8);
    UBRRL = (unsigned char)baud;
    /* Enable transmitter and receiver */
    UCSRB = (1<<TXEN)|(1<<RXEN);
    /* Set frame format: 8data, 2stop bit */
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

void USART_Transmit_char(char txdata )
{
    /* Wait for empty transmit buffer */
    while ( !( UCSRA & (1<<UDRE)) )
    ;
    /* Put data into buffer, sends the data */
    UDR = txdata;
}

unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}

int main(void)
{
    char data;
    USART_Init(51);
    USART_Transmit_char('H');
    USART_Transmit_char('i');
    while(1)
    {
        data=USART_Receive();
        USART_Transmit_char(data);
    }
}

 The output can be seen in the following picture:


No comments :

Post a Comment