STM32 串口奇偶校验详解
一、奇偶校验的基本原理
奇偶校验是一种简单的检错机制,通过在每帧数据后附加一位校验位,使整个数据帧中“1”的个数满足预设规则:
- 偶校验:数据位 + 校验位中“1”的总数为偶数
- 奇校验:数据位 + 校验位中“1”的总数为奇数
例如:数据 00110101 中有4个“1”(偶数),若选择偶校验则校验位为0,若选择奇校验则校验位为1。
奇偶校验能够检测单比特错误,但不能纠正错误,也无法检测偶数个比特同时出错的情况。
二、STM32 奇偶校验的硬件实现
STM32的USART外设原生支持奇偶校验,整个过程由硬件自动完成,无需软件干预:
- 发送端:CPU写入8位数据后,硬件自动计算并附加校验位
- 接收端:硬件对接收到的数据自动验证,若失败则置位PE标志(Parity Error)
三、关键寄存器配置
3.1 USART_CR1 控制寄存器表格
| 位域 | 功能 | 说明 |
|---|---|---|
| PCE (bit 10) | 奇偶校验控制使能 | 1=启用,0=禁用 |
| PS (bit 9) | 校验类型选择 | 0=偶校验,1=奇校验 |
| M (bit 12) | 字长定义 | 启用校验时需配合M位设置 |
| PEIE (bit 8) | 校验错误中断使能 | 1=使能PE中断 |
3.2 帧格式配置
启用奇偶校验时,帧格式取决于M位(字长控制位):
表格
| M位 | PCE位 | 帧格式 | 说明 |
|---|---|---|---|
| 0 | 0 | SB + 8位数据 + STB | 标准8N1 |
| 0 | 1 | SB + 7位数据 + 校验位 + STB | 7位数据+校验 |
| 1 | 0 | SB + 9位数据 + STB | 9位数据无校验 |
| 1 | 1 | SB + 8位数据 + 校验位 + STB | 8位数据+校验 |
关键点:当需要传输8位数据并附加校验位时,必须将M位设为1(即9位字长模式),此时帧结构为“8位数据 + 1位校验位”。
四、HAL库配置方法
4.1 初始化结构体配置
UART_HandleTypeDef huart2;
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_9B; // 必须设为9位
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_EVEN; // 偶校验
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK) {
Error_Handler();
}
}
注意:启用奇偶校验后,WordLength 必须设为 UART_WORDLENGTH_9B,否则校验功能不会生效。
4.2 错误处理机制
方式一:中断模式
// 在中断服务函数中处理
void USART2_IRQHandler(void)
{
// 检查是否为奇偶错误
if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_PE) &&
__HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_PE)) {
__HAL_UART_CLEAR_PEFLAG(&huart2); // 清除标志
// 处理错误:丢弃数据、触发重传、记录日志等
HandleParityError();
}
else {
HAL_UART_IRQHandler(&huart2); // 正常处理
}
}
方式二:回调函数
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_PE)) {
__HAL_UART_CLEAR_PEFLAG(huart); // 清除标志
volatile uint16_t dummy = huart->Instance->RDR; // 读取RDR清除RXNE
// 记录错误、告警等
error_counter++;
}
}
重要:清除PE标志后,必须读取数据寄存器(RDR)来释放接收通道,否则后续接收会阻塞。
五、实际应用场景
5.1 工业传感器通信
在工业现场,电磁干扰容易导致数据位翻转。奇偶校验作为第一道防线,能在硬件层面快速拦截错误,避免错误数据进入应用层。
5.2 RS-485 双保险机制
对于Modbus RTU等协议,可在物理层叠加奇偶校验,形成双重防护:
- 第一道防线(硬件):USART检测奇偶错误 → 快速丢弃明显损坏的数据帧
- 第二道防线(软件):CRC校验 → 确保数据完整性
5.3 通信链路质量监测
通过统计PE错误频率,可以评估通信链路健康状况。例如连续1分钟内出现超过10次奇偶错误,可发出“通信环境恶化”预警。
六、常见问题与避坑指南
❌ 问题1:通信双方配置不一致
现象:一端启用奇校验,另一端使用偶校验,或一方开启校验另一方未开,导致持续报错。
解决:确保所有设备统一配置为相同的奇偶模式和数据位数。
❌ 问题2:字长配置错误
现象:启用校验后仍使用 USART_WordLength_8b,导致数据错乱。
原因:启用校验时必须使用9位字长模式(8位数据+1位校验),WordLength 参数指的是“帧中数据位和校验位的总位数”。
❌ 问题3:未清除PE标志
现象:一次校验错误后,后续所有接收都失败,串口“卡死”。
解决:在错误回调中调用 __HAL_UART_CLEAR_PEFLAG() 并读取RDR。
❌ 问题4:DMA + 奇偶校验组合问题
风险:DMA只管搬数据,不管PE标志。错误帧会被原样写入内存。
建议:在DMA传输完成回调中手动轮询检查PE标志,并丢弃对应缓冲区数据。
❌ 问题5:高波特率下更容易出错
原因:波特率越高,每位时间越短,受噪声影响越大。
建议:使用屏蔽双绞线、添加终端电阻(120Ω)、缩短走线长度。
七、总结
奇偶校验是STM32 USART硬件提供的低成本、高效率的检错机制,能够在物理层快速捕获单比特错误,显著提升串行通信的可靠性。虽然它不能检测双比特错误,也不具备纠错能力,但作为系统的第一道防线,与上层协议校验(如CRC)配合使用,能形成高效的双重保障机制。
更多推荐
所有评论(0)