STM32之UART(通用异步收发器)通信
UART作为嵌入式开发的基础通信接口,其配置灵活性和低成本特性使其在STM32项目中广泛应用。掌握波特率计算、中断处理及DMA优化等关键技术,可显著提升系统实时性和稳定性。建议结合具体项目需求,灵活选择查询、中断或DMA模式。
·
STM32之UART(通用异步收发器)通信
一、UART通信概述
UART(Universal Asynchronous Receiver/Transmitter)是一种全双工异步串行通信协议,广泛应用于嵌入式系统中实现设备间的数据交互。其核心特点包括:
- 异步传输:无需时钟信号同步,通过起始位、数据位、校验位和停止位实现数据帧同步。
- 全双工模式:支持同时收发数据,典型应用场景如STM32与PC串口调试助手的通信。
- 灵活配置:支持多种波特率(如9600、115200)、数据位长度(8/9位)及校验方式(奇/偶/无校验)。
二、STM32的UART硬件特性
1. 硬件资源
- USART与UART区别:USART支持同步/异步模式,UART仅支持异步模式;STM32F103系列提供5个串口(3个USART,2个UART)。
- 关键引脚:
- TX(发送端):需配置为复用推挽输出(GPIO_Mode_AF_PP)
- RX(接收端):需配置为浮空输入(GPIO_Mode_IN_FLOATING)。
- 波特率计算:基于公式
波特率 = 串口时钟 / BRR寄存器值,例如72MHz时钟下115200波特率对应BRR=0x0271。
三、UART配置步骤(以STM32F103为例)
1. 硬件初始化
// 使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// GPIO配置
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
2. 串口参数配置
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
3. 中断配置(可选)
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 使能接收中断
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
四、代码实现与实例
1. 查询方式收发数据
// 发送字符串
void USART_SendString(USART_TypeDef* USARTx, char* str) {
while (*str) {
USART_SendData(USARTx, *str++);
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
}
}
// 接收单个字符
uint8_t USART_ReceiveChar(USART_TypeDef* USARTx) {
while (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET);
return USART_ReceiveData(USARTx);
}
2. 中断接收回显示例
void USART1_IRQHandler(void) {
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
uint8_t ch = USART_ReceiveData(USART1);
USART_SendData(USART1, ch); // 回传接收到的字符
}
}
3. 重定向printf函数
int fputc(int ch, FILE *f) {
USART_SendData(USART1, ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
return ch;
}
// 使用示例:printf("Hello STM32 UART!\r\n");
五、应用场景与调试技巧
1. 典型应用
- 串口调试:通过printf输出调试信息至PC端。
- 多设备通信:配置多个UART接口实现STM32与传感器、显示屏等外设的数据交互。
- 工业控制:结合RS485协议实现长距离通信。
2. 常见问题
- 波特率不匹配:确保收发双方波特率一致,误差需小于3%。
- 数据丢失:使用DMA或FIFO缓冲区提升高波特率下的稳定性。
- 电磁干扰:增加终端电阻或屏蔽线缆,降低误码率。
六、总结
UART作为嵌入式开发的基础通信接口,其配置灵活性和低成本特性使其在STM32项目中广泛应用。掌握波特率计算、中断处理及DMA优化等关键技术,可显著提升系统实时性和稳定性。建议结合具体项目需求,灵活选择查询、中断或DMA模式。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐

所有评论(0)