前言
笔者在调试一款新的mcu的can通信时候,最麻烦的是波特率设置。由于没有弄明白其计算原理,经常出错,且不同的波特率有不同的采样点的要求。浪费了不少时间。这次一次搞明白can波特率的计算公式。
can波特率计算
在ISO 11898-1-2015 标准中有对can波特了的描述
其中nominal bit rate 即为波特率。nominal bit time 由Sync_seg,Prop_seg,Phase_seg2,Phase_seg2这四部分组成。
其中 Sync_Seg为1个tq 其他都是n个tq,则
假设Prop_seg = prop_segtq;
phase_seg1= seg1tq
phase_seg2= seg2*tq
BAUD = 1/(tq(1+pro_seg+seg1+seg2))
seg配置:在标准中推荐了seg配置范围
tq为时间片,即为can通信的时钟周期。
接下来看下stm32 和hc32can内部结构
stm32 can
在stm32中,可以看到其BS1实际上是Prop_seg+phase_seg1。
经过转换,其波特率为
baudRate = fpclk/(BRP+1)/(1+ tbs1+1 + tbs2+1)
其在can初始化配置的结构体定义如下:
其中 TimeSeg1 = tbs1+1
TimeSeg2 = tbs2+1
Prescaler = BRP+1
从而得出:
baudRate = fpclk/Prescaler/(1+ TimeSeg1 + TimeSeg2 )其中在stm32f407中fpclk=APB1=42M
采样点 sample_point = (TimeSeg1)/(1+ TimeSeg1 + TimeSeg2 )
目前采样点暂时没有找到官方的要求,一般是如下要求
75% when BaudRate > 800K
80% when BaudRate > 500K
87.5% when BaudRate <= 500K
比如波特率500k ,尽量将采样点设置为80%。
hc32 can
笔者使用的是hc32f4a0
在其数据手册中可以看到,其将sync_seg也融合到了Seg1了。
其波特率计算公式为:
在其初始结构体中定义如下:
HC推荐can控制器的时钟设置为40M
最终的计算公式为:
baudrate = CANclock /u32Prescaler/(u32TimeSeg1+u32TimeSeg2)
samplepoint = u32TimeSeg1/(u32TimeSeg1+u32TimeSeg2)
数据手册中还推荐了其他配置规则
u32TimeSeg1 >=u32TimeSeg2+1
u32TimeSeg2 >=u32SJW
实际上由于hc32支持fanfd 。所以u32TimeSeg2 u32TimeSeg1 可以大于8。stm32f4不支持canfd,所以其配置要小于8