STM32F103C8T6 的 UART 功能详解
STM32F103C8T6 芯片内置了 USART(Universal Synchronous/Asynchronous Receiver/Transmitter) 模块,支持标准的 UART(异步模式) 和 同步通信模式。以下是其 UART 功能的详细描述:
1. 硬件特性
- 支持数量:芯片包含 3 个独立的 USART 模块(USART1、USART2、USART3)。
- USART1:挂载在 APB2 总线(最高时钟频率 72 MHz)。
- USART2/USART3:挂载在 APB1 总线(最高时钟频率 36 MHz)。
- 引脚分配:
- USART1:TX (PA9)、RX (PA10) 或 复用引脚 (PB6/PB7)。
- USART2:TX (PA2)、RX (PA3) 或 复用引脚 (PD5/PD6)。
- USART3:TX (PB10)、RX (PB11) 或 复用引脚 (PC10/PC11)。
2. 数据帧格式
UART 传输的每帧数据包含以下可配置参数:
- 数据位长度:8 位或 9 位(通过
USART_WordLength
配置)。 - 停止位长度:1 位、1.5 位或 2 位(通过
USART_StopBits
配置)。 - 校验位:奇校验、偶校验或无校验(通过
USART_Parity
配置)。
3. 波特率生成
- 公式:波特率=USART 时钟频率16×USARTDIV
- 其中
USARTDIV
是一个 16 位浮点数(整数部分 + 小数部分),由波特率寄存器 (BRR
) 配置。 - 误差控制:波特率误差需小于 2%(建议使用芯片提供的波特率计算工具)。
4. 工作模式
- 异步模式(UART):
- 无时钟信号,仅需 TX/RX 双线通信。
- 支持全双工(同时收发)或半双工(单线双向)。
- 同步模式:
- 需额外时钟线(SCLK),适用于高速通信。
- 支持主从设备配置。
5. 中断与 DMA 支持
- 中断类型:
- 发送完成(TXE)、接收就绪(RXNE)、校验错误、噪声错误、帧错误等。
- 可通过中断服务程序(ISR)实现实时数据处理。
- DMA 支持:
- 支持 DMA 传输,降低 CPU 负载。
- 适用于高速大数据量传输(如 GPS 数据接收)。
6. 硬件流控制(可选)
- RTS(Request to Send):通知对方本机接收缓冲区状态。
- CTS(Clear to Send):接收对方 RTS 信号以控制数据流。
- 需额外引脚(如 USART1 的 RTS: PA12,CTS: PA11)。
7. 多处理器通信
- 静默模式(Mute Mode):
- 接收器仅在检测到特定地址字节时唤醒,适用于多设备总线通信。
- 通过
WAKE
位配置地址匹配模式(4 位或 7 位地址)。
8. 错误检测与恢复
- 校验错误:数据位与校验位不匹配时触发中断。
- 噪声检测:通过采样多次消除信号毛刺。
- 帧错误:停止位未正确检测时触发中断。
- 溢出错误:接收缓冲区未及时读取导致数据丢失。
9. 低功耗特性
- 睡眠模式:UART 可配置为在睡眠模式下保持活动,唤醒 CPU。
- 自动波特率检测:部分型号支持 LIN 协议的自动波特率同步。
上完整程序模版,复制可用,已详细注释
#include "stm32f10x.h"
// 函数声明
void USART1_SendChar(char c);
void USART1_SendString(char *str);
char USART1_ReceiveChar(void);
int main(void) {
//---------------- 1. 时钟配置 -----------------
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// 使能GPIOA和USART1时钟(USART1挂载在APB2总线,最高72MHz)
//---------------- 2. GPIO初始化 -----------------
GPIO_InitTypeDef GPIO_InitStruct;
// 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);
// RX引脚配置(PA10:浮空输入)
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入模式
GPIO_Init(GPIOA, &GPIO_InitStruct);
//---------------- 3. USART参数配置 -----------------
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 115200; // 波特率设置(常用9600/115200)
USART_InitStruct.USART_WordLength = USART_WordLength_8b; // 数据位:8位
USART_InitStruct.USART_StopBits = USART_StopBits_1; // 停止位: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); // 应用配置
//---------------- 4. 中断配置(可选)-----------------
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 使能接收中断
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; // 中断通道
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; // 子优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; // 使能中断
NVIC_Init(&NVIC_InitStruct);
//---------------- 5. 启动USART -----------------
USART_Cmd(USART1, ENABLE); // 使能USART1
// 示例:发送启动信息
USART1_SendString("USART Initialized\r\n");
while(1) {
// 接收回显示例
char c = USART1_ReceiveChar(); // 阻塞式接收
USART1_SendChar(c); // 回显字符
}
}
//---------------- 6. 中断服务函数 -----------------
void USART1_IRQHandler(void) {
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
// 接收中断处理(自动清除RXNE标志)
char c = USART_ReceiveData(USART1); // 读取接收数据
USART1_SendChar(c); // 示例:回显数据
}
}
//---------------- 7. 基础通信函数 -----------------
void USART1_SendChar(char c) {
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // 等待发送缓冲区空
USART_SendData(USART1, c); // 写入发送寄存器
}
void USART1_SendString(char *str) {
while(*str) {
USART1_SendChar(*str++); // 逐字符发送
}
}
char USART1_ReceiveChar(void) {
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); // 等待接收完成
return USART_ReceiveData(USART1); // 返回接收数据
}
代码功能说明与参数详解
1. 时钟配置
-
RCC_APB2Periph_GPIOA
:USART1的TX/RX引脚在GPIOA端口,需开启时钟 -
RCC_APB2Periph_USART1
:USART1模块时钟使能(必须单独开启) - 注意:APB2总线时钟为72MHz,决定最高波特率支持
2. GPIO初始化
- TX引脚(PA9):
-
GPIO_Mode_AF_PP
:复用推挽输出,确保信号驱动能力
-
- RX引脚(PA10):
-
GPIO_Mode_IN_FLOATING
:浮空输入模式,适应外部信号电平
-
- 关键点:不同USART模块的引脚位置需查阅数据手册
3. USART参数配置
-
USART_BaudRate
:波特率,需与通信双方一致(误差<2%) -
USART_WordLength
:数据位长度,可选8b
或9b
-
USART_StopBits
:停止位,可选1
、0.5
或2
位 -
USART_Parity
:校验方式,可选No
(无校验)、Even
(偶校验)、Odd
(奇校验) -
USART_Mode
:工作模式,Rx
(接收)、Tx
(发送)可组合使用
4. 中断配置
-
USART_IT_RXNE
:接收中断使能(数据寄存器非空时触发) -
NVIC_Init
:配置中断优先级,优先级数值越小优先级越高
5. 基础通信函数
-
USART_SendChar()
:阻塞式发送单字符,等待发送完成 -
USART_ReceiveChar()
:阻塞式接收,持续等待数据到来 -
USART_SendString()
:字符串发送封装函数
6. 中断服务函数
- 自动清除标志:读取
USART_ReceiveData()
会自动清除RXNE
标志 - 典型应用:实现非阻塞接收,适合实时性要求高的场景
7.重要参数说明表
参数 | 典型值 | 说明 |
---|---|---|
USART_BaudRate | 9600, 115200 | 波特率误差需小于2%,计算工具:72MHz/(16 * 115200)=39.0625 → BRR=39.0625 |
USART_WordLength | 8b/9b | 9位模式常用于带校验位的通信 |
USART_StopBits | 1/0.5/2 | 停止位长度影响帧格式 |
USART_Parity | No/Even/Odd | 校验位可提高通信可靠性 |
USART_HardwareFlowControl | None/RTS/CTS/RTS_CTS | 硬件流控可防止数据溢出,需配合RTS/CTS引脚使用 |
8.应用场景
- 调试终端:通过串口助手查看程序运行状态
- 设备通信:与传感器、显示屏、无线模块等外设交互
- 固件升级:配合Bootloader实现远程更新
- 多机通信:通过地址字节实现主从设备通信
9.扩展功能
- DMA传输:
USART_DMACmd(USART1, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
- 自动波特率检测(需硬件支持):
USART_AutoRateCmd(USART1, ENABLE);
- 多缓冲器通信:
USART_MultiBufferModeCmd(USART1, ENABLE);
10. 应用场景
- 调试终端:通过 UART 输出调试信息(配合 PC 串口助手)。
- 工业通信:与传感器、PLC 等设备通信(Modbus 协议)。
- 无线模块控制:驱动蓝牙、Wi-Fi、LoRa 模块。
- 固件升级:通过 Bootloader 实现串口烧录。
11. 关键配置参数
- 波特率范围:
- USART1(APB2):最高 4.5 Mbps(72 MHz 时钟)。
- USART2/USART3(APB1):最高 2.25 Mbps(36 MHz 时钟)。
- 时钟源:由系统时钟分频后提供,需确保波特率计算与时钟树匹配。
12. 注意事项
- 抗干扰设计:长距离通信时需增加 RS485 转换芯片或终端电阻。
- 时钟配置:APB1/APB2 总线时钟错误将导致波特率偏差。
- 中断优先级:高实时性场景需合理分配中断优先级。