STM32——CAN总线_stm32 can
STM32——CAN总线
1. CAN总线基础概念
1.1 CAN总线简介
控制器局域网(Controller Area Network, CAN)是由Bosch公司开发的串行通信协议,专为汽车电子和工业控制设计,具有以下核心特性:
- 多主控制架构:所有节点均可主动发送数据
- 差分信号传输:CAN_H与CAN_L双绞线抗干扰
- 非破坏性仲裁:基于ID优先级的冲突解决机制
- 高可靠性:CRC校验、错误帧检测等安全机制
图表
#mermaid-svg-EFg2t33nRenLtheO {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-EFg2t33nRenLtheO .error-icon{fill:#552222;}#mermaid-svg-EFg2t33nRenLtheO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EFg2t33nRenLtheO .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-EFg2t33nRenLtheO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EFg2t33nRenLtheO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EFg2t33nRenLtheO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EFg2t33nRenLtheO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EFg2t33nRenLtheO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EFg2t33nRenLtheO .marker.cross{stroke:#333333;}#mermaid-svg-EFg2t33nRenLtheO svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EFg2t33nRenLtheO .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-EFg2t33nRenLtheO .cluster-label text{fill:#333;}#mermaid-svg-EFg2t33nRenLtheO .cluster-label span{color:#333;}#mermaid-svg-EFg2t33nRenLtheO .label text,#mermaid-svg-EFg2t33nRenLtheO span{fill:#333;color:#333;}#mermaid-svg-EFg2t33nRenLtheO .node rect,#mermaid-svg-EFg2t33nRenLtheO .node circle,#mermaid-svg-EFg2t33nRenLtheO .node ellipse,#mermaid-svg-EFg2t33nRenLtheO .node polygon,#mermaid-svg-EFg2t33nRenLtheO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EFg2t33nRenLtheO .node .label{text-align:center;}#mermaid-svg-EFg2t33nRenLtheO .node.clickable{cursor:pointer;}#mermaid-svg-EFg2t33nRenLtheO .arrowheadPath{fill:#333333;}#mermaid-svg-EFg2t33nRenLtheO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EFg2t33nRenLtheO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EFg2t33nRenLtheO .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-EFg2t33nRenLtheO .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-EFg2t33nRenLtheO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EFg2t33nRenLtheO .cluster text{fill:#333;}#mermaid-svg-EFg2t33nRenLtheO .cluster span{color:#333;}#mermaid-svg-EFg2t33nRenLtheO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-EFg2t33nRenLtheO :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}CAN_H/CAN_LCAN_H/CAN_LCAN_H/CAN_L节点1CAN总线节点2节点3终端电阻 120Ω
1.2 CAN物理层结构
物理连接示意图:
STM32 CAN收发器 CAN总线|------| |------| |--------|| | TX ----| TXD | | CAN_H || CAN | | |--------| || 控制 | RX ----| RXD | | CAN_L || 器 | |------| |--------||------| ↑ VCC(5V)
2. STM32 CAN控制器架构
2.1 功能框图
#mermaid-svg-vRd6WBg0yI9ugVhr {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-vRd6WBg0yI9ugVhr .error-icon{fill:#552222;}#mermaid-svg-vRd6WBg0yI9ugVhr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vRd6WBg0yI9ugVhr .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-vRd6WBg0yI9ugVhr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vRd6WBg0yI9ugVhr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vRd6WBg0yI9ugVhr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vRd6WBg0yI9ugVhr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vRd6WBg0yI9ugVhr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vRd6WBg0yI9ugVhr .marker.cross{stroke:#333333;}#mermaid-svg-vRd6WBg0yI9ugVhr svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vRd6WBg0yI9ugVhr .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vRd6WBg0yI9ugVhr .cluster-label text{fill:#333;}#mermaid-svg-vRd6WBg0yI9ugVhr .cluster-label span{color:#333;}#mermaid-svg-vRd6WBg0yI9ugVhr .label text,#mermaid-svg-vRd6WBg0yI9ugVhr span{fill:#333;color:#333;}#mermaid-svg-vRd6WBg0yI9ugVhr .node rect,#mermaid-svg-vRd6WBg0yI9ugVhr .node circle,#mermaid-svg-vRd6WBg0yI9ugVhr .node ellipse,#mermaid-svg-vRd6WBg0yI9ugVhr .node polygon,#mermaid-svg-vRd6WBg0yI9ugVhr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vRd6WBg0yI9ugVhr .node .label{text-align:center;}#mermaid-svg-vRd6WBg0yI9ugVhr .node.clickable{cursor:pointer;}#mermaid-svg-vRd6WBg0yI9ugVhr .arrowheadPath{fill:#333333;}#mermaid-svg-vRd6WBg0yI9ugVhr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vRd6WBg0yI9ugVhr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vRd6WBg0yI9ugVhr .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-vRd6WBg0yI9ugVhr .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-vRd6WBg0yI9ugVhr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vRd6WBg0yI9ugVhr .cluster text{fill:#333;}#mermaid-svg-vRd6WBg0yI9ugVhr .cluster span{color:#333;}#mermaid-svg-vRd6WBg0yI9ugVhr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vRd6WBg0yI9ugVhr :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}CAN核心发送邮箱接收FIFO过滤器组控制逻辑CAN TXCAN RX标识符匹配波特率控制
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)
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 常见调试工具
6.2 典型问题排查
- 无法通信:
- 检查终端电阻(总线两端各120Ω)
- 验证波特率配置一致性
- 测量CAN_H-CAN_L差分电压(2V左右)
- 数据丢失:
- 增加接收FIFO深度
- 优化过滤器设置减少无关报文
- 提升中断优先级
- 总线错误:
- 使用
HAL_CAN_GetError()
获取错误码 - 检查物理线路是否受干扰
- 降低波特率测试稳定性
- 使用
7. 应用案例
7.1 汽车电子网络
┌──────────────┐ ┌──────────────┐│ 发动机控制器 │◄─────►│ 车身控制模块 │├──────────────┤ ├──────────────┤│ CAN总线 │◄──┐ ┌─►│ 仪表盘显示 │└──────▲───────┘ │ │ └──────────────┘ │ ▼ ▼┌──────┴───────┐ ┌──────────────┐│ 制动系统 │ │ 网关控制器 │└──────────────┘ └──────────────┘
7.2 工业控制系统
#mermaid-svg-sd4CfNsQz3UPBu08 {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-sd4CfNsQz3UPBu08 .error-icon{fill:#552222;}#mermaid-svg-sd4CfNsQz3UPBu08 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-sd4CfNsQz3UPBu08 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-sd4CfNsQz3UPBu08 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-sd4CfNsQz3UPBu08 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-sd4CfNsQz3UPBu08 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-sd4CfNsQz3UPBu08 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-sd4CfNsQz3UPBu08 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-sd4CfNsQz3UPBu08 .marker.cross{stroke:#333333;}#mermaid-svg-sd4CfNsQz3UPBu08 svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-sd4CfNsQz3UPBu08 .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-sd4CfNsQz3UPBu08 .cluster-label text{fill:#333;}#mermaid-svg-sd4CfNsQz3UPBu08 .cluster-label span{color:#333;}#mermaid-svg-sd4CfNsQz3UPBu08 .label text,#mermaid-svg-sd4CfNsQz3UPBu08 span{fill:#333;color:#333;}#mermaid-svg-sd4CfNsQz3UPBu08 .node rect,#mermaid-svg-sd4CfNsQz3UPBu08 .node circle,#mermaid-svg-sd4CfNsQz3UPBu08 .node ellipse,#mermaid-svg-sd4CfNsQz3UPBu08 .node polygon,#mermaid-svg-sd4CfNsQz3UPBu08 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sd4CfNsQz3UPBu08 .node .label{text-align:center;}#mermaid-svg-sd4CfNsQz3UPBu08 .node.clickable{cursor:pointer;}#mermaid-svg-sd4CfNsQz3UPBu08 .arrowheadPath{fill:#333333;}#mermaid-svg-sd4CfNsQz3UPBu08 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-sd4CfNsQz3UPBu08 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-sd4CfNsQz3UPBu08 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-sd4CfNsQz3UPBu08 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-sd4CfNsQz3UPBu08 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-sd4CfNsQz3UPBu08 .cluster text{fill:#333;}#mermaid-svg-sd4CfNsQz3UPBu08 .cluster span{color:#333;}#mermaid-svg-sd4CfNsQz3UPBu08 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-sd4CfNsQz3UPBu08 :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}CANCANCANSTM32-PLC电机驱动器IO模块传感器集线器伺服电机限位开关温度传感器
最佳实践提示:在工业环境中,建议使用带隔离的CAN收发器(如ISO1050)并增加TVS管保护电路,可显著提升系统抗干扰能力。