三十、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 标志位指示接收缓冲区状态;

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

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

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

相关推荐
从零点2 小时前
STM32连接以太网失败自动重新连接
stm32·单片机·嵌入式硬件
dlwlrma_5162 小时前
NUCLEO-G0B1RE STM32G0B1RET6的学习(3)——SPI从DMA HAL库到应用层回调函数CallBack的定义
stm32
python百炼成钢2 小时前
13.RTC实时时钟
linux·stm32·单片机·嵌入式硬件·实时音视频
国科安芯3 小时前
FreeRTOS 在 AS32系列RISC-V 架构MCU电机驱动中的应用实践与优化
单片机·嵌入式硬件·安全·架构·压力测试·risc-v·安全性测试
染予3 小时前
GPIO中断实现流程
单片机·嵌入式硬件
门思科技3 小时前
LoRaWAN通信协议详解:架构、加密机制与核心应用
运维·服务器·网络·嵌入式硬件·物联网
小柯博客3 小时前
STM32MP1 没有硬件编解码,如何用 CPU 实现 H.264 编码支持 WebRTC?
c语言·stm32·嵌入式硬件·webrtc·h.264·h264·v4l2
Jerry丶Li5 小时前
二十九、STM32的USART (串口发送)
stm32·单片机·嵌入式硬件
d111111111d6 小时前
STM32外设学习-串口数据包笔记-(数据包的了解)
笔记·stm32·单片机·嵌入式硬件·学习