过采样
过程是全自动的(硬件完成),但模式是可以配置的(软件选择)。
对于绝大多数应用场景,你甚至 完全不需要管它,直接使用默认配置即可。
1. 为什么要过采样?
因为 UART 是异步的(没有时钟线),接收方并不知道发送方发来的这一位数据是从哪一微秒准确开始的,也没法保证双方的时钟完全一致(可能有 1-2% 的误差)。
2. 寻找起始位:防抖动 (Start Bit Detection)
当接收引脚(RX)检测到一个 下降沿(电平从 1 变 0)时,硬件不会马上相信“数据来了”,它怀疑这可能是个静电干扰或尖峰噪声。
STM32 的处理逻辑(以 16x 采样为例):
检测到下降沿。
硬件开始计数。
它会去检查第 3、5、7 次采样点(检查前半段)。
判断规则: 如果这 3 次采样中,大部是 0(低电平),硬件才确认:“好,这是真的起始位,不是噪声,准备接收数据!”
- 如果这几次采样里发现还是高电平,硬件就会认为这是噪声,直接忽略,回到空闲状态
3. 读取数据:取中间值 (Data Sampling)
一旦确认了起始位(起始位只确认一次 3.5.7),硬件就要找 最稳定的地方读取数据。哪里最稳定?当然是 正中间。
两边(第1份和第16份)靠近电平跳变沿,信号可能还没升上去或者刚降下来,容易出错。
所以,硬件会锁定中间的 第 8、9、10 次采样点。
4. 少数服从多数:噪音检测 (Noise Detection)
即使选了中间的 8、9、10 三个点,硬件还是很谨慎。它会采用 “三票两胜” (Majority Vote) 的逻辑。
举个例子: 假设发送方发的是高电平(1),但因为线路干扰,中间出现了一个短暂的波动:
- 第 8 次采样:
1 - 第 9 次采样:
0(干扰!) - 第 10 次采样:
1
硬件的判决:
- 判定结果: 因为有两个 1,一个 0,所以 最终结果判定为 1。
- 副作用: 虽然读到了数据,但硬件发现这 3 个值不一致,它会悄悄把寄存器里的 NE (Noise Error) 标志位置 1。
- 这就告诉程序:“数据我帮你尽力还原了,但是刚才信号有点脏,你自己注意一下。”
txt
Tick: | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
动作: ^ ^ ^ ^ ^ ^
确认起始位 读取数据位
(避免假触发) (取中间值投票)这就是为什么串口在环境很差、波特率有点偏差的情况下,依然能稳定工作的原因——它不是看一眼就定生死,而是看了好几眼,还搞了个投票。