STM32——CAN总线 - 详解

STM32——CAN总线


1. CAN总线基础概念

1.1 CAN总线简介

控制器局域网(Controller Area Network, CAN)是由Bosch公司开发的串行通信协议,专为汽车电子和工业控制设计,具有以下核心特性:

  • 多主控制架构:所有节点均可主动发送数据
  • 差分信号传输:CAN_H与CAN_L双绞线抗干扰
  • 非破坏性仲裁:基于ID优先级的冲突解决机制
  • 高可靠性:CRC校验、错误帧检测等安全机制

图表

CAN_H/CAN_L
CAN_H/CAN_L
CAN_H/CAN_L
节点1
CAN总线
节点2
节点3
终端电阻 120Ω

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 功能框图

CAN核心
发送邮箱
接收FIFO
过滤器组
控制逻辑
CAN TX
CAN RX
标识符匹配
波特率控制

2.2 关键效果单元

  1. 发送邮箱:3个独立邮箱(F1/F4系列)
    • 优先级管理机制
    • 自动重传特性
  2. 接收FIFO:2个FIFO(FIFO0/FIFO1)
    • 每个FIFO深度3个报文
    • 可配置溢出处理
  3. 过滤器组:最多28个(F4系列)
    • 工作模式:掩码模式/列表模式
    • 尺度选择:16位/32位

3. CAN通信协议详解

3.1 数据帧结构

┌───┬───────┬──────┬───┬───────┬──────┬──────┬───┬───┐ │SOF│Arbitr.│Control│IDE│Data │ CRC │ ACK │EOF│IFS│ │111/29610-641627 |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 基础配置流程

  1. 在Pinout视图启用CAN
  2. 配置参数:
    • Mode:Normal/Loopback
    • Bit Timings:设置Prescaler/BS1/BS2
  3. 过滤器配置:
    • Filter Activate:Enable
    • Scale:32-bit/16-bit
    • Mode:Mask/List
  4. NVIC设置:启用接收中断

4.2 推荐调整参数(500kbps)

参数说明
Prescaler6分频系数
Time Quanta12总时间量子数
BS18 TQ传播时间段
BS23 TQ相位缓冲段2
SJW1 TQ同步跳转宽度
Sample Point75%(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 典型问题排查

  1. 无法通信
    • 检查终端电阻(总线两端各120Ω)
    • 验证波特率配置一致性
    • 测量CAN_H-CAN_L差分电压(2V左右)
  2. 数据丢失
    • 增加接收FIFO深度
    • 优化过滤器设置减少无关报文
    • 提升中断优先级
  3. 总线错误
    • 使用HAL_CAN_GetError()获取错误码
    • 否受干扰就是检查物理线路
    • 降低波特率测试稳定性

7. 应用案例

7.1 汽车电子网络

┌──────────────┐ ┌──────────────┐ │ 发动机控制器 │◄─────►│ 车身控制模块 │ ├──────────────┤ ├──────────────┤ │ CAN总线 │◄──┐ ┌─►│ 仪表盘显示 │ └──────▲───────┘ │ │ └──────────────┘ │ ▼ ▼ ┌──────┴───────┐ ┌──────────────┐ │ 制动框架 │ │ 网关控制器 │ └──────────────┘ └──────────────┘

7.2 工业控制系统

CAN
CAN
CAN
STM32-PLC
电机驱动器
IO模块
传感器集线器
伺服电机
限位开关
温度传感器

最佳实践提示:在工业环境中,建议使用带隔离的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
posted on 2025-06-07 14:23  ljbguanli  阅读(150)  评论(0)    收藏  举报