UART - From AVR to Linux to Logic Analyzer

2019/09/20 | Embedded

UART - From AVR to Linux to Logic Analyzer

Introduction

In this article, let’s see how a program running on Atmega328PU microcontroller can communicate to the external world using UART. In order to run through this exercise we need the below equipment.

  1. Atmega328PU Microcontroller
  2. Breadboard
  3. AVR/USBASP programmer
  4. USB to TTL Adapter
  5. Logic Analyzer
  6. Digital Oscilloscope

Atmega328PU pinout

It is an 8-bit microcontroller(uC) with the following pinout. All its digital pins are grouped into 4 banks(PA/PB/PC/PD). Atmega328PU microcontroller pinout diagram

USBASP programmer pinout

All of the pins highlighted on the uC with pink should be connected to the below appropriate usbasp pins

USBASP programmer pinout diagram

Complete setup with host

Below is the complete setup and USBASP, USB to TTL adapter, Logic Analyzer routed through a USB hub connected to the host machine. Hook the USB to TTL Adapter to TX pin to monitor the string in cutecom. Also, to actually see the electrical signals transmitted on the TX pin, connect the Logic Analyzer channel zero pin to TX pin of the uC.

Complete breadboard setup with USBASP, USB to TTL adapter, and Logic Analyzer connected via USB hub

Simple UART program to send information out of Atmega328PU

Below sample program will initialize the UART and transmits “Hello UART” string on TXD(PD1) pin on the uC.

Atmega328P UART register configuration reference

#include <string.h>
#include <avr/io.h>
#include <util/delay.h>
#include <util/setbaud.h>

void USART_Init() {
    // Set baud rate
    // By default, atmega328p runs at 1Mhz without external oscilator
    // So as per the data sheet the UBBR value should be 6 for 9600 baud rate
    UBRR0H = 0;
    UBRR0L = 6;

    UCSR0A &= ~(1 << U2X0);

    // Enable receiver and transmitter
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
    // Set frame format: 8data, 1stop bit
    UCSR0C = (3<<UCSZ00);
}

void USART_Transmit(unsigned char data) {
    // Wait for empty transmit buffer
    while (!(UCSR0A & (1<<UDRE0)));
    // Put data into buffer, sends the data
    UDR0 = data;
}

int main() {
    char outstr[50] = "Hello UART \r\n";
  
    USART_Init();
    DDRB = 0xff;
    while (1) {
        for (int i = 0; i < strlen(outstr); i++) {
            USART_Transmit(outstr[i]);  // to test
        }
    }
  
    return 0;
}

Flash the above program to the uC(check references for the sample makefile) and connect USB to TTL adapter to TX pin of the uC. Then fire up cutecom(as sudo) and connect the appropriate ttyUSB and make sure the baudrate is set to 9600.

USB to TTL adapter connected to microcontroller TX pin UART output displaying Hello UART in cutecom terminal

This confirms both the transmission of data from uC and reception on the host machine. But in order to actually look at the electrical signals we can use a cheap logic analyzer. This logic analyzer works with Saleae Logic Analyzer software.

Below is the waveforms captured and appropriately decoded in the logic analyzer software UART waveforms captured and decoded in Saleae Logic Analyzer software

Finally, If you are curious, you can also watch the same in a cheap oscilloscope like below! UART signal viewed on oscilloscope

References