• 正文
  • 相关推荐
申请入驻 产业图谱

HC32F4A0 串口波特率计算

22小时前
5
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

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%)

 

相关推荐