波特率计算公式中的 ×16 与 UART 通信的底层采样机制密切相关。以下是详细解释:
一、核心原因:过采样(Oversampling)
UART 接收端需要通过 过采样 来准确检测起始位和数据位。在异步串行通信中,发送端和接收端的时钟可能存在微小偏差,过采样技术可以提高抗噪声能力和同步精度。具体来说:
- 标准做法:接收端以 16 倍波特率 的频率对信号进行采样。
- 目的:在每个比特位的持续时间内多次采样,确保在信号中间位置(最稳定点)读取数据。
二、公式推导过程
以 STC 单片机(1T 模式)为例,波特率计算公式为:
[
\text{波特率} = \frac{\text{Fosc}}{16 \times (65536 - \text{T2H:T2L})}
]
其中:
- Fosc:系统主频(如 12MHz)。
- T2H:T2L:定时器 2 的 16 位初值。
关键步骤解析:
- 定时器溢出频率: [ \text{定时器溢出频率} = \frac{\text{Fosc}}{(65536 - \text{T2H:T2L})} ] 定时器每计数 (65536 - 初值) 次溢出一次。
- 波特率与定时器溢出频率的关系: 定时器溢出频率需要经过 16 分频 后得到实际波特率。 这是因为接收端需要 16 次采样/比特,因此波特率计算公式中需 除以 16: [ \text{波特率} = \frac{\text{定时器溢出频率}}{16} ]
三、实际应用示例
假设使用 12MHz 晶振,目标波特率为 4800bps:
- 计算定时器初值: [ \text{初值} = 65536 - \frac{\text{Fosc}}{16 \times \text{波特率}} = 65536 - \frac{12,000,000}{16 \times 4800} = 65379.75 \approx 65380 ] 十六进制表示为 0xFF64,即 T2H = 0xFF,T2L = 0x64。
- 验证波特率: [ \text{实际波特率} = \frac{12,000,000}{16 \times (65536 - 65380)} = \frac{12,000,000}{16 \times 156} = 4807.69 , \text{bps} ] 误差为 0.16%,在可接受范围内。
四、为什么要用 16 倍采样?
- 起始位检测: 接收端持续检测 RX 引脚的电平,当发现 下降沿(起始位开始)时,会等待 8 个采样周期(即半个比特时间)后,再次采样确认起始位。 若此时仍为低电平,则确认起始位有效。
- 数据位采样: 每个数据位在 第 7、8、9 次采样(中间位置)时读取,取多数值(如 2/3 表决)以提高抗干扰能力。
- 容错机制: 16 倍过采样允许发送端和接收端时钟存在一定偏差(通常容忍 ±5% 误差)。
五、对比其他过采样方案
过采样倍数 | 应用场景 | 优缺点 |
---|
×16 | 标准 UART 通信 | 可靠性高,资源占用适中 |
×8 | 高速通信 | 抗噪能力略低 |
×32 | 高噪声环境或低波特率通信 | 延迟增加,资源消耗大 |
六、常见问题解答
1. 如果不用 16 倍采样会怎样?
- 误码率上升:无法可靠检测起始位和中间数据位,尤其在时钟偏差或噪声环境下。
- 协议失效:可能导致帧错误、数据错位。
2. 如何修改过采样倍数?
- 硬件支持:某些现代单片机(如 STM32)可配置过采样倍数(如 ×8 或 ×16)。
- 传统 8051:固定为 ×16,不可修改。
3. 公式中的 16 可以省略吗?
- 不能:这是 UART 协议的标准要求,省略会导致波特率错误。
七、总结
- ×16 的来源:UART 接收端需要 16 倍过采样以确保数据可靠性。
- 公式意义:波特率 = 定时器溢出频率 / 16。
- 配置关键:正确计算定时器初值,使溢出频率为目标波特率的 16 倍。
通过这种方式,串口通信能够在异步环境下实现高精度的数据传输,平衡速度和可靠性。