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

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

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

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

相关推荐
v先v关v住v获v取1 分钟前
番茄打浆机结构设计cad13+三维图+设计说明说
科技·单片机·51单片机
CQ_YM15 分钟前
网络编程之UDP
linux·c语言·网络·单片机·udp
小刘爱玩单片机16 分钟前
【stm32简单外设篇】- ESP8266 Wi-Fi 模块(ESP-01系列)
c语言·stm32·单片机·嵌入式硬件
点灯master19 分钟前
miniOTA:32位mcu平台OTA升级
单片机·嵌入式硬件
qqssss121dfd20 分钟前
计算机网络(第8版,谢希仁)第四章习题解答
服务器·c语言·网络·单片机·计算机网络
HarrySunCn21 分钟前
大夏龙雀DX-CT511N-B实战之路-第1步
前端·单片机·物联网·iot
田甲36 分钟前
STM32L051实现RTC低功耗唤醒
stm32·嵌入式硬件·实时音视频
清月电子9 小时前
杰理AC109N系列AC1082 AC1074 AC1090 芯片停产替代及资料说明
人工智能·单片机·嵌入式硬件·物联网
智嵌电子10 小时前
【笔记篇】【硬件基础篇】模拟电子技术基础 (童诗白) 第10章 模拟电子电路读图
笔记·单片机·嵌入式硬件