STM32——CAN总线 - 详解
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_ttxMailbox;txHeader.StdId = id; // 标准IDtxHeader.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_trxData[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 |
浙公网安备 33010602011771号