Tuesday, September 29, 2020

ATMega32 AVR Universal Asynchronous Receiver Transmitter (UART)

Overview of AVR ATMega32 USART/UART

The Universal Synchronous/Asynchronous serial Receiver/Transmitter (USART) is a serial communication interface that communicates in either synchronous or asynchronous mode.  The Universal Asynchronous Receiver Transmitter (UART) is serial communication interface that work only in asynchronous mode. In the AVR ATMega32, this communication module is called USART, and it's fully compatible with the UART.

Here are some basic features of the module I got from the device datasheet:

  • Full duplex operation
  • Asynchronous/Synchronous operation
  • Master/Slave mode
  • Precise clock generator
  • Selectable data bits from 5 9, up to two stop bits
  • Normal or double speed
The figure below is a detailed block diagram of the USART.

ATMega32 AVR Universal Asynchronous Receiver Transmitter (UART)
The block diagram of the USART from the device vendor specification

Clock generation for the USART Baud rate

The MCU clock frequency Fosc creates the timing for the USART baud rate. The USART Baud Rate Register (UBRR) that make up to two 8-bit register creates the baud rate for this communication. It's a count down timer.

Clock generator block diagram from the device's datasheet

The Baud rate (in bits per second, bps) is BAUD in short. There are three modes of the USART operation. To find the BAUD we have the equations list below.

Relation between the BAUD and the UBRR register

The UBRR (contains the UBRRH and the UBRRL) is a 12-bit register (0 to 4095). 

The transfer rate could be twice in speed by using the double speed mode. This reduce the baud rate divisor from 16 to 8.

Frame Formats

In the serial communication one frame of data defines a character the make up of several data bits. A frame may contains of,
  • 1 start bit
  • 5, 6, 7, 8, or 9 data bits
  • no, even or odd parity bit
  • one or two stop bits
A data frame initiates by a start bit follows by many remanding bits as shown below. An idle mode keep the data line high until it's pulled low to start the data transmission.

The data frame formats of the USART

For instant the programmer select a BAUD of 9600, an 8-bit data mode, no parity bit and 1 stop bit.  

USART Registers Configurations and Operations

To initial the USART with a desired requirements we must take some register configurations in the,
  • UCSRA - USART Control and Status Register A
  • UCSRA - USART Control and Status Register B
  • UCSRC - USART Control and Status Register C
  • UBRRL and UBRRH - USART Baud Rate Registers (UBRR)
Another one's is the USART I/O data register (UDR). It's an 8-bit shift register that shift data in and out for the data transmission/reception. It cooperates with other two FIFO registers that I don't list the full details here.

USART Control and Status Register A

USART Control and Status Register A
  • Bit 7 - RXC : USART Receiver Complete
It's set whenever there's an unread data in the buffer otherwise it's clear whenever the buffer is empty.
  • Bit 6 - TXC : USART Transmit Complete
It's set when there's no current data in the UDR that's mean that the data is already shift out.
  • Bit 5 - UDRE : USART Data Register Empty
If it's one it indicates that the transmit buffer UDR ready to be written to.
  • Bit 4 - FE : Frame Error
Typically the stop bit of the UART is 1. When the data is read from the buffer with a zero stop bit then this bit is set indicating the frame error.
  • Bit 3 - DOR : Data OverRun
This bit is set indicating that the unread buffer of the size of two character is full and a new start bit has detect to force the module receiving the incoming data.
  • Bit 2 - PE : Parity Error
With the parity checker enabled and the data read from UDR has a wrong parity bit then this bit is set.
  • Bit 1 - U2X : Double the USART Transmission Speed
This bit only effect the asynchronous operation. Setting this bit to 1 to double the speed of the UART. This reduces the baud rate division from 16 to 8 then double the BAUD.
  • Bit 0 - MPCM : Multi-processor Communication Mode
This bit relates to multiprocessor communication mode.

USART Control and Status Register B

USART Control and Status Register B

  • Bit 7 - RXCIE : RX Complete Interrupt Enable
Writing this bit to 1 to enable the receiver complete interrupt. It relates to the other interrupt control register and the RXC flag bit.
  • Bit 6 - TXCIE : TX Complete Interrupt Enable
Writing this bit to 1 to enable the transmitter completion of data transfer interrupt. It relates to the other interrupt control register and the TXC flag bit.
  • Bit 5 - UDRIE : USART Data Register Empty Interrupt Enable
Setting this bit to enable the UDRE interrupt flag. It relate to the other interrupt control register and the UDRE bit of the UCSRA.
  • Bit 4 - RXEN : Receiver Enable
Setting this bit to 1 to turn on the USART receiver and the RxD of the MCU is also enabled.
  • Bit 3 - TXEN : Transmitter Enable
Setting this bit to 1 to turn on the USART transmitter and the TxD of the MCU is also enabled.
  • Bit 2 - UCSZ2 : Character Size
This bit combines with the UCSZ1:0 bit to select the number of data bits.
  • Bit 1 - RXB8 : Receive Data Bit 8
When selecting the 9-bit data mode this bit is the ninth bit of the received data.
  • Bit 0 - TXB8 : Transmit Data Bit 8
When selecting the 9-bit data mode this bit is the ninth bit of the data to transmit.

USART Control and Status Register C

USART Control and Status Register C

This register shares the same I/O location as the UBRRH register. For more details please see the device data sheet.
  • Bit 7 - URSEL : Register Select
This bit uses for switching between the UCSRC and the UBRRH register. It's 1 by default selecting the UCSRC register.
  • Bit 6 - UMSEL : USART Mode Select
Setting this bit to 0 to select the Asynchronous operation otherwise it's the synchronous operation.
  • Bit 5:4 - UPM1:0 : Parity Mode
These two bit configure the generation of the parity bit and also the error checking. If the mismatch condition is met it will set the PE bit of the UCSRA register.

Parity Mode
  • Bit 3 - USBS : Stop Bit Select
By default it's 0 which set the number of stop bits to 1. Setting this bit to 1 giving the 2 stop bits.
  • Bit 2:1 - UCSZ1:0 Character Size
These two bit combine with the UCSZ2 to configure the numbers of the USART data bits.

Character Size Selections

  • Bit 0 - UCPOL : Clock Polarity
It's used for the synchronous operation only.

Clock Polarity

USART Baud Rate Generator - UBRRL and UBRRH

The UBRRH shares the same I/O location with the UCSRC register. These two-register pairs set the baud rate of the USART. However it uses only 12-bit of accessible bits of this pairs. 

USART baud rate generator

BAUD Selecting Example

Without using any calculation the find the UBRRH:L value we can use a simple from the device data sheet to set those register manually and get the specific baud rate of the USART. 

BAUD selection table for a commonly used crystal clock frequency

For most of math calculation it often has some error in rounding. The error in percent is shown in the equation below.


USART Connection to its Peripheral Devices

Many microcontroller external add-on modules use USART communication protocol as in an example of the popular GSM modem module.
ATMega32 AVR Universal Asynchronous Receiver Transmitter (UART)
Some UART based communication devices

These devices use their commands for example the AT command for GSM and Bluetooth module, the display instructions for the Nextion HMI display module.

A host PC is an application of the personal computer based control and instrumentations. However the original PC interface to the MCU USART requires and RS-232 voltage level. It is a long range data communication method. 
A PC Serial Port comes with a Desktop PC

To make a communication between a host PC and MCU USART, it requires a voltage level converter module as an instant the MAX-232 bridge.

MAX232 adapter board on an online market 
place

The RS-232 has a voltage level of +/-12V while the MCU USART has a TTL +5V voltage level.

However due to the advancement of the semiconductor chip developments, the old PC serial port could be replace with the USB-Serial converter chip at a lower cost and ease of use - for example the FT-232 from the FDI semiconductor. 

FT232 USB-Serial converter module from an online market place

These chips work at 5V TTL and 3.3V supply and communication voltage level.

AVR Programming For The USART

To program the USART module of the AVR ATMega32 we must initialize the module first.
  1. set the numbers of the data bits
  2. set the numbers the stop bits
  3. enable or disable the parity checker
  4. Select and appropriate baud rate by working with the UBRR register.
To send and receive the UART data we must follow the following steps,
  1. enable the receiver and the transmitter
  2. put the data into the UDR register
  3. wait until the completion
Optionally we can use the USART interrupt to more efficient in timing of the operation.

An MCU Transmitter Example

For an introductory example we demonstrate how to configure the USART as a transmitter that send some characters to the PC UART terminal.

/*
 * uart_basic.c
 *
 * Created: 9/28/2020 8:19:06 PM
 * Author : aki-technical
 */ 

#include <avr/io.h>

#define F_CPU 16000000UL
#include <util/delay.h>

void uartInit(unsigned long baud){
unsigned int UBRR;
/*Baud rate calculator*/
UBRR=(F_CPU/(16*baud))-1;
UBRRH=(unsigned char)(UBRR>>8);
UBRRL=(unsigned char)UBRR;
/*Enable the transmitter and receiver*/
UCSRB=(1<<RXEN)|(1<<TXEN);
/*asynchronous mode, 8-bit, 1-stop bit*/
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

void uartTransmit(unsigned char data){
/*Stay here until the buffer is empty*/
while(!(UCSRA&(1<<UDRE)));
/*Put the data into the buffer*/
UDR=data;
}

int main(void)
{
    uartInit(9600);
    uartTransmit('H');
    uartTransmit('i');
    while (1) 
    {
    }
}

Click here to download zip file of this working example.

ATMega32 AVR Universal Asynchronous Receiver Transmitter (UART)
Schematic Diagram

The schematic shows only a virtual terminal that could emulate the host PC serial port.

A C Pointer Example

With the advantage of using the C pointer the numbers of character is flexible in sizing. We can send a string of character to the UART transmitter.

/*
 * uart_basic_with pointer.c
 *
 * Created: 9/29/2020 7:05:51 PM
 * Author : aki-technical
 */ 

#include <avr/io.h>

#define F_CPU 16000000UL
#include <util/delay.h>

void uartInit(unsigned long baud){
unsigned int UBRR;
/*Baud rate calculator*/
UBRR=(F_CPU/(16*baud))-1;
UBRRH=(unsigned char)(UBRR>>8);
UBRRL=(unsigned char)UBRR;
/*Enable the transmitter and receiver*/
UCSRB=(1<<RXEN)|(1<<TXEN);
/*asynchronous mode, 8-bit, 1-stop bit*/
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

void uartTransmit(unsigned char data){
/*Stay here until the buffer is empty*/
while(!(UCSRA&(1<<UDRE)));
/*Put the data into the buffer*/
UDR=data;
}

void sendText(char *txt){
while(*txt) uartTransmit(*txt++);
}

int main(void)
{
uartInit(9600);
sendText("Hello From ATMega32 AVR!");
while (1)
{
}
}

Click here to download the zip file of this working example. The schematic diagram remain the same as the previous one's.

ATMega32 AVR Universal Asynchronous Receiver Transmitter (UART)
UART with C pointer example

USART Receive and Transmit Example

The receiver of the USART can be enabled by setting the RXEN to '1'. To get the data from the USART receiver the program must test the UDRE bit until it's empty then the data can be read from the UDR.

In this example the host PC terminal send the character to the MCU USART then it echo the character to the host PC again.

/*
 * uart_Tx_Rx.c
 *
 * Created: 9/29/2020 7:18:40 PM
 * Author : aki-technical
 */ 

#include <avr/io.h>

#define F_CPU 16000000UL
#include <util/delay.h>

void uartInit(unsigned long baud){
unsigned int UBRR;
/*Baud rate calculator*/
UBRR=(F_CPU/(16*baud))-1;
UBRRH=(unsigned char)(UBRR>>8);
UBRRL=(unsigned char)UBRR;
/*Enable the transmitter and receiver*/
UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXEN);
/*asynchronous mode, 8-bit, 1-stop bit*/
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

void uartTransmit(unsigned char data){
/*Stay here until the buffer is empty*/
while(!(UCSRA&(1<<UDRE)));
/*Put the data into the buffer*/
UDR=data;
}

 unsigned char uartReceive(){
/*Wait until the buffer is full*/
while(!(UCSRA&(1<<RXC)));
/*Get the data ready to use*/
return UDR;
}

void sendText(char *txt){
while(*txt) uartTransmit(*txt++);
}

int main(void)
{
char tmp;
DDRC=0xFF;
uartInit(9600);
sendText("ATMEGA32 AVR UART Receive/Transmit Example.\n\r");
while (1)
{
tmp=uartReceive();
PORTC=tmp;
uartTransmit(tmp);
}
}

The schematic diagram a little add-on.

ATMega32 AVR Universal Asynchronous Receiver Transmitter (UART)
Schematic Diagram

Click here to download the zip file of this working example.


No comments:

Post a Comment

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (54) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (46) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (66) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (2) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (30) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)