最近我在一个项目中使用笙泉(Megawin)的MCU,具体型号是MG82F6D17。这个芯片非常适合嵌入式低功耗的应用项目,尤其是带有丰富的外设接口,比如UART。我就通过它实现了一个完整的串口通信功能,并且增加了中断处理来优化数据传输。下面分享一下我的实现代码。
串口通信代码实现(使用中断)
首先,我们需要初始化UART,并启用中断,这样数据接收可以自动触发中断处理,避免主循环过多等待。以下是代码的具体实现:
#include <mg82f6d17.h>
#define BUFFER_SIZE 64 // 定义缓冲区大小
volatile char rxBuffer[BUFFER_SIZE]; // 接收缓冲区
volatile unsigned char rxIndex = 0; // 缓冲区索引
void UART_Init() {
SCON = 0x50; // 串口模式1,8位数据,1个停止位
TMOD |= 0x20; // 定时器1,模式2,自动重装
TH1 = 0xFD; // 波特率9600
TR1 = 1; // 启动定时器1
ES = 1; // 启用串口中断
EA = 1; // 全局中断使能
TI = 1; // 启动发送
}
void UART_Send(char data) {
SBUF = data;
while (!TI); // 等待发送完成
TI = 0;
}
void UART_SendString(char* str) {
while (*str) {
UART_Send(*str++); // 发送字符串每一个字符
}
}
void UART_ReceiveHandler() interrupt 4 { // 串口中断服务函数
if (RI) {
RI = 0; // 清除接收中断标志
rxBuffer[rxIndex++] = SBUF; // 将接收的数据保存到缓冲区
if (rxIndex >= BUFFER_SIZE) {
rxIndex = 0; // 防止缓冲区溢出
}
}
}
void main() {
UART_Init();
UART_SendString("UART Initialized\r\n");
while (1) {
if (rxIndex > 0) {
UART_Send(rxBuffer[rxIndex - 1]); // 回传接收到的最后一个字符
UART_Send('\r'); // 发送回车符
UART_Send('\n'); // 发送换行符
rxIndex = 0; // 清空接收索引
}
}
}
代码详细说明:- UART 初始化 (UART_Init):
- 配置串口为模式1(8位数据,1个停止位)。
- 通过定时器1设置波特率为9600。
- 启用串口中断(ES = 1)以及全局中断(EA = 1)。
- UART 发送函数 (UART_Send):
- 发送单个字符,通过检查发送中断标志 (TI) 来确认数据发送完成。
- UART 发送字符串函数 (UART_SendString):
- 实现发送整个字符串,逐个字符发送,常用于初始化或者发送消息。
- 串口中断服务程序 (UART_ReceiveHandler):
- 当接收到数据时,触发中断,将接收到的字符保存在 rxBuffer 缓冲区中。
- 索引递增,确保接收多个字符,且避免缓冲区溢出。
- 主循环 (main):
- 主循环不断检查是否接收到数据,如果有数据(rxIndex > 0),就将接收的数据回传,并发送回车换行符。
- 这个回传的过程可以方便地通过串口助手进行测试。
测试方法:- 使用 Keil 进行编译和烧录,确保串口助手已经连接到正确的串口。
- 打开串口助手,设置波特率为9600,发送任何数据。
- 你发送的字符会立即回显,并且通过中断机制处理。
例子演示了一个基础的串口通信系统,并且通过中断提高了数据接收的实时性,非常适合在嵌入式系统中做实时通信的应用。希望对你有帮助,欢迎提出问题和建议!
|