STM32——串口通信(USART)

一、串口通信 基础知识

1. 什么是串口通信

串口是 单片机与外界通信最简单、最常用的方式 。它通过 两根线(TX 发送、RX 接收) 实现数据互相传输:

  • 单片机 → 电脑 / 其他模块:发送数据(TX)
  • 电脑 / 其他模块 → 单片机:接收数据(RX)

一句话理解:串口就是单片机的 "嘴巴" 和 "耳朵",能发数据、能听数据。

2. 串口通信的作用

  • 程序调试(打印日志)
  • 与蓝牙、WiFi、GPS 模块通信
  • 与上位机(电脑)交互
  • 单片机之间互相通信

3. 串口通信的关键参数

必须收发双方完全一致,否则乱码:

  1. 波特率:通信速度(常用 9600、115200)
  2. 数据位:8 位(标准)
  3. 停止位:1 位
  4. 校验位:无校验(None)
  5. 流控制:无

4. STM32 串口资源

  • STM32F103 有 3 个串口:USART1、USART2、USART3
  • 默认引脚:
    • USART1:TX=PA9,RX=PA10
    • USART2:TX=PA2,RX=PA3
    • USART3:TX=PB10,RX=PB11

最常用:USART1(PA9、PA10)

5. 串口通信工作流程

电脑发数据 → RX 引脚收到 → 进入接收中断 → 读取数据单片机发数据 → TX 引脚发出 → 电脑接收显示

二、复用功能(串口必须用复用功能)

1. 什么是 GPIO 复用功能

一个 GPIO 引脚不只是输入 / 输出,还能变成:

  • 串口收发
  • 定时器 PWM
  • SPI、I2C
  • 外部中断

这种多功能切换 就叫 复用功能

2. 为什么串口必须用复用功能

TX、RX 不是普通输入输出,而是 串口外设专用功能引脚,必须开启复用模式。

3. 串口关键引脚模式

  • TX(PA9)复用推挽输出(GPIO_Mode_AF_PP)
  • RX(PA10)浮空输入 / 上拉输入(GPIO_Mode_IN_FLOATING)

4. 必记知识点

  • 串口必须开启 GPIO 时钟
  • 串口必须开启 USART 外设时钟
  • 引脚必须配置为 复用功能

三、重映射(串口引脚重定义)

1. 什么是重映射

有些引脚不够用,可以把默认串口引脚 换到别的引脚,这就叫重映射。

2. USART1 重映射规则

  • 默认:TX=PA9,RX=PA10
  • 重映射:TX=PB6,RX=PB7

开启重映射需要:

复制代码
GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);

3. 重映射作用

  • 方便布线
  • 解决引脚冲突
  • 灵活分配硬件资源

4. 不重映射也能用

直接用默认引脚 PA9、PA10 最简单

四、中断嵌套控制器 NVIC(串口中断)

1. 为什么要用串口中断

  • 不用一直循环检测是否收到数据
  • 收到数据自动进入中断
  • 效率高、不占用 CPU

2. NVIC 在串口中断中的作用

  • 开启串口接收中断
  • 设置中断优先级
  • 管理中断嵌套

3. 串口中断优先级规则

  • 数字越小,优先级越高
  • 抢占优先级 > 子优先级
  • 一般设置:
    • 抢占优先级:1
    • 子优先级:1

4. 串口接收中断流程

电脑发数据 → RX 收到 → 触发中断 → 进入中断服务函数 → 读取数据

五、STM32 串口 USART 标准配置步骤

1、提前配置:中断分组(整个工程只配一次)

复制代码
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

第 1 步:开启 GPIO 时钟 + 串口时钟

复制代码
RCC_APB2PeriphClockCmd(
    RCC_APB2Periph_GPIOA |
    RCC_APB2Periph_USART1,
ENABLE);

第 2 步:配置 TX(PA9)复用推挽输出

复制代码
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);

第 3 步:配置 RX(PA10)浮空输入

复制代码
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStruct);

第 4 步:配置串口参数(波特率、数据位等)

复制代码
USART_InitTypeDef USART_InitStruct;

USART_InitStruct.USART_BaudRate = 9600;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStruct.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;

USART_Init(USART1, &USART_InitStruct);

第 5 步:开启接收中断(可选)

复制代码
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

第 6 步:配置 NVIC 中断优先级

复制代码
NVIC_InitTypeDef NVIC_InitStruct;

NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStruct);

第 7 步:使能 USART 外设

复制代码
USART_Cmd(USART1, ENABLE);

六、串口发送 / 接收标准函数模板

1. 发送一个字节

复制代码
void Usart_SendByte(USART_TypeDef *USARTx, uint8_t byte)
{
    USART_SendData(USARTx, byte);
    while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
}

2. 发送字符串

复制代码
void Usart_SendString(uint8_t *str)
{
    while(*str)
    {
        Usart_SendByte(USART1, *str);
        str++;
    }
}

3. 串口接收中断服务函数

复制代码
void USART1_IRQHandler(void)
{
    uint8_t ch;
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        ch = USART_ReceiveData(USART1);
        // 处理收到的数据
        USART_SendData(USART1, ch); // 回显
    }
}

七、浓缩口诀

开时钟 → 配 TX 复用 → 配 RX 输入 → 配置串口参数 → 开中断 → 配 NVIC → 使能串口

八、串口常用对应表

串口 TX RX 中断函数
USART1 PA9 PA10 USART1_IRQHandler
USART2 PA2 PA3 USART2_IRQHandler
USART3 PB10 PB11 USART3_IRQHandler

九、新手必避 4 个坑

  1. TX 必须是复用推挽输出
  2. RX 必须是浮空输入
  3. 波特率必须和串口助手一致
  4. 必须使能 USART 外设
相关推荐
iCxhust1 小时前
微机原理实践教程(C语言篇)---A002流水灯
c语言·开发语言·单片机·嵌入式硬件·51单片机·课程设计·微机原理
Deitymoon3 小时前
STM32——外部中断按键控制led
stm32·单片机·嵌入式硬件
czwxkn4 小时前
7STM32(stdl)flash内部闪存
stm32·单片机·嵌入式硬件
咕噜咕噜啦啦4 小时前
STlink下载程序
stm32·单片机
Deitymoon5 小时前
STM32——串口中断接收
stm32·单片机·嵌入式硬件
charlie1145141916 小时前
嵌入式C++实践开发第21篇(单片机实践):按钮输入 —— 硬件原理、消抖与HAL API
开发语言·c++·单片机
一起搞IT吧6 小时前
Android性能系列专题理论之十一:block IO问题分析思路
android·嵌入式硬件·智能手机·性能优化
余生皆假期-7 小时前
YuanHub 源码分析【一】FlashDB 初始化与项目应用
笔记·单片机·嵌入式硬件
Deitymoon7 小时前
STM32——串口通信发送数据
stm32·单片机·嵌入式硬件