请用c语言在51平台上实现非阻塞的串口不定长中断接收,带有超时判断功能
时间: 2023-12-09 12:03:11 浏览: 89
关于串口中断发送数据的c语言程序
4星 · 用户满意度95%
好的,针对您的问题,我可以给出以下参考代码:
```c
#include <reg51.h>
#define UART_BAUDRATE 9600
#define UART_BUFF_SIZE 64
#define UART_TIMEOUT_MS 1000
unsigned char uart_buff[UART_BUFF_SIZE];
unsigned char uart_buff_idx = 0;
bit uart_data_ready = 0;
unsigned int uart_timeout_cnt = 0;
void uart_init() {
TMOD |= 0x20; // 设置定时器1为8位自动重载模式
TH1 = 256 - (11059200UL / 12 / 32 / UART_BAUDRATE);
TL1 = TH1;
TR1 = 1; // 启动定时器1
ES = 1; // 开启串口中断
EA = 1; // 开启总中断
}
void uart_isr() interrupt 4 {
if (RI) {
RI = 0;
uart_buff[uart_buff_idx++] = SBUF;
if (uart_buff_idx >= UART_BUFF_SIZE) {
uart_buff_idx = 0;
}
uart_data_ready = 1;
uart_timeout_cnt = 0;
}
}
void timer1_isr() interrupt 3 {
if (TF1) {
uart_timeout_cnt++;
if (uart_timeout_cnt >= (UART_TIMEOUT_MS / 10)) {
uart_timeout_cnt = 0;
uart_data_ready = 1;
}
TF1 = 0;
TH1 = 256 - (11059200UL / 12 / 32 / UART_BAUDRATE);
TL1 = TH1;
}
}
void main() {
uart_init();
TMOD |= 0x10; // 设置定时器0为16位定时计数模式
TH0 = (65536 - 11059) >> 8;
TL0 = (65536 - 11059) & 0xFF;
TR0 = 1; // 启动定时器0
while(1) {
if (uart_data_ready) {
// 处理接收到的数据
// ...
uart_data_ready = 0;
}
// 检查超时
if (uart_timeout_cnt >= (UART_TIMEOUT_MS / 10)) {
// 超时处理
// ...
uart_timeout_cnt = 0;
}
// 做其他事情
// ...
}
}
```
上述代码在前面的基础上增加了一个定时器0,用来检测超时情况。在每个定时器1中断中,我们将超时计数器递增,并在超时时间到达时设置标志位。在主循环中,我们检查标志位和超时计数器,如果数据已准备就绪或者超时时间到达,则进行相应的处理。这样,我们就实现了一个带有超时判断功能的非阻塞的串口不定长中断接收程序。
阅读全文