1. CAN协议基础回顾:从帧结构到CMS32外设特性

各位同学,咱们今天正式开讲。CAN协议这东西,说实话,搞嵌入式的人迟早都得碰。我最早接触CAN是在做汽车BCM项目的时候,那时候被总线上的波形折腾得够呛。后来慢慢摸透了它的脾气,才发现CAN的设计其实非常巧妙。

这一节,咱们先打好地基。把CAN 2.0A/B的帧结构、仲裁机制、位填充和CRC校验这些核心概念过一遍,最后再看看CMS32的CAN模块长什么样。

1.1 CAN 2.0A/B帧结构:标准帧与扩展帧

CAN总线上的报文,说白了就是一串电平跳变。但这一串跳变里,藏着严格的分段结构。CAN 2.0A定义的是标准帧,11位标识符;CAN 2.0B扩展帧,29位标识符。两者在总线上是完全兼容的,但帧格式有区别。

我习惯把CAN帧分成这么几段:

  • SOF(Start of Frame):1个显性位,告诉总线上所有节点“我要发数据了”。
  • 仲裁场:标准帧11位ID + RTR位;扩展帧29位ID + SRR + IDE + RTR。这里藏着总线仲裁的秘密。
  • 控制场:IDE位、保留位、DLC(数据长度码,4位)。DLC告诉接收方后面跟了多少字节数据。
  • 数据场:0~8字节。嗯,CAN一次最多传8个字节,这是硬限制。做大数据包拆分的时候要记住这个。
  • CRC场:15位CRC + 1位CRC界定符。校验整个帧的完整性。
  • ACK场:发送方释放总线,接收方在ACK Slot位拉低电平,表示“我收到了”。
  • EOF:7个隐性位,帧结束。

下面这张图,把标准帧和扩展帧的结构画清楚了:

CAN 2.0A/B 帧结构对比 标准帧 (CAN 2.0A) SOF 11位ID + RTR 控制场 数据场 (0~8B) CRC场 ACK EOF 扩展帧 (CAN 2.0B) SOF 11位ID SRR IDE 18位扩展ID RTR 控制场 数据场 (0~8B) CRC场 ACK EOF 关键区别: • 标准帧:11位ID,帧长度最短,适合简单节点通信。 • 扩展帧:29位ID,兼容标准帧,但总线利用率略低(多出18位ID + SRR + IDE)。 • 项目中混用时,注意ID掩码配置,否则容易收不到报文。
个人经验:我刚开始做CAN开发时,总以为扩展帧比标准帧“高级”。其实不是。如果你的系统节点少于20个,标准帧完全够用,而且总线负载更低。扩展帧的优势在于大型网络(比如整车CAN),需要更多ID来区分节点和功能。

1.2 仲裁机制:谁先说话,谁赢

CAN总线是CSMA/CA架构。多个节点同时发送时,不会冲突,而是通过ID逐位仲裁。谁ID小,谁优先级高。

具体怎么仲裁的?我举个例子:

  • 节点A发ID = 0x123(二进制:0001 0010 0011)
  • 节点B发ID = 0x456(二进制:0100 0101 0110)

从最高位开始比。第1位,A发0(显性),B发0(显性),总线保持显性,两者继续。第2位,A发0(显性),B发1(隐性),总线被A拉成显性。B检测到总线电平与自己发送的不一致,立刻退出竞争。A胜出,继续发送剩余帧。

整个过程发生在仲裁场,不丢数据,不浪费带宽。这就是CAN的优雅之处。

避坑指南:我曾经在一个项目中,把两个节点的ID设成了0x001和0x002。结果0x001的节点一直抢不到总线,因为它的ID比0x002大?不对,0x001比0x002小,优先级更高。但问题出在:0x001的节点发送频率太高,导致0x002几乎发不出去。后来我加了发送间隔控制和优先级分组,才解决。记住:ID越小优先级越高,但也要考虑公平性。

1.3 位填充与CRC校验:保证数据不出错

CAN总线是差分信号,抗干扰能力很强。但再强的物理层,也怕连续相同的电平。为什么?因为接收节点靠电平跳变来同步时钟。如果连续5个相同位,接收方可能丢失同步。

位填充规则很简单:发送方在连续发送5个相同位后,自动插入一个相反位。接收方检测到5个相同位后,自动丢弃第6位(填充位)。这样保证了总线上的电平跳变密度。

CRC校验呢?CAN用的是15位CRC,生成多项式是:

CRC生成多项式:x¹⁵ + x¹⁴ + x¹⁰ + x⁸ + x⁷ + x⁴ + x³ + 1

这个多项式覆盖了SOF、仲裁场、控制场、数据场。接收方重新计算CRC,与发送方附带的CRC值比对。不一致就发错误帧。

关键点:位填充和CRC是CAN可靠性的两大支柱。位填充保证时钟同步,CRC保证数据完整性。两者缺一不可。

1.4 CMS32 CAN模块外设特性概览

好了,理论讲完,咱们看看CMS32的CAN外设长什么样。CMS32的CAN模块,我总结下来有这几个特点:

特性 说明 我的评价
协议支持 CAN 2.0A/B,标准帧和扩展帧 主流配置,够用
邮箱数量 最多32个消息邮箱 比很多MCU多,适合多节点场景
位速率 最高1 Mbps 常规CAN的上限
过滤方式 ID掩码过滤,支持单个/双滤波 灵活,但配置稍复杂
中断支持 发送完成、接收完成、错误中断 齐全,低功耗设计必备
低功耗模式 支持CAN唤醒,总线活动检测 这个后面章节会重点讲

我个人觉得,CMS32的CAN模块最值得关注的是它的邮箱管理和低功耗唤醒机制。邮箱多,意味着你可以同时缓存多个不同ID的报文,不用频繁中断CPU。低功耗唤醒,则是做电池供电设备的关键。

下面这张图,展示了CMS32 CAN模块的内部结构:

CMS32 CAN模块内部结构 CAN核心控制器 消息邮箱 0 ~ 31 ID过滤 / 掩码 中断控制 / 唤醒 CAN收发器 CMS32 CAN模块工作流程: 1. 收发器接收总线差分信号,转换为数字电平。 2. 核心控制器解析帧结构,ID过滤单元判断是否接收。 3. 匹配的报文存入消息邮箱,触发中断或唤醒CPU。
使用建议:配置CMS32的CAN模块时,我建议先把邮箱分组。比如邮箱0~7给高优先级报文,邮箱8~15给低优先级。这样中断处理时,可以快速响应关键数据。另外,低功耗模式下,记得使能CAN唤醒中断,否则总线有活动时MCU醒不过来。