STM32 CAN 总线通信:位定时配错为什么收不到帧?从波特率到采样点的工程排查
在 STM32 上调 CAN 总线,最常见的故障不是发不出去,而是收不到帧——示波器上波形明明在跳,接收中断就是不进。很多时候问题不在代码逻辑,而在位定时(Bit Timing)配错了。
一、CAN 位时间的四个段
一个 CAN 位时间由四个段组成:同步段(Sync_Seg,固定 1 个时间量子 TQ)、传播段(Prop_Seg)、相位缓冲段 1(Phase_Seg1)和相位缓冲段 2(Phase_Seg2)。采样点位于 Phase_Seg1 结束处,计算公式为:
采样点 = (1 + Prop_Seg + Phase_Seg1) / (1 + Prop_Seg + Phase_Seg1 + Phase_Seg2)
波特率则由分频系数和每位 TQ 总数决定:
波特率 = CAN 时钟 / (BRP × 每位 TQ 总数)
两个节点只要波特率名义上相同还不够,采样点位置也必须接近,否则一方在边沿附近采样,遇到线缆延迟和晶振偏差就会误判。
二、为什么 125k 能通、500k 不通
低速时 Prop_Seg 的容差大,线缆延迟和收发器延时占位时间的比例小,配得粗糙也能工作;速率一高,同样几十纳秒的延迟就占掉可观的位时间,采样点稍偏就读错位。排查时先把两端都设成常见的 87.5% 采样点(例如每位 8 TQ:Sync 1 + Prop 1 + Seg1 5 + Seg2 1),再实测。
三、三个最容易踩的坑
第一,时钟源算错。CAN 时钟取自 APB1,开启超频或改过系统时钟后忘记重算 BRP,名义波特率与实际差几千赫兹,短帧偶尔能过、长帧必错。
第二,收发器使能脚没拉。很多 CAN 收发器有 STB/EN 引脚,悬空默认待机,表现为总线静默,CAN 控制器本身报不出错。
第三,滤波器把帧挡在外面。STM32 的 CAN 滤波器默认不放行任何帧,必须配置至少一组掩码模式、放行目标 ID,否则接收 FIFO 永远是空的。调试阶段先把滤波器设为全通,确认链路没问题后再收紧。
四、排查顺序
先用示波器确认 TX 引脚有波形且显性/隐性电平正常;再查两端波特率实测值是否一致;然后对齐采样点到 87.5% 附近;最后检查滤波器与终端电阻(总线两端各 120Ω,缺一个都可能在高速率下出现反射误码)。
位定时是 CAN 通信的地基,地基配错,协议栈写得再漂亮也收不到一帧数据。
- 点赞
- 收藏
- 关注作者
评论(0)