📜  uart 中断 (1)

📅  最后修改于: 2023-12-03 15:35:24.899000             🧑  作者: Mango

UART中断

简介

UART(Universal Asynchronous Receiver/Transmitter)是一种数据传输协议,用于将数据从一个设备传输到另一个设备。它通常用于连接计算机和周边设备(例如串行鼠标、打印机或调制解调器),以及嵌入式系统中。

UART中断是一种处理UART数据传输过程中产生的中断的机制。当接收到数据时,中断会被触发,处理器会停止当前任务并执行中断服务程序。中断服务程序会读取接收缓冲区的数据并进行处理。这个过程可以极大地提高串口通信的效率。

实现
初始化

在使用UART中断之前,首先需要初始化串口。具体方法会因不同的芯片和开发环境而异,下面以C语言为例。首先需要导入对应的头文件,并定义相关的变量。

#include <avr/io.h>   // 导入AVR芯片的I/O操作头文件
#include <avr/interrupt.h>   // 导入AVR芯片的中断服务头文件

// 定义相关变量
#define BAUDRATE 9600   // 定义波特率为9600
#define UBRR_VAL ((F_CPU+BAUDRATE*8)/(BAUDRATE*16)-1)   // 计算UBRR值
#define BUFFER_SIZE 64   // 定义接收缓冲区大小

unsigned char buffer[BUFFER_SIZE];
unsigned char head = 0, tail = 0;

接下来,需要定义UART的初始化函数。下面是一种常见的初始化方法:

void uart_init(void) {
    UBRRH = (unsigned char)(UBRR_VAL>>8);
    UBRRL = (unsigned char)UBRR_VAL;
    UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

在这个函数中,首先设置波特率,然后开启接收和发送功能,并开启接收中断。最后设置数据位数为8位,并确保使用的是UCSRC寄存器而不是UBRRH寄存器。

中断服务程序

下面是一个简单的UART接收中断服务程序。它的功能是将接收到的字节存储到接收缓冲区中。

ISR(USART_RXC_vect) {
    unsigned char data = UDR;
    unsigned char next = (tail+1)%BUFFER_SIZE;
    if (next != head) {
        buffer[tail] = data;
        tail = next;
    }
}

在这个函数中,首先读取接收数据寄存器中的数据。然后将数据存储到接收缓冲区中,如果缓冲区已满则丢弃数据。最后更新tail指针的位置。

示例

下面是一个简单的例子程序,演示如何使用UART中断实现串口接收数据。

#include <avr/io.h>
#include <avr/interrupt.h>

#define BAUDRATE 9600
#define UBRR_VAL ((F_CPU+BAUDRATE*8)/(BAUDRATE*16)-1)
#define BUFFER_SIZE 64

unsigned char buffer[BUFFER_SIZE];
unsigned char head = 0, tail = 0;

void uart_init(void) {
    UBRRH = (unsigned char)(UBRR_VAL>>8);
    UBRRL = (unsigned char)UBRR_VAL;
    UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}

ISR(USART_RXC_vect) {
    unsigned char data = UDR;
    unsigned char next = (tail+1)%BUFFER_SIZE;
    if (next != head) {
        buffer[tail] = data;
        tail = next;
    }
}

int main(void) {
    uart_init();
    sei();   // 开启全局中断

    while(1) {
        if (head != tail) {
            unsigned char data = buffer[head];
            head = (head+1)%BUFFER_SIZE;
            // 处理接收到的数据...
        }
    }
}

在这个程序中,首先初始化UART并开启全局中断。然后在主循环中等待接收缓冲区中有数据到达。一旦有数据到达,就从接收缓冲区中读取一个字节并处理它。在处理完数据之后,程序会继续等待下一个字节到达。

总结

使用UART中断可以大大加速串口通信过程,尤其是在数据量比较大的情况下。需要注意的是,在处理UART中断时需要保证数据的完整性,避免出现丢包或者重复接收的情况。