📖 第 17 章:串口通信实验(USART)

🔧 正点原子《DMF407 开发指南》V1.0 · Chapter 17
🗨️ 「嵌入式开发最常用调试手段:串口让 MCU 会说话。」
这一章在干嘛? 串口通信实验:USART/UART 概念、波特率、帧格式、TX/RX 引脚复用、HAL 库阻塞与中断收发、printf 重定向、回环实验。理解后调试效率翻倍。
17.1 串口简介17.2 硬件设计17.3 程序设计17.4 下载验证

17.1 串口简介

17.1.1 数据通信的基础概念

术语含义
单工A→B 单向
半双工A↔B 双向但不能同时
全双工A↔B 可同时收发
串行数据一位一位发送
并行数据一次多位发送
同步带时钟线
异步无时钟线,靠波特率约定

USART = 通用同步异步收发器,常用异步模式即「串口」。

17.1.2 串口通信协议

串口帧格式:

[起始位 0] [数据位 D0..D7] [校验位 P] [停止位 1]
参数常用值
波特率9600 / 115200 / 921600
数据位8
校验位None
停止位1
流控None

原书图 17.1.2.1:串口帧格式示意图
原书图 17.1.2.1:串口帧格式示意图

双方波特率误差不能超过 2%,否则数据错位。

17.1.3 STM32 的 USART/UART

F407 有 6 个 USART + 2 个 UART,USART 支持同步/异步,UART 仅异步。

USART1/2/3 在 APB2(84 MHz),USART4/5/6 + UART7/8 在 APB1(42 MHz × 2 = 84 MHz,但分频后是 42 MHz)。

17.2 硬件设计

USART1 TX → PA9,RX → PA10(开发板已经通过 CH340 转 USB 接出)。

17.3 程序设计

17.3.1 编程步骤

  1. 开启 GPIOA / USART1 时钟;
  2. 初始化 PA9/PA10 为复用推挽/浮空输入;
  3. HAL_UART_Init(&huart1) 配置 115200-8-N-1;
  4. 发送:HAL_UART_Transmit(&huart1, buf, len, timeout);
  5. 接收:HAL_UART_Receive_IT(&huart1, buf, 1); + 回调。

17.3.2 关键代码

// 阻塞发送
HAL_UART_Transmit(&huart1, (uint8_t *)"Hello\n", 6, 100);

// 中断接收
HAL_UART_Receive_IT(&huart1, &rx_byte, 1);

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart->Instance == USART1) {
        HAL_UART_Transmit_IT(&huart1, &rx_byte, 1);  // 回环
        HAL_UART_Receive_IT(&huart1, &rx_byte, 1);    // 重启接收
    }
}

原书图 17.3.2.1:USART 框图
原书图 17.3.2.1:USART 框图

原书图 17.3.2.2:HAL_UART 收发流程图
原书图 17.3.2.2:HAL_UART 收发流程图

17.3.3 printf 重定向

printf("...") 直接发到串口:

int fputc(int ch, FILE *f) {
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 10);
    return ch;
}

MDK 勾选 Use MicroLIB。

MicroLIB 不支持浮点 printf:要用 sprintf + HAL_UART_Transmit 自己拼。

17.4 下载验证

XCOM 串口助手打开 COMx 115200 → 看到「Hello World」并支持键入字符回环。

原书图 17.4.1:串口助手回环实验现象
原书图 17.4.1:串口助手回环实验现象

🧠 小测验
串口常用参数 115200-8-N-1 含义?
115200 波特率、8 数据位、无校验、1 停止位。
USART 与 UART 的区别?
USART 支持同步/异步,UART 仅异步。
为什么中断接收后要再调一次 `HAL_UART_Receive_IT`?
HAL 中断模式只触发一次,必须手动重启。
printf 重定向的两个前提?
实现 fputc + 勾选 MicroLIB。
← 上一篇🏠 顶层目录下一篇 →