Blog Datasheets Home About me Clients My work Services Contact

G2Labs Grzegorz Grzęda

Serial Communication with UART on AVR Atmega-328

February 27, 2024

Serial Communication with UART on AVR Atmega-328

In this blog post, we will explore how to establish serial communication with UART (Universal Asynchronous Receiver Transmitter) on AVR Atmega-328 microcontroller. UART is a widely used communication protocol for sending and receiving data between microcontrollers and other devices.

Introduction to UART

UART is an asynchronous serial communication protocol that allows for the transmission of data between devices using only two wires - one wire for data transmission (TX) and one wire for data reception (RX). It is commonly used for communication between microcontrollers, sensors, and other peripherals.

At the heart of UART communication is the baud rate. Baud rate refers to the speed at which data is transferred and is measured in bits per second (bps). Both the transmitting and receiving devices must be configured with the same baud rate to ensure successful communication.

UART on AVR Atmega-328

AVR Atmega-328 microcontroller is widely used in Arduino boards. It features a built-in UART hardware module, allowing for easy serial communication without the need for any additional hardware.

To utilize the UART on AVR Atmega-328, we need to configure specific registers - UCSRA, UCSRB, UCSRC, UBRRL, and UBRRH. These registers control various aspects of the UART module, such as enabling the transmitter and receiver, setting the baud rate, and configuring data frame size.

Configuring UART

Let’s take a look at an example of setting up UART communication on AVR Atmega-328:

 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
#include <avr/io.h>

void UART_init(uint16_t baud_rate) {
    // Set baud rate
    uint16_t ubrr_value = F_CPU / 16 / baud_rate - 1;
    UBRR0H = (uint8_t)(ubrr_value >> 8);
    UBRR0L = (uint8_t)ubrr_value;

    // Enable receiver and transmitter
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);

    // Set frame format: 8 data bits, 1 stop bit
    UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);
}

void UART_send_byte(uint8_t data) {
    // Wait until the transmitter is ready
    while (!(UCSR0A & (1 << UDRE0)))
        ;

    // Send the data
    UDR0 = data;
}

uint8_t UART_receive_byte() {
    // Wait until data is received
    while (!(UCSR0A & (1 << RXC0)))
        ;

    // Return received data
    return UDR0;
}

In the UART_init function, we calculate the ubrr_value based on the desired baud rate and set the UBRR0H and UBRR0L registers accordingly. The UCSR0B register is set to enable the receiver and transmitter, while the UCSR0C register sets the frame format to 8 data bits and 1 stop bit.

The UART_send_byte function waits until the transmitter is ready (UDRE0 flag) and then writes the data to the UDR0 register for transmission.

The UART_receive_byte function waits until data is received (RXC0 flag) and then reads the received data from the UDR0 register.

Example Usage

Let’s now see an example of sending and receiving data using UART on AVR Atmega-328:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include <avr/io.h>

int main() {
    // Initialize UART with baud rate 9600
    UART_init(9600);

    // Send "Hello" via UART
    UART_send_byte('H');
    UART_send_byte('e');
    UART_send_byte('l');
    UART_send_byte('l');
    UART_send_byte('o');

    // Receive and echo back characters
    while (1) {
        uint8_t received_data = UART_receive_byte();
        UART_send_byte(received_data);
    }

    return 0;
}

In this example, we first initialize UART with a baud rate of 9600. We then send the string “Hello” character-by-character using the UART_send_byte function.

Finally, in the infinite loop, we continuously receive characters using the UART_receive_byte function and echo them back using the UART_send_byte function.

Conclusion

Serial communication with UART is a fundamental skill when working with microcontrollers. By utilizing the built-in UART hardware module on AVR Atmega-328 microcontroller, we can easily establish serial communication for data transmission and reception. The provided examples and explanations should help you get started with UART on your AVR projects. Happy coding!


➡️ More about databases in Flask


⬅️ Databases in Flask


Go back to Posts.