这一章在干嘛?
CAN 实验:CAN 协议帧格式、bxCAN 控制器、SN65HVD230 收发器、标识符过滤、远程帧。学会后 ECU 通信、Modbus 替代方案都能上手。
30.1 CAN 总线简介
30.1.1 CAN 简介
CAN(Controller Area Network):1986 年 Bosch 为汽车开发的串行总线。
- 差分传输:CANH/CANL 两根线;
- 多主:所有节点都可主动发送;
- 仲裁:ID 越小优先级越高;
- 速率:1 Mbps(40 m),125 kbps(500 m);
- 节点数:理论上无限(实际 120 Ω 终端电阻影响)。
原书图 30.1.1.1:CAN 总线拓扑
电平:
| 状态 | CANH | CANL | 差分 |
|---|---|---|---|
| 显性(0) | 3.5 V | 1.5 V | 2 V |
| 隐性(1) | 2.5 V | 2.5 V | 0 V |
注意 CAN 是「显性=0」,与 TTL 反逻辑。
30.1.2 CAN 帧格式
CAN 有 5 种帧:数据帧、远程帧、错误帧、过载帧、帧间隔。最常用数据帧:
| 字段 | 长度 | 说明 |
|---|---|---|
| SOF | 1 bit | 起始位(显性) |
| ID | 11 bit | 标识符(标准帧) |
| RTR | 1 bit | 远程发送请求 |
| IDE | 1 bit | 扩展帧标志 |
| r0 | 1 bit | 保留 |
| DLC | 4 bit | 数据字节数(0~8) |
| Data | 0~64 bit | 数据 |
| CRC | 15 bit | 校验 |
| ACK | 2 bit | 应答 |
| EOF | 7 bit | 帧结束 |
原书图 30.1.2.1:CAN 数据帧结构
30.1.3 bxCAN 控制器
F407 内置 bxCAN:
- 2 个 CAN 控制器(CAN1/CAN2);
- 每个有 2 个接收 FIFO(深度 3);
- 28 个过滤器组(共享);
- 支持标准帧(11 位 ID)和扩展帧(29 位 ID)。
原书图 30.1.3.1:bxCAN 框图
30.2 硬件设计
CAN1 引脚:PA11/PA12 → SN65HVD230 → CANH/CANL。
原书图 30.2.1:SN65HVD230 接线图
30.3 程序设计
30.3.1 CubeMX 配置
- CAN1 → Activated, Prescaler = 3, Time Quantum = 14 → 1 Mbps
- SJW = 1, BS1 = 12, BS2 = 1
- 引脚 PA11/PA12 设为复用推挽
- NVIC: CAN1 RX0 interrupt
30.3.2 关键代码
CAN_TxHeaderTypeDef txh = {0};
txh.StdId = 0x123;
txh.IDE = CAN_ID_STD;
txh.RTR = CAN_RTR_DATA;
txh.DLC = 8;
uint8_t tx_data[8] = {1,2,3,4,5,6,7,8};
uint32_t mailbox;
HAL_CAN_AddTxMessage(&hcan1, &txh, tx_data, &mailbox);
// 接收
CAN_RxHeaderTypeDef rxh;
uint8_t rx_data[8];
HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &rxh, rx_data);
30.4 下载验证
两块开发板对连,A 发送 → B 接收并打印到串口;用 CAN 分析仪观察波形。
终端电阻 120 Ω 必加在总线两端各一个,否则高速时信号反射导致错误。
CAN 总线用几根差分线?
2 根(CANH、CANL)。
CAN 是多主还是单主?
多主。
bxCAN 有几个接收 FIFO?
2 个,每个深度 3。