STM32——CAN总线
1. CAN总线基础概念
1.1 CAN总线简介
控制器局域网(Controller Area Network, CAN)是由Bosch公司开发的串行通信协议,专为汽车电子和工业控制设计,具有以下核心特性:
- 多主控制架构:所有节点均可主动发送数据
- 差分信号传输:CAN_H与CAN_L双绞线抗干扰
- 非破坏性仲裁:基于ID优先级的冲突解决机制
- 高可靠性:CRC校验、错误帧检测等安全机制
图表
1.2 CAN物理层结构
组件 | 功能说明 | 典型参数 |
---|---|---|
CAN控制器 | 协议处理、帧过滤 | 集成在STM32内部 |
CAN收发器 | 电平转换(TTL↔差分) | TJA1050, SN65HVD |
双绞线 | 信号传输介质 | 特性阻抗120Ω |
终端电阻 | 消除信号反射 | 120Ω两端各1个 |
物理连接示意图:
STM32 CAN收发器 CAN总线
|------| |------| |--------|
| | TX ----| TXD | | CAN_H |
| CAN | | |--------| |
| 控制 | RX ----| RXD | | CAN_L |
| 器 | |------| |--------|
|------| ↑
VCC(5V)
2. STM32 CAN控制器架构
2.1 功能框图
2.2 关键功能单元
- 发送邮箱:3个独立邮箱(F1/F4系列)
- 优先级管理机制
- 自动重传功能
- 接收FIFO:2个FIFO(FIFO0/FIFO1)
- 每个FIFO深度3个报文
- 可配置溢出处理
- 过滤器组:最多28个(F4系列)
- 工作模式:掩码模式/列表模式
- 尺度选择:16位/32位
3. CAN通信协议详解
3.1 数据帧结构
┌───┬───────┬──────┬───┬───────┬──────┬──────┬───┬───┐
│SOF│Arbitr.│Control│IDE│Data │ CRC │ ACK │EOF│IFS│
│1 │11/29 │6 │1 │0-64 │16 │2 │7 |3 |
└───┴───────┴──────┴───┴───────┴──────┴──────┴───┴───┘
- SOF:帧起始(显性电平)
- Arbitration:ID+ RTR位(11位标准/29位扩展)
- Control:DLC(数据长度0-8字节)
- CRC:15位校验 + 1位界定符
- ACK:应答槽 + 应答界定符
3.2 波特率配置
计算公式:
波特率 = APB1时钟 / (Prescaler * (BS1 + BS2 + 1))
位时间组成:
┌───┬──────────────┬──────────────┐
│SYNC│ BS1(Prop) │ BS2(Ph2) │
├───┼─────┬────┬───┼─────┬────┬───┤
│ 1 │ TQ1│... │TQn│ TQ1│... │TQm│
└───┴─────┴────┴───┴─────┴────┴───┘
- SYNC_SEG:固定1个时间量子(TQ)
- BS1:传播时间段(1-16 TQ)
- BS2:相位缓冲段2(1-8 TQ)
4. STM32CubeMX配置步骤
4.1 基础配置流程
- 在Pinout视图启用CAN
- 配置参数:
- Mode:Normal/Loopback
- Bit Timings:设置Prescaler/BS1/BS2
- 过滤器配置:
- Filter Activate:Enable
- Scale:32-bit/16-bit
- Mode:Mask/List
- NVIC设置:启用接收中断
4.2 推荐配置参数(500kbps)
参数 | 值 | 说明 |
---|---|---|
Prescaler | 6 | 分频系数 |
Time Quanta | 12 | 总时间量子数 |
BS1 | 8 TQ | 传播时间段 |
BS2 | 3 TQ | 相位缓冲段2 |
SJW | 1 TQ | 同步跳转宽度 |
Sample Point | 75% | (1+BS1)/(1+BS1+BS2) |
5. HAL库编程实战
5.1 CAN初始化代码
CAN_HandleTypeDef hcan;
CAN_FilterTypeDef filter;
void CAN_Init(void)
{
hcan.Instance = CAN1;
hcan.Init.Prescaler = 6;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_8TQ;
hcan.Init.TimeSeg2 = CAN_BS2_3TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = DISABLE;
hcan.Init.AutoWakeUp = DISABLE;
hcan.Init.AutoRetransmission = ENABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK) {
Error_Handler();
}
// 配置过滤器(接收所有消息)
filter.FilterBank = 0;
filter.FilterMode = CAN_FILTERMODE_IDMASK;
filter.FilterScale = CAN_FILTERSCALE_32BIT;
filter.FilterIdHigh = 0x0000;
filter.FilterIdLow = 0x0000;
filter.FilterMaskIdHigh = 0x0000;
filter.FilterMaskIdLow = 0x0000;
filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
filter.FilterActivation = ENABLE;
HAL_CAN_ConfigFilter(&hcan, &filter);
HAL_CAN_Start(&hcan);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
}
5.2 数据发送函数
uint8_t CAN_Send(uint32_t id, uint8_t* data, uint8_t len)
{
CAN_TxHeaderTypeDef txHeader;
uint32_t txMailbox;
txHeader.StdId = id; // 标准ID
txHeader.ExtId = 0; // 扩展ID(标准帧设为0)
txHeader.IDE = CAN_ID_STD; // 使用标准帧
txHeader.RTR = CAN_RTR_DATA; // 数据帧
txHeader.DLC = len; // 数据长度
txHeader.TransmitGlobalTime = DISABLE;
if(HAL_CAN_AddTxMessage(&hcan, &txHeader, data, &txMailbox) != HAL_OK) {
return 0; // 发送失败
}
// 等待发送完成
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) != 3);
return 1;
}
5.3 中断接收处理
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
CAN_RxHeaderTypeDef rxHeader;
uint8_t rxData[8];
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, rxData) == HAL_OK)
{
uint32_t id = rxHeader.StdId; // 获取标准ID
uint8_t len = rxHeader.DLC; // 数据长度
// 处理接收数据 (示例: 串口转发)
printf("ID:0x%X Data:", id);
for(int i=0; i<len; i++) {
printf("%02X ", rxData[i]);
}
printf("\n");
}
}
6. 调试技巧与工具
6.1 常见调试工具
工具类型 | 推荐型号 | 特点 |
---|---|---|
CAN分析仪 | PCAN-USB, ZLG USBCAN | 专业级报文分析 |
逻辑分析仪 | Saleae, DSLogic | 物理层信号观测 |
终端电阻 | 120Ω精密电阻 | 消除信号反射 |
6.2 典型问题排查
- 无法通信:
- 检查终端电阻(总线两端各120Ω)
- 验证波特率配置一致性
- 测量CAN_H-CAN_L差分电压(2V左右)
- 数据丢失:
- 增加接收FIFO深度
- 优化过滤器设置减少无关报文
- 提升中断优先级
- 总线错误:
- 使用
HAL_CAN_GetError()
获取错误码 - 检查物理线路是否受干扰
- 降低波特率测试稳定性
- 使用
7. 应用案例
7.1 汽车电子网络
┌──────────────┐ ┌──────────────┐
│ 发动机控制器 │◄─────►│ 车身控制模块 │
├──────────────┤ ├──────────────┤
│ CAN总线 │◄──┐ ┌─►│ 仪表盘显示 │
└──────▲───────┘ │ │ └──────────────┘
│ ▼ ▼
┌──────┴───────┐ ┌──────────────┐
│ 制动系统 │ │ 网关控制器 │
└──────────────┘ └──────────────┘
7.2 工业控制系统
最佳实践提示:在工业环境中,建议使用带隔离的CAN收发器(如ISO1050)并增加TVS管保护电路,可显著提升系统抗干扰能力。
附录:CAN资源速查表
寄存器 | 功能描述 | 关键位域 |
---|---|---|
CAN_MCR | 主控制寄存器 | INRQ, SLEEP, TTCM |
CAN_MSR | 主状态寄存器 | INAK, SLAK, RX, TX |
CAN_TSR | 发送状态寄存器 | TME0/1/2, TXOK0/1/2 |
CAN_RF0R/RF1R | 接收FIFO寄存器 | FMP0/1, FULL0/1 |
CAN_FMR | 过滤器主寄存器 | FINIT, CAN2SB |
CAN_FA1R | 过滤器激活寄存器 | FACT0-27 |