从数据帧到校验位:深入解析STM32串口通信的物理层与协议层
从数据帧到校验位:深入解析STM32串口通信的物理层与协议层
在嵌入式系统开发中,串口通信是最基础也是最常用的通信方式之一。无论是调试信息输出、设备间数据交换,还是与上位机通信,串口都扮演着不可或缺的角色。STM32系列微控制器内置了强大的USART(通用同步异步收发器)模块,支持全双工异步通信,为开发者提供了灵活且高效的通信解决方案。本文将深入探讨STM32串口通信的物理层特性、协议层机制以及实际应用中的关键配置细节,帮助开发者从理论到实践全面掌握串口通信技术。
1. 物理层:电平标准与硬件连接
串口通信的物理层定义了电气特性和机械特性,确保数据能够在设备间可靠传输。STM32的USART模块通常通过GPIO引脚与外部设备连接,最常用的引脚是TX(发送)和RX(接收)。
电平标准是物理层的核心概念。常见的串口电平标准有TTL和RS-232两种:
- TTL电平:逻辑1对应3.3V或5V,逻辑0对应0V,直接与微控制器引脚兼容
- RS-232电平:逻辑1对应-3V~-15V,逻辑0对应+3V~+15V,传输距离更远,抗干扰能力更强
在实际应用中,STM32的USART引脚输出的是TTL电平。如果需要与采用RS-232标准的设备通信,需要添加电平转换芯片如MAX3232。
硬件连接配置示例:
// 使能GPIOA和USART1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// 配置TX引脚(PA9)为复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置RX引脚(PA10)为浮空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
注意:STM32F1系列与F4系列在GPIO配置上存在差异。F4系列所有复用功能的引脚都应设置为GPIO_Mode_AF模式,而F1系列需要根据具体功能选择输入或输出模式。
2. 协议层:数据帧结构与传输机制
串口通信的协议层定义了数据包的格式和传输规则。一个完整的串口数据帧由起始位、数据位、校验位和停止位组成。
2.1 数据帧组成
起始位:标志一个数据帧的开始,固定为低电平,持续1个位时间。
数据位:实际传输的数据,可以是5-9位,STM32支持8位或9位数据长度。数据传输采用低位先行(LSB First)的方式。
校验位:用于错误检测,可选奇校验、偶校验或无校验。奇校验确保数据位和校验位中"1"的个数为奇数,偶校验则确保为偶数。
停止位:标志数据帧的结束,固定为高电平,可以是0.5、1、1.5或2个位时间。
下表总结了数据帧各组成部分的特性:
| 组成部分 | 电平状态 | 持续时间 | 可选参数 |
|---|---|---|---|
| 起始位 | 低电平 | 1位时间 | 固定 |
| 数据位 | 高/低电平 | 5-9位时间 | 8位或9位 |
| 校验位 | 高/低电平 | 1位时间 | 奇校验、偶校验、无校验 |
| 停止位 | 高电平 | 0.5-2位时间 | 0.5、1、1.5或2位 |
2.2 波特率与定时
波特率是指每秒传输的符号数,直接决定通信速度。STM32的USART使用小数波特率发生器,能够精确产生各种常用波特率。
波特率计算公式为:
波特率 = fPCLK / (16 * USARTDIV)
其中USARTDIV是一个无符号定点数,整数部分存放在USART_BRR寄存器的高12位,小数部分存放在低4位。
常用波特率配置示例(fPCLK=72MHz时):
| 目标波特率 | USARTDIV计算值 | BRR寄存器值 |
|---|---|---|
| 9600 | 468.75 | 0x1D4C |
| 115200 | 39.0625 | 0x271 |
| 230400 | 19.53125 | 0x138 |
3. STM32 USART功能架构与寄存器配置
STM32的USART模块提供了丰富的功能和灵活的配置选项,通过一系列寄存器实现通信控制。
3.1 核心寄存器介绍
USART_SR(状态寄存器):包含传输状态标志,如TXE(发送数据寄存器空)、TC(发送完成)、RXNE(接收数据寄存器非空)等。
USART_DR(数据寄存器):用于读取接收到的数据或写入要发送的数据。实际包含两个寄存器:TDR(发送数据寄存器)和RDR(接收数据寄存器)。
USART_BRR(波特率寄存器):设置USARTDIV值,生成所需的波特率。
USART_CR1(控制寄存器1):配置字长、校验控制、中断使能等。
USART_CR2(控制寄存器2):配置停止位长度等。
3.2 USART初始化配置
完整的USART初始化过程包括以下步骤:
void USART_InitConfig(void)
{
USART_InitTypeDef USART_InitStructure;
// 波特率设置
USART_InitStructure.USART_BaudRate = 115200;
// 字长设置:8位或9位
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 停止位设置
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 校验位设置
USART_InitStructure.USART_Parity = USART_Parity_No;
// 硬件流控制设置
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 工作模式设置
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// 应用配置
USART_Init(USART1, &USART_InitStructure);
// 使能USART
USART_Cmd(USART1, ENABLE);
}
提示:如果使用硬件流控制(RTS/CTS),需要额外配置相应的GPIO引脚为复用功能,并使能USART_CR3寄存器中的相应控制位。
4. 数据收发机制与实现方式
STM32串口数据收发支持三种方式:查询方式、中断方式和DMA方式,各有其适用场景。
4.1 查询方式
查询方式是最基础的通信方式,通过循环检测状态标志位来实现数据收发。
发送数据函数:
void USART_SendByte(uint8_t data)
{
// 等待发送数据寄存器为空
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
// 写入要发送的数据
USART_SendData(USART1, data);
// 等待发送完成
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
}
接收数据函数:
uint8_t USART_ReceiveByte(void)
{
// 等待接收到数据
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
// 读取接收到的数据
return USART_ReceiveData(USART1);
}
查询方式实现简单,但效率较低,在等待期间CPU无法执行其他任务。
4.2 中断方式
中断方式允许CPU在等待数据时执行其他任务,当数据传输完成时通过中断通知CPU。
中断配置:
// 使能接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 配置NVIC
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);
中断服务函数:
void USART1_IRQHandler(void)
{
uint8_t receivedData;
// 检查是否是接收中断
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
// 读取接收到的数据
receivedData = USART_ReceiveData(USART1);
// 处理数据...
// 清除中断标志
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
4.3 DMA方式
DMA(直接存储器访问)方式可以在不需要CPU干预的情况下实现数据搬运,大大提高了传输效率,特别适合大数据量传输。
DMA发送配置:
// 配置DMA通道
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)txBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = bufferSize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
// 使能USART的DMA发送
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
// 启动DMA传输
DMA_Cmd(DMA1_Channel4, ENABLE);
5. 高级应用与性能优化
在实际项目中,除了基本的收发功能外,还需要考虑一些高级应用场景和性能优化措施。
5.1 不定长数据接收
处理不定长数据是串口通信中的常见需求,STM32提供了多种解决方案:
空闲中断检测:利用串口空闲中断(IDLE)检测一帧数据的结束。当总线空闲时间超过一个数据帧传输时间时,会产生空闲中断。
// 使能空闲中断
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
// 在中断服务函数中处理空闲中断
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
{
// 处理接收完成的数据帧
// ...
// 清除空闲中断标志(通过读USART_SR和USART_DR)
uint32_t temp = USART1->SR;
temp = USART1->DR;
(void)temp;
}
}
超时检测:使用定时器设置超时时间,如果在规定时间内没有收到新数据,则认为一帧数据接收完成。
5.2 错误检测与处理
串口通信中可能出现的错误包括噪声错误、帧错误、溢出错误等。STM32的USART模块提供了多种错误检测机制:
- 奇偶校验错误:当接收到的数据与校验位不匹配时产生
- 帧错误:当检测到停止位为低电平时产生
- 噪声错误:当在接收过程中检测到噪声时产生
- 溢出错误:当接收数据寄存器尚未读取又收到新数据时产生
错误处理示例:
void USART1_IRQHandler(void)
{
// 检查溢出错误
if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) == SET)
{
// 处理溢出错误
// 清除错误标志:先读USART_SR,再读USART_DR
uint32_t temp = USART1->SR;
temp = USART1->DR;
(void)temp;
}
// 检查其他错误...
}
5.3 性能优化技巧
双缓冲机制:使用两个缓冲区交替进行数据传输和处理,提高吞吐量。
环形缓冲区:实现生产者-消费者模型,解耦数据接收和处理过程。
波特率自适应:在某些应用中,可以实现波特率自动检测和适配,提高系统兼容性。
DMA与中断结合:对于大数据量传输,使用DMA进行数据搬运,结合中断处理传输完成事件。
在实际项目中,我发现最实用的优化是结合DMA和空闲中断实现高效的不定长数据接收。这种方式既能减轻CPU负担,又能灵活处理各种长度的数据帧,特别适合与各种传感器和模块通信的场景。
更多推荐



所有评论(0)