打印
[经验分享]

基于笙泉(Megawin) MCU的串口通信应用与中断实现

[复制链接]
106|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Wordsworth|  楼主 | 2024-10-5 08:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

最近我在一个项目中使用笙泉(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,发送任何数据。
  • 你发送的字符会立即回显,并且通过中断机制处理。

例子演示了一个基础的串口通信系统,并且通过中断提高了数据接收的实时性,非常适合在嵌入式系统中做实时通信的应用。希望对你有帮助,欢迎提出问题和建议!

使用特权

评论回复
沙发
公羊子丹| | 2024-10-5 08:22 | 只看该作者
哇,这个串口通信的例子挺实用的,我刚好也在用笙泉的MCU,马上试试!

使用特权

评论回复
板凳
周半梅| | 2024-10-5 08:22 | 只看该作者
串口中断的实现看起来很清晰,之前一直卡在这部分,谢谢分享!

使用特权

评论回复
地板
帛灿灿| | 2024-10-5 08:23 | 只看该作者
代码很完整,我正好需要用到缓冲区的处理,感觉这篇帖子救了我!

使用特权

评论回复
5
童雨竹| | 2024-10-5 08:23 | 只看该作者
有点意思,直接在主循环回显接收的数据,调试起来应该很方便。

使用特权

评论回复
6
万图| | 2024-10-5 08:23 | 只看该作者
学到了!一直不知道怎么处理串口中断,现在终于搞明白了,感谢!

使用特权

评论回复
7
Bblythe| | 2024-10-5 08:23 | 只看该作者
有没有考虑过用DMA传输数据?串口传大量数据时中断频繁可能会影响性能。

使用特权

评论回复
8
Pulitzer| | 2024-10-5 08:24 | 只看该作者
这个回传功能挺好,可以直接通过串口助手观察数据流。

使用特权

评论回复
9
Uriah| | 2024-10-5 08:24 | 只看该作者
你用的是9600波特率,有没有试过更高的速率?感觉更高的速率会有些挑战。

使用特权

评论回复
10
Clyde011| | 2024-10-5 08:24 | 只看该作者
串口通信功能终于搞定了,完全参考你的代码,非常感谢!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

3579

帖子

1

粉丝