HC32F4A0 USART 波特率公式(官方 AN)
HC32F4A0 和 F460 USART 模块完全一致,USART 时钟源 = PCLK1,先经过 PR 寄存器分频 C,
再进入波特率生成器
FBME=1:小数分频使能(推荐打开,减小误差);
FBME=0:小数部分固定 0
Baud = (C *(128 + DIV_Fraction))/(8*(2-OVER8) * (DIV_Integer + 1) *256)
变量说明
C:USART 输入时钟(PR 分频后,单位 Hz,不是 MHz!很多笔记这里踩坑)
PR.PSC 分频:1 / 4 / 16 / 64 / 128 / 256 / 512 / 1024
C = f_PCLK1/ PR_div
OVER8:过采样
OVER8=0 → 16 倍过采样(默认,抗干扰好),
(2-OVER8 = 2)
OVER8=1 → 8 倍过采样,(2-OVER8 = 1)
DIV_Integer:整数分频,8bit,范围 0~0xFF
DIV_Fraction:小数分频,7bit,范围 0~0x7F;FBME=1 才生效
变形:求 DIV_Integer + DIV_Fraction
C/(Baud*8*(2-OVER8))=( (DIV_Integer+1) + DIV_Fraction/128) 这个式子最适合代码里计算!
两种常用场景简化
① OVER8=0(16 倍采样,最常用)
Baud = C *(128+DIV_Fraction)/(16 * (DIV_Integer+1) * 256)
C/(Baud * 16) = ((DIV_Integer+1) + DIV_Fraction/128))
② OVER8=1(8 倍采样)
Baud = C * (128+DIV_Fraction)/(8 *(DIV_Integer+1) * 256)
C/(Baud *8) = ((DIV_Integer+1) + (DIV_Fraction/128))
计算步骤(DD 库内部逻辑)
拿到 fPCLK1(比如系统 240M,PCLK1=120MHz)
设置 PR 分频,算出 C = fPCLK1 / PR_div)
计算 temp = C / (Baud × 8 × (2-OVER8)
DIV_Integer = (uint8_t)temp - 1
frac = temp - (DIV_Integer + 1)
DIV_Fraction = (uint8_t)(frac * 128 + 0.5)四舍五入
检查边界:DIV_Integer ≤ 0xFF;DIV_Fraction ≤ 0x7F
写入 BRR 寄存器,必须 TE=0、RE=0 时修改 BRR,发送接收开启后不能改
举例
PCLK1=120MHz,PR 不分频 (div=1),OVER8=0(16 倍),目标 115200
(temp = 120000000/(115200 * 16) = 65.1041667)
DIV_Integer = 65 - 1 = 64
frac = 0.1041667
DIV_Fraction = 0.1041667 × 128 ≈ 13 → 0x0D
实际波特率:
(Baud = 120000000*(128+13)/(16*(64+1)*256} = 115144.5) 误差:-0.048%,非常优秀
重要坑点
不是 STM32 公式! STM32 小数是 4bit,HC32F4A0 是 7bit (1/128 步进),分辨率更高
DIV_Integer 最大 0xFF,太低波特率会溢出,此时加大 PR 分频(÷16/÷64)
FBME=0 时,DIV_Fraction 强制 = 0,误差会变大
时钟源是 PCLK1,不是 PCLK2;USART1~10 都挂 PCLK1
工业串口建议误差 < 2%,RS485 建议 <1%
误差公式
(Error(%)=(C*(128+DIV_Fraction)/(8*(2-OVER8)*(DIV_Integer+1)*256*Baud_target)- 1 * 100%)
5