0
0
Embedded Cprogramming~7 mins

UART interrupt-driven communication in Embedded C

Choose your learning style9 modes available
Introduction

UART interrupt-driven communication lets your microcontroller talk to other devices without waiting. It uses interrupts to handle data, so your program can do other things at the same time.

When you want to receive data from a sensor without stopping your program.
When sending data over UART and you donโ€™t want to wait for each byte to finish.
When you need to handle incoming messages quickly and efficiently.
When your program has multiple tasks and canโ€™t block on UART communication.
When you want to save power by letting the CPU sleep until data arrives.
Syntax
Embedded C
void UART_IRQHandler(void) {
    if (UART_Receive_Interrupt_Flag) {
        char received = UART_Read_Data();
        // Process received data
    }
    if (UART_Transmit_Interrupt_Flag) {
        if (more_data_to_send) {
            UART_Write_Data(next_byte);
        } else {
            Disable_Transmit_Interrupt();
        }
    }
}

The interrupt handler function name depends on your microcontroller and toolchain.

Inside the handler, check which UART interrupt happened (receive or transmit).

Examples
This example reads one byte when data arrives and stores it in a buffer.
Embedded C
void UART_IRQHandler(void) {
    if (UART_Receive_Interrupt_Flag) {
        char c = UART_Read_Data();
        buffer[index++] = c;
    }
}
This example sends bytes from a buffer one by one when the UART is ready to send.
Embedded C
void UART_IRQHandler(void) {
    if (UART_Transmit_Interrupt_Flag) {
        if (index < length) {
            UART_Write_Data(buffer[index++]);
        } else {
            Disable_Transmit_Interrupt();
        }
    }
}
Sample Program

This program simulates receiving 10 characters via UART using interrupts. The interrupt handler stores each character in a buffer. When the buffer is full, it prints the received characters.

Embedded C
#include <stdint.h>
#include <stdbool.h>

#define BUFFER_SIZE 10

volatile char rx_buffer[BUFFER_SIZE];
volatile uint8_t rx_index = 0;
volatile bool data_ready = false;

// Mock functions for UART hardware
bool UART_Receive_Interrupt_Flag = false;
char UART_Data_Register = 0;

char UART_Read_Data() {
    UART_Receive_Interrupt_Flag = false; // Clear flag
    return UART_Data_Register;
}

void UART_IRQHandler(void) {
    if (UART_Receive_Interrupt_Flag) {
        char c = UART_Read_Data();
        if (rx_index < BUFFER_SIZE) {
            rx_buffer[rx_index++] = c;
        }
        if (rx_index == BUFFER_SIZE) {
            data_ready = true;
        }
    }
}

int main(void) {
    // Simulate receiving data
    for (int i = 0; i < BUFFER_SIZE; i++) {
        UART_Data_Register = 'A' + i; // Letters A to J
        UART_Receive_Interrupt_Flag = true;
        UART_IRQHandler();
    }

    if (data_ready) {
        for (int i = 0; i < BUFFER_SIZE; i++) {
            // Print received data
            // In embedded, replace with actual output method
            // Here we use printf for demonstration
            printf("%c", rx_buffer[i]);
        }
        printf("\n");
    }
    return 0;
}
OutputSuccess
Important Notes

Interrupt-driven UART lets your program do other work while waiting for data.

Always clear the interrupt flag inside the handler to avoid repeated interrupts.

Make sure shared variables between main code and interrupt are declared volatile.

Summary

UART interrupt-driven communication uses interrupts to handle data without blocking.

It improves efficiency by letting the CPU do other tasks while waiting for UART data.

Interrupt handlers must check and clear interrupt flags and safely handle data.