三十、STM32的USART (串口发送+接收)

前言:在学习 STM32 的过程中,串口通信(USART) 是最常用、也是最基础的外设之一。

它不仅可以用来输出调试信息,还常被用于与其他模块(如 GPS、蓝牙、WiFi、传感器等)之间进行通信。上一篇文章我们介绍了 STM32 USART 的发送功能,本文将重点讲解 USART 的接收机制 ------ 包括初始化配置、接收中断、数据读取与显示。同时,我们还将通过 OLED 显示模块来观察接收到的数据,从而直观了解整个数据流过程。相关发送的博客二十九、STM32的USART (串口发送)

目录

[一、USART 接收原理简介](#一、USART 接收原理简介)

[二、USART 接收程序结构分析](#二、USART 接收程序结构分析)

[三、USART 初始化配置](#三、USART 初始化配置)

[四、SART 接收中断服务函数](#四、SART 接收中断服务函数)

五、接收标志位与数据读取函数

六、主函数与数据回显

七、运行结果与测试现象

八、总结


一、USART 接收原理简介

USART(Universal Synchronous/Asynchronous Receiver/Transmitter,通用同步/异步收发器)是一种通用的串行通信接口。

在异步模式下,它主要依靠起始位和停止位来同步数据帧,而接收端通过中断机制检测并读取接收到的数据。

USART 的接收流程可以概括为以下几步:

  1. 当数据帧到达时,USART 硬件自动检测起始位;

  2. 数据按位采样后存入接收数据寄存器;

  3. RXNE(接收缓冲非空)标志位置 1;

  4. 若使能了中断,CPU 会自动跳转到中断函数中;

  5. 用户代码读取寄存器数据;

  6. 读取后 RXNE 自动清零,等待下一次接收。

二、USART 接收程序结构分析

我们在本例中使用 USART1 进行通信。

引脚配置如下:

三、USART 初始化配置

复制代码
void Serial_Init(void)
{
    /* 开启时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    /* 配置 TX 引脚 PA9 为复用推挽输出 */
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* 配置 RX 引脚 PA10 为上拉输入 */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* USART 参数配置 */
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;                            // 波特率
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;       // 启用收发模式
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_Init(USART1, &USART_InitStructure);

    /* 开启接收中断 */
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

    /* NVIC 配置 */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* 使能 USART1 */
    USART_Cmd(USART1, ENABLE);
}

这部分代码完成了:

✅ 时钟开启

✅ GPIO 配置(PA9 / PA10)

✅ 串口通信参数初始化

✅ 开启 RXNE 接收中断

✅ 配置 NVIC 优先级与中断入口

四、SART 接收中断服务函数

当串口接收到数据后,RXNE 标志位置 1,并自动触发中断。

以下是中断函数:

复制代码
void USART1_IRQHandler(void)
{
    if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)  // 判断是否为接收中断
    {
        Serial_RxData = USART_ReceiveData(USART1);        // 读取接收数据
        Serial_RxFlag = 1;                                // 设置标志位
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);   // 清除中断标志位
    }
}

注意:

  • 读取 USART_ReceiveData() 后,RXNE 位会自动清零。

  • 为了防止遗漏,也可以手动调用 USART_ClearITPendingBit() 清除标志。

  • 中断函数名称必须与启动文件定义的保持一致,否则不会被调用。

五、接收标志位与数据读取函数

为了让主函数方便使用,我们定义了两个接口函数:

复制代码
uint8_t Serial_GetRxFlag(void)
{
    if (Serial_RxFlag == 1)
    {
        Serial_RxFlag = 0;
        return 1;
    }
    return 0;
}

uint8_t Serial_GetRxData(void)
{
    return Serial_RxData;
}

这样主循环中就可以用"轮询方式"来检测是否收到新数据。

六、主函数与数据回显

主函数的逻辑非常清晰:

1️⃣ 等待串口接收标志位;

2️⃣ 读取接收数据;

3️⃣ 通过串口将数据回传(即回显测试);

4️⃣ 通过 OLED 显示接收的内容。

复制代码
int main(void)
{
    OLED_Init();                // 初始化 OLED
    OLED_ShowString(1, 1, "RxData:");

    Serial_Init();              // 初始化串口

    while (1)
    {
        if (Serial_GetRxFlag() == 1)            // 检测是否接收到数据
        {
            RxData = Serial_GetRxData();        // 读取接收数据
            Serial_SendByte(RxData);            // 将数据回显
            OLED_ShowHexNum(1, 8, RxData, 2);   // 显示数据的十六进制值
        }
    }
}

七、运行结果与测试现象

  1. 打开串口调试助手,设置波特率为 9600。

  2. 向 STM32 发送任意字符(例如字母 A)。

  3. OLED 显示屏上将显示接收到的数据(十六进制形式,如 0x41)。

  4. 串口助手也会收到 STM32 回传的相同数据。

八、总结

通过本次实验,我们实现了 STM32C8T6 的 USART 接收功能,并通过中断机制实现了高效、可靠的数据获取。

🔹 重点知识回顾:

  • USART 的接收由硬件自动检测起始位;

  • RXNE 标志位指示接收缓冲区状态;

  • 中断方式比轮询方式更高效;

  • 通过标志位机制实现主循环与中断的解耦;

  • 接收到的数据可用于显示、处理或回传测试。

相关推荐
Mr-pn-junction9 小时前
clk_gate
单片机·嵌入式硬件·fpga开发
尼喃13 小时前
662K和65Z5三脚稳压芯片PW6566,附引脚定义与典型电路图
嵌入式硬件
李永奉17 小时前
杰理可视化SDK开发-【BUG】配置“TWS两边同时按消息使能”功能后,按键单击功能无效失灵
开发语言·单片机·嵌入式硬件·物联网·bug
执迷不悟82317 小时前
51单片机--中断/定时/PWM
单片机·嵌入式硬件·51单片机
A小调的码农19 小时前
OPENOCD+MSYS+VSCODE:从“灯不亮“到“终于亮了“
ide·vscode·stm32·单片机·编辑器
AI的探索之旅19 小时前
让 Claude Code 直接操刀画原理图和 PCB:VSCode 插件接外部 API 全流程
linux·ide·vscode·嵌入式硬件·编辑器
Dlrb121120 小时前
单片机通信协议---串口及串口通信
单片机·嵌入式硬件·串口·uart·modbus·波特率·主机从机
嵌入式-老费21 小时前
esp32开发与应用(用好ttl转485模块)
stm32·单片机·嵌入式硬件
謓泽21 小时前
【6.30】芯片 Bring-up 三步核心|从短路检查到 SPI 排障全拆解!
单片机·嵌入式硬件
2CM_Embed21 小时前
Quartus II 工程编译与 FPGA 下载流程记录
嵌入式硬件·fpga开发