一、奇偶校验的基本原理

奇偶校验是一种简单的检错机制,通过在每帧数据后附加一位校验位,使整个数据帧中“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)配合使用,能形成高效的双重保障机制。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐