3、CAN通信基础:从物理层到错误处理
各位同学,今天我们来聊聊CAN通信。说实话,CAN总线在汽车圈里摸爬滚打这么多年,早就成了车载通信的“老大哥”。我入行那会儿,第一个项目就是调试CAN报文,当时被一个隐性位搞到凌晨三点——嗯,这个坑后面我会讲。
3.1 CAN总线物理层:信号怎么在线上跑?
CAN总线物理层,说白了就是两根线:CAN_H和CAN_L。它用差分信号传输,抗干扰能力很强。你想想看,发动机舱里电磁环境那么恶劣,普通串口早就废了,但CAN还能稳如老狗。
物理层有几个关键参数:
- 总线电平:显性(Dominant)对应逻辑0,隐性(Recessive)对应逻辑1。显性时CAN_H≈3.5V,CAN_L≈1.5V;隐性时两者都≈2.5V。
- 传输速率:常见的有125kbps、250kbps、500kbps、1Mbps。速率越高,总线长度越短。
- 终端电阻:总线两端各接120Ω电阻,用来消除信号反射。
重要提醒:CAN总线是“线与”逻辑。多个节点同时发送显性位时,总线呈现显性状态。这个特性是仲裁机制的基础。
我在项目中遇到过一个问题:某次台架测试,CAN通信时断时续。查了半天,发现终端电阻焊错了,用了100Ω。换回120Ω后,一切正常。所以啊,硬件细节真不能马虎。
3.2 CAN数据链路层:帧是怎么组织的?
数据链路层负责把数据打包成帧。CAN有两种帧格式:标准帧(11位ID)和扩展帧(29位ID)。
先看标准帧的结构:
SOF | 11位ID | RTR | IDE | r0 | DLC | 数据段(0-8字节) | CRC | ACK | EOF
扩展帧呢,就是把ID扩展到29位:
SOF | 11位ID | SRR | IDE | 18位扩展ID | RTR | r1 | r0 | DLC | 数据段 | CRC | ACK | EOF
这里有几个关键位,我解释一下:
- SOF(Start of Frame):帧起始,一个显性位。
- ID:标识符,决定优先级。数值越小,优先级越高。
- RTR(Remote Transmission Request):远程帧标志。0是数据帧,1是远程帧。
- IDE(Identifier Extension):0表示标准帧,1表示扩展帧。
- DLC(Data Length Code):数据长度,0-8字节。
- CRC:循环冗余校验,15位。
- ACK:应答位,接收节点发送显性位确认。
个人经验:我建议你在设计CAN节点时,优先使用标准帧。扩展帧虽然ID空间大,但仲裁效率略低。除非ID不够用,否则别折腾。
3.3 CAN总线仲裁机制:谁先说话?
CAN总线是多主总线,多个节点可以同时发送。那冲突了怎么办?靠仲裁。
仲裁的原理很简单:ID越小,优先级越高。发送时,每个节点逐位比较ID。如果某个节点发送隐性位(1),但总线上是显性位(0),说明有更高优先级的节点在发送,它就自动退出发送。
举个例子:
节点A ID = 0x100(二进制:001 0000 0000)
节点B ID = 0x200(二进制:010 0000 0000)
第1位:A发0,B发0 → 总线0,继续
第2位:A发0,B发1 → 总线0(显性),B检测到冲突,退出
A继续发送,B转为接收
为什么会这样?因为显性位(0)会覆盖隐性位(1)。所以ID小的节点,高位0更多,自然占优势。
避坑指南:我曾经在一个项目中,把两个ECU的ID设成了0x100和0x101。结果0x101的节点几乎发不出数据,因为0x100优先级太高。后来我把0x101改成了0x200,问题解决。记住:ID分配要留足间隔,别挤在一起。
3.4 CAN错误处理机制:出错了怎么办?
CAN的错误处理机制,我觉得是它最牛的地方之一。它不依赖上层协议,硬件自己就能搞定。
错误类型有5种:
| 错误类型 | 说明 | 检测位置 |
|---|---|---|
| 位错误(Bit Error) | 发送节点监控总线,发现发送的位与总线状态不一致 | 发送节点 |
| 填充错误(Stuff Error) | 连续5个相同位后,未检测到填充位 | 所有节点 |
| CRC错误 | 接收节点计算的CRC与发送的不一致 | 接收节点 |
| 格式错误(Form Error) | 帧格式不符合规范(如EOF位不是隐性) | 所有节点 |
| 应答错误(ACK Error) | 发送节点未收到ACK显性位 | 发送节点 |
错误处理流程是这样的:
- 节点检测到错误,立即发送错误帧(6个显性位)。
- 其他节点收到错误帧,丢弃当前报文。
- 发送节点根据错误计数器决定是否重发。
每个节点有两个错误计数器:
- TEC(Transmit Error Counter):发送错误计数。
- REC(Receive Error Counter):接收错误计数。
节点状态根据计数器值变化:
- 错误主动(Error Active):TEC<127且REC<127。正常发送,检测到错误时发送主动错误帧。
- 错误被动(Error Passive):TEC>127或REC>127。发送被动错误帧,且发送间隔延长。
- 总线关闭(Bus Off):TEC>255。节点完全断开总线,不再参与通信。
关键点:总线关闭状态需要上层协议介入恢复。我建议你在AUTOSAR的Can模块中配置自动恢复机制,别让节点永久离线。
我记得有一次,客户反馈某ECU在高温测试中频繁丢帧。查日志发现REC飙升到200多,节点进入了错误被动状态。原因是CAN收发器在高温下性能下降,导致位采样出错。后来换了宽温范围的收发器,问题解决。所以啊,硬件选型一定要考虑环境边界。
3.5 本章知识体系
下面这张图,是我自己画的CAN通信基础结构图。你看一眼,就能把物理层、数据链路层、仲裁和错误处理串起来。
这张图把本章的核心内容都串起来了。物理层是基础,数据链路层是框架,仲裁机制保证多节点有序通信,错误处理确保可靠性。四者缺一不可。
我的建议:学CAN通信,别只盯着协议看。找个CAN分析仪,抓几帧实际报文看看,比读十遍书都管用。我当年就是这么入门的。
公众号:蓝海资料掘金营,微信deep3321