What is Communication Protocol
The communication protocol is a set of rules which has the main purpose to exchange digital messages between devices. These protocols have certain syntax and they ensure detection of error if any and its correction, signal transmission and authentication.
There are two types of communication protocol:
- Inter System Protocol
- Intra System Protocol
UART is a type of Inter System protocol and is mainly used for communication between two different devices.
Introduction to UART
UART stands for Universal Asynchronous Receive Transmit. It is one of the most fundamental types of communication protocol. Both the devices are connected with two wires, one is used for transmission and the other is used for receiving. In UART, the data is transferred digitally bit by bit. It is a half-duplex protocol which means either transferring or receiving will occur at a time.
Transmitting and Receiving
In the device which is transmitting, data is taken in the form of bytes and each byte is transmitted bit by bit sequentially. In the receiving end, bits received are assembled in the form of bytes. An algorithm is used at both ends to perform this task
Structure
- A clock generator for setting bit rate.
- Input and output shift registers.
- Transmission and receiving lines.
- Read and write algorithms.
How do two devices communicate?
Two UART’s are directly connected via two cables. On the transmitting end, the data in byte form is transmitted bit by bit and at the receiving end, it is again converted into a byte. The transmitting bit first sends the start bit so that the receiving end starts reading and after the data is transmitted, a stop bit is transferred so that the receiving end stops reading.
A specific frequency is set for defining the no. of bits being transferred per second. This is known as the baud rate. For a successful data transmission, the baud rate must be the same at both ends.
Explore Arduino Collection
Explaining the Data Packets in UART
The data transmitted by the UART is organized into packets with one start bit, 5 to 9 data bits (with the lowest bit first and the highest bit last), an optional parity bit finally followed by 1 or 2 stop bits.
Start Bit
The start bit is marked by a low voltage in the normally high voltage transmitting line for one clock cycle. This tells the receiving UART to start reading the bits at an accurate baud rate, thus marking the start of a data packet.
Parity Bit
Parity Bit is used to inform the receiving UART for changes caused to the data by electromagnetism, different baud rates, or by the long-distance transmission of data. If the parity bit is set to even it ensures that the number of 1’s in the data including parity is even, that is if there are even numbers of 1’s in the data, the parity bit will be 0 and if there are odd numbers of 1’s in the data, the parity bit will be 1. Similarly, if it is set to odd parity it will ensure that the number of 1’s in the data is odd including parity. If the parity bit matches the data then we can be sure that the data was free of error.
Stop Bit
This marks the end of data by driving the transmission line to a high voltage for one or two clock cycles.
Baud Rate
The time interval between two bits is known as baud rate, which is calculated as bits per second. Both the devices must have the same baud rate so that the receiver can interpret the data at the right intervals of time as sent by the transmitter. Higher baud rates have higher chances of corruption of data, thus lower baud rates are used to decrease the chances of error in the transmitted data
How the data packets are transmitted
UART receives data in the form of a data bus from devices such as microcontrollers, memory or CPU. A data package is made by adding a start bit, a parity bit (optional) and a stop bit to the data. The data packets are then transmitted using serial communication as follows:
- At the start, the receiver device is informed to start logging in data by sending the start bit first which as explained above is active low.
- After the start bit, the data ( 5 to 9 bit) is sent through the wire bit by bit from lowest bit first to a highest bit last whose time is dependent on their baud rate
- Parity bit, which is optional, is sent after the data byte. It helps to check the corruption of the received data
- According to its working described above the parity bit is encoded in the data packet and transmitted
- At the receiver side, the parity bit is used to confirm the credibility of the data received by counting the number of high bits and matching it with the parity. If the data is corrupted it is discarded and the error counter is incremented. If the error counter exceeds a certain value it is advised to reduce the baud rate which sacrifices speed for quality
- The parity bit is followed by one or two stop bits. 2 stop bits are generally used to give enough time in between consecutive data packets and which makes the transmission a bit slower and decreases the error rate
Errors in UART
Overrun Error
Such an error is caused when the receiver UART is unable to process the incoming data before the next data. For the buffer to not be filled the CPU or controller must service the UART quickly. Overrun error is caused by the filling of the buffer which in turn leads to loss of incoming data.
Parity Error
This error is caused when the parity bit does not match the data. This error can only take place if a parity bit is used in the data packet.
Framing Error
In the absence of a stop bit at the expected interval, a UART can trigger this error. A framing error will be signaled if the data packet does not arrive at the expected state and expected time. A break condition between the data packet can also cause this error.
Explore Audio Components
Overrun Error
In asynchronous mode, an empty buffer is treated as a sign that no data has remained transmitted. Thus, an empty buffer while transferring the data will give an underrun error.
Pros of UART
- Less power consumption
- Lower hardware complexity
- The clock is not required
- Less power consumption
- No need for software addressing
- It has a parity bit to check the quality
Cons of UART
- Has a limited data frame size
- Speed of data transfer is less
- The baud rates of both devices must be in a 10% range
read more : Implementation of ADC in AVR
Sample of an AVR code in which a microcontroller takes in analog input and sends it to another microcontroller to make a PWM
Transmitter
#ifndef F_CPU #define F_CPU 1000000UL #endif #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> //These are the basic functions we will be using throughout the programming #define SET_BIT(byte, bit) (byte |= (1 << bit)) #define CLEAR_BIT(byte, bit) (byte &= ~(1 << bit)) #define TOGGLE_BIT(byte, bit) (byte ^= (1 << bit)) #define BIT_IS_SET(byte, bit) (byte & (1 << bit)) #define BIT_IS_CLEAR(byte, bit) (!(byte & (1 << bit))) unsigned int Val; int main(void){ //Enable a pre-scalar (needed cause ADC gives max output for 50kHz to 200kHz whereas the in made clock works at 1MHz)(for 10bit input or more) SET_BIT(ADCSRA,ADPS2); //8-bit or 10-bit results || here we have shifted the result to left thus only requiring us to read ADCH for 8-bit SET_BIT(ADMUX,ADLAR); //The reference of the highest voltage SET_BIT(ADMUX,REFS0); //Turn on the ADC (analog to DC converter) feature SET_BIT(ADCSRA,ADEN); int UBRR_Value = 25;//for 2400 baud rate UBRR0H = (unsigned char) (UBRR_Value >> 8); UBRR0L = (unsigned char) UBRR_Value; UCSR0B = (1 << TXEN0); //Set the TX pin for sending data using UART UCSR0C = (1 << USBS0) | (3 << UCSZ00); //Set 2 stop bits || Alternative code for 8-bit length while (1) { ADCSRA |= (1 << ADSC); // start ADC conversion while(BIT_IS_SET(ADCSRA, ADSC)) {} // wait here until the chip clears the ADSC bit for us, which means the ADC is complete Val = (ADCH); //Gets the value from ADC while(!(UCSR0A & (1 << UDRE0))); // To check if TX is free for more data UDR0 = Val; //Send the value through to another microcontroller
} return(0); }
|
Receiver
#ifndef F_CPU #define F_CPU 1000000UL #endif #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> //These are the basic functions we will be using throughout the programming #define SET_BIT(byte, bit) (byte |= (1 << bit)) #define CLEAR_BIT(byte, bit) (byte &= ~(1 << bit)) #define TOGGLE_BIT(byte, bit) (byte ^= (1 << bit)) #define BIT_IS_SET(byte, bit) (byte & (1 << bit)) #define BIT_IS_CLEAR(byte, bit) (!(byte & (1 << bit))) /*DDRx is used to declare type in which the Pin is to be used PORTx is used to take in value or give out value based on DDRx PINx is used to check the value of a pin*/ unsigned int Val; int main(void){ SET_BIT(DDRB,PINB1); SET_BIT(PORTD,PINB1); //Set the wave form generation and time pre-scaling TCCR1A |= 1<<WGM11 | 1<<COM1A1; // WGM is to determine the type of counter || sets the mode of the PWM TCCR1B |= 1<<WGM12 | 1<<WGM13 | 1<<CS10; //CS is for prescalling //Set upper limit for time || Defines the TOP value ICR1 = 255; int UBRR_Value = 25;//for 2400 baud rate UBRR0H = (unsigned char) (UBRR_Value >> 8); UBRR0L = (unsigned char) UBRR_Value; UCSR0B = (1 << RXEN0); UCSR0C = (1 << USBS0) | (3 << UCSZ00); while (1){ while(!(UCSR0A & (1 << RXC0))); Val = UDR0; OCR1A = Val; } return(0); }
|
This blog has been submitted by KRSSG under the Robocraze Club Outreach Program.
Author: Vishesh & Vrihad