如果说 GPIO 和 PWM 是单片机的“手脚”,定时器是“脉搏”,那么 串口通信(UART) 就是单片机的“嘴巴”和“耳朵”。有了它,单片机就能把内部的运行数据(比如传感器的数值、调试信息)发送给电脑显示出来,也能接收电脑发来的指令。
1. 什么是 UART?(通俗理解)
UART (Universal Asynchronous Receiver/Transmitter),即通用异步收发传输器。
- 异步 (Asynchronous):意思是通信双方没有共同的时钟线(不像 SPI 或 I2C 有根时钟线牵着)。
- 收发 (Receiver/Transmitter):它有两根核心信号线:
- TX (Transmit):发送数据(嘴巴)。
- RX (Receive):接收数据(耳朵)。
- 全双工:因为有两根线,单片机可以一边说一边听,互不干扰。
2. UART 的“接头暗号”(通信参数)
既然没有时钟线同步,通信双方必须提前约定好“说话的速度”和“说话的格式”,否则就是鸡同鸭讲,显示乱码。
| 参数名称 | 常用设置 | 形象比喻 |
|---|---|---|
| 波特率 (Baud Rate) | 115200 / 9600 | 说话的速度(每秒钟发送多少个比特位)。 |
| 停止位 (Stop Bits) | 1 | 句号(一段话结束的标志)。 |
| 数据位 (Data Bits) | 8 bits | 单词长度(每次发 8 位,刚好一个字节)。 |
| 奇偶校验 (Parity) | None (无) | 逻辑纠错(检查话有没有传错)。 |
3. 硬件连接:必须“交叉”
这是初学者最容易犯错的地方。单片机和电脑(通过 USB-TTL 模块)连接时:
- 单片机的 TX(PA9) $\rightarrow$ USB-TTL 的 RX(我的嘴对着你的耳朵)
- 单片机的 RX(PA10) $\leftarrow$ USB-TTL 的 TX(你的嘴对着我的耳朵)
- GND $\leftrightarrow$ GND(必须共地,参考电压一致)
graph LR
subgraph STM32_MCU [STM32 开发板]
TX1[PA9 / TX]
RX1[PA10 / RX]
GND1[GND]
end
subgraph USB_TTL [USB-TTL 模块]
RX2[RXD]
TX2[TXD]
GND2[GND]
end
TX1 --- RX2
RX1 --- TX2
GND1 --- GND2
4. STM32CubeIDE 配置步骤
我们通常使用 USART1(它是单片机里最高速、最常用的串口)。
- 开启串口:在
.ioc文件左侧找到 Connectivity -> USART1。 - 设置模式:将 Mode 设为 Asynchronous(异步)。
- 你会发现引脚图上 PA9 (TX) 和 PA10 (RX) 变绿了。
- 配置参数:
- Baud Rate: 115200。
- Word Length: 8 bits。
- Stop Bits: 1。
- 生成代码:按
Ctrl + S。
5. 核心代码实现
A. 发送数据(让单片机说话)
|
|
![[Pasted image 20251221092640.png]]
B. 接收数据(让单片机听话)
在串口通信中,让单片机接收数据(听话)通常有两种方法:
- 轮询接收(Polling):单片机死等电脑发消息,不来就不干别的。
- 中断接收(Interrupt):单片机边干活边等,电脑一发消息就立刻停下活去处理。
在实际开发中,中断接收才是最专业、最常用的,这里单独开一篇学习—>[[ZZZ-15-串口通讯中断接收]]
6. 一个进阶的小技巧:重定向 printf
如果你想像在电脑上写 C 语言一样使用 printf("数值是: %d", value);,你需要做一个“重定向”。
第一步:包含头文件 在 main.c 最顶部的 USER CODE BEGIN Includes 区域:
|
|
第二步:重定向(告诉编译器 printf 往串口跑) 在 main.c 里的 MX_USART1_UART_Init() 函数之后,或者专门的 USER CODE BEGIN 0 区域:
|
|
这样,你之后所有的 printf 都会自动通过串口 1 发送到电脑上。
常见避坑指南
- 波特率不匹配:如果电脑串口助手设置的是 9600,单片机是 115200,你会看到满屏乱码。
- 未接 GND:如果不接地线,信号没有参考平面,也会产生乱码或无法接收。
- 阻塞问题:
HAL_UART_Receive在没收到数据前会一直卡在那(死等)。在正式项目中,我们通常会配合中断或 DMA 来接收数据。