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

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

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

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

相关推荐
贝塔实验室8 小时前
新手如何使用Altium Designer创建第一张原理图(三)
arm开发·单片机·嵌入式硬件·fpga开发·射频工程·基带工程·嵌入式实时数据库
@good_good_study8 小时前
STM32 ADC多通道采样实验
stm32·单片机·嵌入式硬件
Darken038 小时前
什么是“位带”?;在STM32单片机中有什么作用?
stm32·单片机·嵌入式硬件
清风6666669 小时前
基于单片机的智能豆浆机设计(加热打浆熬煮自动控制与防干溢保护)
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
Triumph++10 小时前
STM32工程(Kile5)生成Bin文件
stm32·嵌入式硬件
dian2008-ic10 小时前
Linux pcie【9】基于GIC-V3 ITS实现pcie msi中断
linux·arm开发·驱动开发·嵌入式硬件
清风66666610 小时前
基于51单片机的智能断路器设计:过压欠压过流温度实时监控与保护
单片机·嵌入式硬件·毕业设计·51单片机·课程设计·期末大作业
大智兄11 小时前
126.n32使用gpio模拟iic从模式,全靠外部中断实现
单片机·嵌入式硬件
集芯微电科技有限公司11 小时前
40V/3A高性能高集成三相BLDC驱动器具有电流及故障诊断功能(FLT)
c语言·数据结构·单片机·嵌入式硬件·fpga开发
li星野11 小时前
打工人日报#20251204
单片机·嵌入式硬件