🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习
🎬擅长领域:驱动开发,嵌入式软件开发,BSP开发
❄️作者主页:一个平凡而乐于分享的小比特的个人主页
✨收录专栏:通信协议,本专栏为记录项目中用到的知识点,以及一些硬件常识总结
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖
CAN通信协议详解:工业通信的"神经系统"
一、CAN协议核心思想图解

二、CAN协议诞生背景
汽车电子的革命
1980年代汽车电子问题:
┌─────────────────────────────────────────┐
│传统布线方式: │
│ 每个传感器→独立线束→ECU │
│ 问题:线束重量↑、成本↑、可靠性↓ │
│ │
│宝马7系(1986年): │
│ 线束总长度:4公里 │
│ 线束重量:100公斤 │
│ 连接器数量:2000个 │
└─────────────────────────────────────────┘
解决方案:CAN总线
┌─────────────────────────────────────────┐
│CAN总线方式: │
│ 所有设备→共享双绞线→所有ECU │
│ 优势:线束重量↓80%、成本↓、可靠性↑ │
│ │
│现代汽车典型: │
│ 线束总长度:1.5公里 │
│ 线束重量:20公斤 │
│ 连接器数量:500个 │
└─────────────────────────────────────────┘
三、CAN协议基础架构
1. 物理层连接
CAN总线典型拓扑结构:
┌─────────────┐
│ 120Ω │
│终端电阻 │
└─────┬───────┘
│
┌──────────┴──────────┐
│ 双绞线(CAN_H/CAN_L) │
└──────────┬──────────┘
┌──────┼──────┐
┌───┴──┐ ┌─┴──┐ ┌─┴──┐
│ECU1 │ │ECU2│ │ECU3│
│CAN │ │CAN │ │CAN │
└──────┘ └────┘ └────┘
CAN信号电平(差分):
隐性(逻辑1):CAN_H ≈ CAN_L ≈ 2.5V → 电压差≈0V
显性(逻辑0):CAN_H ≈ 3.5V, CAN_L ≈ 1.5V → 电压差≈2V
优势:抗干扰强,噪声同时影响两根线,差分抵消
2. 帧结构详解
标准CAN帧(11位标识符)结构:
┌───┬───┬───┬─────┬───┬──────┬──────┬───┬───┬───┐
│SOF│标识符│RTR│IDE │DLC│ 数据场 │ CRC │ACK│EOF│IFS│
├───┼───┼───┼─────┼───┼──────┼──────┼───┼───┼───┤
│1 │11 │1 │1(r0)│4 │0-8字节│15 │2 │7 │3 │
└───┴───┴───┴─────┴───┴──────┴──────┴───┴───┴───┘
单位:bit
扩展CAN帧(29位标识符)结构:
┌───┬───┬───┬─────┬───┬───┬─────┬───┬──────┬──────┬───┬───┬───┐
│SOF│标识符│SRR│IDE │标识符│RTR│DLC │ 数据场 │ CRC │ACK│EOF│IFS│
│ │11位 │ │1=1 │18位 │ │ │0-8字节│ │ │ │ │
├───┼───┼───┼─────┼───┼───┼─────┼───┼──────┼──────┼───┼───┼───┤
│1 │11 │1 │1 │18 │1 │4 │0-64│15 │2 │7 │3 │ │
└───┴───┴───┴─────┴───┴───┴─────┴───┴──────┴──────┴───┴───┴───┘
各字段说明:
SOF(Start of Frame): 帧起始,同步用
标识符(ID): 消息优先级,值越小优先级越高
RTR(Remote Transmission Request): 远程帧请求
IDE(Identifier Extension): 标识符扩展位
DLC(Data Length Code): 数据长度码(0-8字节)
数据场(Data Field): 实际传输数据
CRC(Cyclic Redundancy Check): 循环冗余校验
ACK(Acknowledge): 应答场
EOF(End of Frame): 帧结束
IFS(Inter Frame Space): 帧间间隔
四、CAN协议核心设计思想
1. 非破坏性仲裁机制(CAN的灵魂)
仲裁过程示例:
节点A发送ID=0x123 (二进制:0001 0010 0011)
节点B发送ID=0x456 (二进制:0100 0101 0110)
节点C发送ID=0x789 (二进制:0111 1000 1001)
仲裁过程:
第1位:A=0(显性), B=0(显性), C=0(显性) → 总线=0,都继续
第2位:A=0(显性), B=1(隐性), C=1(隐性) → 总线=0,B和C检测到冲突
第3位:A=0(显性) → A赢得仲裁
结果:
A继续发送完整消息,B和C转为接收模式
A发送完成后,B和C重新尝试发送
▲ 关键:显性位(0)覆盖隐性位(1)
▲ 优势:无数据丢失,优先级高的消息总能先发送
2. 基于消息的通信(而非基于地址)
传统地址寻址 vs CAN消息标识:
传统方式(如I2C):
主设备:给从设备3(地址0x03)发送数据
┌─0x03─→ 从设备1?否
├─0x03─→ 从设备2?否
└─0x03─→ 从设备3?是 → 接收数据
CAN方式:
所有节点发送和接收"车速消息"(ID=0x100)
节点A(发动机):发布车速=80km/h
所有节点同时接收并过滤:
节点B(仪表盘):我需要ID=0x100 → 显示80km/h
节点C(ABS):我需要ID=0x100 → 用于计算
节点D(车窗):我不需要ID=0x100 → 忽略
优势:新设备加入无需重新配置地址
3. 强大的错误处理机制
CAN的错误检测层次:
┌─────────────────────────────────────┐
│ 第五层:错误恢复 │
│ 自动恢复或节点脱离总线 │
├─────────────────────────────────────┤
│ 第四层:错误计数与状态管理 │
│ 错误计数器:TEC/REC │
│ 三种状态:主动错误/被动错误/离线 │
├─────────────────────────────────────┤
│ 第三层:错误帧发送 │
│ 主动错误标志(6个显性位) │
│ 被动错误标志(6个隐性位) │
├─────────────────────────────────────┤
│ 第二层:错误检测 │
│ 1. 位错误 │ 发送≠接收 │
│ 2. 填充错误 │ 5个相同位后无填充│
│ 3. CRC错误 │ 校验和错误 │
│ 4. 格式错误 │ 固定格式位错误 │
│ 5. ACK错误 │ 无应答 │
├─────────────────────────────────────┤
│ 第一层:物理层错误 │
│ 总线断开、短路等 │
└─────────────────────────────────────┘
错误状态机:
┌─────────┐ TEC/REC<127 ┌─────────┐
│主动错误 │◄────────────┤被动错误 │
│状态 │ TEC>127 │状态 │
└────┬────┘ └────┬────┘
│ TEC>255 │ TEC>255且持续
↓ ↓
┌─────────┐ ┌─────────┐
│离线状态 │ │离线状态 │
│(Bus Off)│◄─────────────┤ │
└─────────┘ 恢复过程 └─────────┘
五、CAN协议详细对比
CAN协议版本对比
| 特性 | CAN 2.0A | CAN 2.0B | CAN FD | CAN XL |
|---|---|---|---|---|
| 标准 | 1991 | 1995 | 2012 | 2021 |
| ID长度 | 11位 | 11/29位 | 11/29位 | 11/29位 |
| 最大速率 | 1 Mbps | 1 Mbps | 8 Mbps | 10+ Mbps |
| 数据长度 | 0-8字节 | 0-8字节 | 0-64字节 | 0-2048字节 |
| 主要改进 | 基础标准 | 扩展帧 | 可变速率+大数据 | 超大数据+高速 |
| 兼容性 | 兼容B | 兼容A | 兼容2.0 | 兼容FD |
| 典型应用 | 简单控制 | 汽车网络 | 汽车诊断 | 未来汽车 |
六、CAN协议性能参数
传输速率与距离关系
CAN总线波特率 vs 最大距离(双绞线):
1 Mbps → █████ 40米
500 Kbps → █████████ 100米
250 Kbps → ██████████████ 250米
125 Kbps → ███████████████████ 500米
50 Kbps → █████████████████████████ 1000米
20 Kbps → ███████████████████████████████ 5000米
关键公式:总线长度 ∝ 1/波特率
消息延迟分析
典型1Mbps CAN网络延迟计算:
┌─────────────────────────────────────┐
│ 最坏情况延迟时间 │
│ │
│ 1. 仲裁等待: │
│ 最低优先级消息等待所有高优先级 │
│ 假设有N个更高优先级消息 │
│ 等待时间 = N × 消息传输时间 │
│ │
│ 2. 消息传输时间: │
│ 标准帧(8字节数据): │
│ - 帧头:47位 │
│ - 数据:64位 │
│ - CRC+ACK+EOF:24位 │
│ - 位填充:约18位(10%) │
│ 总计:~153位 │
│ 时间:153μs @ 1Mbps │
│ │
│ 3. 总线负载影响: │
│ 30%负载:平均延迟增加50% │
│ 70%负载:平均延迟增加300% │
└─────────────────────────────────────┘
七、实际应用场景
场景1:汽车动力总成系统
CAN在汽车发动机控制的应用:
┌─────────────────────────────────────┐
│ 发动机控制单元(ECU) │
│ 发布:ID=0x100 发动机转速=3000rpm │
│ ID=0x101 水温=90℃ │
│ ID=0x102 油门位置=60% │
├─────────────────────────────────────┤
│ 变速箱控制单元(TCU) │
│ 发布:ID=0x200 当前档位=3 │
│ 接收:发动机转速→计算换挡时机 │
├─────────────────────────────────────┤
│ 仪表盘 │
│ 接收:转速→显示转速表 │
│ 水温→显示水温警告 │
├─────────────────────────────────────┤
│ ABS系统 │
│ 接收:发动机转速→防抱死计算 │
└─────────────────────────────────────┘
消息优先级安排(ID值越小优先级越高):
0x010: 刹车信号(最高优先级)
0x100: 发动机转速
0x101: 水温
0x200: 档位信息
0x300: 车门状态(最低优先级)
场景2:工业生产线控制
CANopen在工业机械臂控制:
┌─────────────────────────────────────┐
│ 主控制器(PLC) │
│ 发送:PDO1: ID=0x201 目标位置 │
│ PDO2: ID=0x202 运动速度 │
│ 接收:PDO3: ID=0x301 当前位置 │
│ PDO4: ID=0x302 报警状态 │
├─────────────────────────────────────┤
│ 伺服驱动器1 │
│ 接收:目标位置→控制电机 │
│ 发布:当前位置→反馈给PLC │
├─────────────────────────────────────┤
│ 伺服驱动器2 │
│ 接收:目标位置→控制电机 │
│ 发布:当前位置→反馈给PLC │
├─────────────────────────────────────┤
│ I/O模块 │
│ 发布:ID=0x401 限位开关状态 │
│ ID=0x402 紧急停止状态 │
└─────────────────────────────────────┘
CANopen对象字典示例:
索引0x2000: 位置控制参数
索引0x2001: 速度控制参数
索引0x6000: 接收PDO1映射
索引0x6001: 发送PDO1映射
八、CAN高层协议对比
| 协议 | CANopen | DeviceNet | J1939 | CANaerospace |
|---|---|---|---|---|
| 起源 | 欧洲,CIA | 美国,ODVA | 美国,SAE | 航空电子 |
| 应用领域 | 工业自动化 | 工业设备 | 商用车 | 航空航天 |
| 网络管理 | NMT | 显式消息 | 无 | 专用NM |
| 对象模型 | 对象字典 | 对象模型 | 参数组 | 消息目录 |
| 寻址方式 | 节点ID | 节点ID | 名称+地址 | 节点ID |
| 最大数据 | 8字节 | 8字节 | 8字节 | 8字节 |
| 典型应用 | 电机控制 | 传感器网络 | 卡车控制 | 飞机系统 |
| 优势 | 灵活强大 | 简单易用 | 车辆专用 | 高可靠 |
九、CAN系统设计要点
1. 物理层设计要点
正确的CAN网络布线:
正确做法 错误做法
┌──────────────┐ ┌──────────────┐
│ 终端电阻120Ω │ │ 无终端电阻 │
│ 在两端 │ │ │
└──────┬───────┘ └──────┬───────┘
│ │
┌──────┴───────┐ ┌──────┴───────┐
│ 主干线等长 │ │ 支线过长 │
│ 双绞线 │ │ (>0.3m) │
└──────┬───────┘ └──────┬───────┘
┌──────┴───────┐ ┌──────┴───────┐
│ 节点靠近主线 │ │ 星型连接 │
│ 支线<0.3m │ │ 反射严重 │
└──────────────┘ └──────────────┘
关键参数计算:
1. 终端电阻值:R = √(L/C)
其中L为导线电感,C为电容
典型值:120Ω(汽车)、100Ω(工业)
2. 最大节点数:考虑驱动器负载能力
CAN收发器驱动能力:通常45-60Ω
最小负载电阻 = 120Ω/2 = 60Ω
理论最大节点数 = 60Ω/每个节点最小负载
2. 软件设计模式
c
// CAN消息处理状态机示例
typedef enum {
CAN_STATE_IDLE,
CAN_STATE_TX_PENDING,
CAN_STATE_TX_SUCCESS,
CAN_STATE_TX_ERROR,
CAN_STATE_RX_READY
} CAN_State_t;
// 消息优先级队列设计
typedef struct {
uint32_t can_id; // CAN标识符
uint8_t data[8]; // 数据
uint8_t dlc; // 数据长度
uint32_t timestamp; // 时间戳
uint8_t priority; // 计算出的优先级
} CAN_Msg_t;
// 优先级计算:ID值越小优先级越高
uint8_t calculate_priority(uint32_t can_id) {
// 标准帧:11位ID
// 扩展帧:29位ID,但通常只使用部分位
return (can_id & 0x7FF); // 取低11位
}
// 消息过滤配置(硬件过滤器)
void setup_can_filters(void) {
// 方法1:单ID过滤
CAN_FilterTypeDef filter;
filter.FilterIdHigh = 0x100 << 5; // ID高16位
filter.FilterIdLow = 0x0000; // ID低16位
filter.FilterMaskIdHigh = 0x7FF << 5; // 全匹配
filter.FilterMaskIdLow = 0x0000;
// 方法2:ID范围过滤
filter.FilterIdHigh = 0x100 << 5; // 起始ID
filter.FilterIdLow = 0x200 << 5; // 结束ID
filter.FilterMaskIdHigh = 0x0000; // 不检查高位
filter.FilterMaskIdLow = 0x0000;
}
十、故障诊断与调试
常见问题及解决方法
CAN网络常见故障树:
┌─────────────────────────────────────┐
│ 通信失败 │
├─────────────────────────────────────┤
├─ 物理层问题(60%) │
│ ├─ 终端电阻缺失/错误值 │
│ ├─ 电缆短路/开路 │
│ ├─ 接地不良 │
│ └─ 节点距离过远 │
│ │
├─ 配置问题(30%) │
│ ├─ 波特率不匹配 │
│ ├─ ID冲突 │
│ ├─ 过滤器设置错误 │
│ └─ 帧格式不匹配 │
│ │
└─ 软件问题(10%) │
├─ 缓冲区溢出 │
├─ 超时处理不当 │
└─ 状态机错误 │
调试工具与方法
CAN调试工具链:
1. CAN分析仪(硬件)
- 监听模式:被动监听所有流量
- 注入模式:主动发送测试消息
- 触发功能:特定条件触发记录
2. 软件工具
- Wireshark + CAN插件
- CANalyzer/CANoe(专业)
- 自定义分析脚本
3. 诊断流程
┌─────────────┐
│ 检查物理连接 │
│ - 终端电阻 │
│ - 电缆通断 │
└──────┬──────┘
↓
┌─────────────┐
│ 检查信号质量 │
│ - 示波器波形 │
│ - 差分电压 │
└──────┬──────┘
↓
┌─────────────┐
│ 基础通信测试 │
│ - 回环测试 │
│ - 单节点测试 │
└──────┬──────┘
↓
┌─────────────┐
│ 协议分析 │
│ - 消息流 │
│ - 错误帧 │
└─────────────┘
十一、CAN协议未来发展趋势
1. CAN FD(Flexible Data-rate)
CAN FD关键改进:
传统CAN限制: CAN FD突破:
├─ 最大速率1Mbps ├─ 仲裁段:1Mbps
├─ 固定速率传输 ├─ 数据段:最高8Mbps
├─ 最大8字节数据 ├─ 最大64字节数据
└─ 效率较低 └─ 效率提升300%
CAN FD帧结构:
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│SOF│ID │RTR│IDE│FDF│BRS│ESI│DLC│数据│CRC│ACK│
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│1 │11 │1 │1 │1 │1 │1 │4 │0-512│0-21│2 │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
单位:bit
2. CAN XL(下一代CAN)
CAN XL主要特性:
┌─────────────────────────────────────┐
│ 超大容量:最多2048字节数据 │
│ 更高速度:10Mbps+ │
│ 兼容性:兼容CAN FD和CAN 2.0 │
│ 新特性:优先权提升、时间同步 │
└─────────────────────────────────────┘
应用场景:
- 自动驾驶传感器数据(摄像头、雷达)
- 车辆软件OTA更新
- 高带宽车载娱乐系统
十二、总结与最佳实践
CAN设计黄金法则

关键要点总结
- 物理层是基础:正确的布线和终端电阻决定成败
- ID设计是艺术:合理的优先级分配确保实时性
- 错误处理是保障:完善的错误恢复机制保证可靠性
- 测试验证是关键:从单元测试到系统测试的全流程验证
适用场景建议
| 应用需求 | 推荐方案 | 理由 |
|---|---|---|
| 汽车控制网络 | CAN 2.0B | 成熟稳定、广泛支持 |
| 工业实时控制 | CANopen | 功能丰富、标准化 |
| 大数据传输 | CAN FD | 高效率、大容量 |
| 低成本简单应用 | CAN 2.0A | 简单易实现 |
| 未来车载网络 | CAN XL | 高带宽、向前兼容 |
CAN协议经过30多年发展,已成为工业控制领域的事实标准。理解其设计哲学和实现细节,能够帮助工程师设计出更可靠、更高效的分布式控制系统。随着CAN FD和CAN XL的发展,CAN协议将继续在汽车电子和工业自动化领域发挥重要作用。
