STM32-CAN 📅 2026/8/5 10:06:41 一、CAN 是什么CAN 是一种面向现场总线的串行通信协议。和普通 UART 点对点通信不同CAN 更强调多个节点挂在同一条总线上进行可靠通信。CAN 总线通常由以下部分组成CAN 控制器芯片内部的 CAN 外设例如 STM32 内部的 bxCANCAN 收发器外部电平转换芯片例如 TJA1050、SIT1050T 等CAN_H 和 CAN_L两根差分信号线终端电阻用于阻抗匹配减少信号反射STM32 内部 CAN 外设负责协议层处理比如报文收发、仲裁、过滤、错误管理等外部 CAN 收发器负责把控制器的逻辑信号转换成 CAN_H/CAN_L 差分信号。常见 CAN 类型可以简单分为类型速率范围典型特点低速 CAN10Kbps ~ 125Kbps通信距离较远低速场景使用高速 CAN125Kbps ~ 1Mbps经典 CAN 常用形式应用最广CAN FD可达数 Mbps数据段速率更高兼容经典 CAN 的部分机制对于 STM32F1 这类带 bxCAN 的芯片主要学习和使用的是经典 CAN也就是 CAN 2.0A / CAN 2.0B。二、CAN 总线特点CAN 总线有几个非常重要的特点1. 多主控制CAN 总线不是传统“一主多从”的结构。每个节点在总线空闲时都可以主动发送数据。这意味着 CAN 总线上没有固定主机任何节点都可以成为发送节点也可以成为接收节点。2. 无节点地址靠报文 ID 区分数据CAN 报文里没有类似 IIC 从机地址那样的设备地址。CAN 更关注“这条消息是什么”而不是“这条消息发给谁”。接收节点通过报文 ID 判断自己是否关心这条消息。这样新增节点时通常不会破坏原有总线结构。3. 速度快距离远CAN 使用差分信号传输抗干扰能力强。通信速率和传输距离需要平衡速率越高可稳定传输的距离通常越短距离越远通常需要降低速率并做好布线和终端匹配4. 错误处理能力强CAN 协议内置错误检测、错误通知和错误恢复机制。节点可以检测位错误、CRC 错误、格式错误、应答错误等并通过错误帧通知其他节点。这也是 CAN 适合汽车和工业现场的重要原因。5. 支持较多节点CAN 总线可以连接多个节点但节点数量、通信速度、线缆长度和收发器性能之间需要综合权衡。三、CAN 物理层差分信号与显性/隐性电平CAN 使用CAN_H和CAN_L两根线进行差分传输。接收端根据两根线之间的电压差判断总线电平。CAN 总线电平分为两种总线电平逻辑值特点显性电平逻辑 0优先级高可以覆盖隐性电平隐性电平逻辑 1总线空闲时通常处于隐性状态显性电平具有优先权这一点非常关键。它使 CAN 可以实现非破坏性仲裁多个节点同时发送时低 ID 报文可以继续发送其他节点自动退出不会把总线数据撞坏。高速 CAN 和低速 CAN 的物理拓扑不同低速 CAN 通常属于开环总线高速 CAN 通常属于闭环总线两端需要终端电阻实际硬件设计中高速 CAN 总线两端常接120Ω终端电阻用于阻抗匹配减少回波反射。四、CAN 收发器STM32 的 CAN 控制器不能直接连接 CAN_H/CAN_L 总线需要外接 CAN 收发器。常见芯片包括TJA1050TJA1042SIT1050T以 SIT1050T / TJA1050 这类高速 CAN 收发器为例常见引脚含义如下引脚作用D / TXDCAN 发送输入端连接 CAN 控制器发送引脚R / RXDCAN 接收输出端连接 CAN 控制器接收引脚CANH高电位 CAN 总线端CANL低电位 CAN 总线端Vref参考电压输出RS模式控制可用于高速或静音模式简单理解STM32 bxCAN_TX - CAN 收发器 D/TXD - CAN_H/CAN_L 总线 STM32 bxCAN_RX - CAN 收发器 R/RXD - CAN_H/CAN_L 总线CAN 控制器处理协议CAN 收发器处理电气信号两者配合才能完成真实总线通信。五、CAN 协议层5 种帧类型CAN 总线以“帧”为单位进行通信。CAN 协议定义了 5 种帧帧类型作用数据帧发送节点向接收节点传输数据最常用遥控帧接收节点向具有相同 ID 的发送节点请求数据错误帧节点检测到错误时通知其他节点过载帧接收节点通知自己暂时没有准备好接收间隔帧用于分隔数据帧或遥控帧日常应用里最常见的是数据帧。六、CAN 数据帧结构CAN 数据帧由 7 个段组成数据帧字段作用帧起始表示数据帧开始使用显性信号仲裁段包含报文 ID 和 RTR 位用于决定总线优先级控制段表示数据长度和保留位数据段真正传输的数据经典 CAN 一帧可发送0~8字节CRC 段用于检测帧传输错误ACK 段接收节点确认正确接收帧结束表示数据帧结束通常为 7 个隐性位CAN 数据帧又分为标准帧和扩展帧帧格式标识符长度对应版本标准帧11 位 IDCAN 2.0A扩展帧29 位 IDCAN 2.0BSTM32 bxCAN 支持 CAN 2.0A 和 CAN 2.0B Active因此可以处理标准数据帧和扩展数据帧。七、CAN 位时序CAN 通过位时序机制完成采样和同步。一个 CAN 位时间由多个时间量子Tq组成。经典 CAN 协议中一个位时间可以理解为以下几段时间段含义SS同步段通常为1TqPTS传播时间段用于补偿总线传播延迟PBS1相位缓冲段 1PBS2相位缓冲段 2在 STM32 bxCAN 中位时序配置常见为 3 个部分bxCAN 字段对应理解SYNC_SEG同步段固定为1TqBS1相当于协议中的PTS PBS1BS2相位缓冲段 2CAN 波特率计算可以按下面的思路理解CAN波特率 CAN时钟 / 分频系数 / (1 BS1 BS2)其中1对应同步段SYNC_SEG。例如 CAN 时钟为36MHz分频系数为9BS1 5TqBS2 2Tq则波特率 36MHz / 9 / (1 5 2) 500Kbps位时序不仅影响波特率也会影响采样点位置。采样点就是 CAN 控制器读取总线电平并把它判定为当前位值的位置。八、CAN 同步机制CAN 总线上的每个节点都有自己的时钟。由于晶振误差、线缆传播延迟等因素不同节点对同一位的理解可能出现偏移所以 CAN 需要同步机制。CAN 同步可以分为1. 硬同步节点检测到帧起始边沿时会将自己的同步段调整到该边沿位置从而让内部位时序和总线重新对齐。2. 再同步在普通数据位传输过程中如果检测到边沿偏移CAN 控制器会通过调整PBS1或PBS2进行再同步。再同步调整的最大范围由SJW决定。SJW的范围通常为1~4Tq。SJW越大吸收时钟误差和相位偏差的能力越强但配置也要配合整体位时序不能脱离通信速率和采样点随意设置。九、CAN 总线仲裁CAN 支持多个节点同时尝试发送数据。为了避免总线冲突CAN 使用基于报文 ID 的仲裁机制。仲裁规则可以概括为总线空闲时最先开始发送的节点获得发送权多个节点同时发送时从仲裁段的第一位开始比较显性电平0优先于隐性电平1谁先发送隐性电平但检测到总线为显性电平谁就失去仲裁失去仲裁的节点自动转为接收状态并在总线空闲后再次尝试发送由于显性位可以覆盖隐性位因此 CAN 仲裁不会破坏正在发送的高优先级报文这叫非破坏性仲裁。报文 ID 数值越小仲裁时越容易保持显性位因此优先级越高。十、STM32 bxCAN 控制器STM32 中常见的 CAN 外设叫 bxCAN。它支持 CAN 2.0A 和 CAN 2.0B Active 协议。bxCAN 的主要特点最高波特率可达1Mbps支持标准帧和扩展帧支持时间触发通信具有 3 个发送邮箱具有 2 个接收 FIFO每个 FIFO 具备 3 级深度支持可变过滤器组部分系列最多 28 个过滤器组支持正常、睡眠、初始化等工作模式支持静默、环回、环回静默等测试模式1. 工作模式工作模式作用初始化模式用于配置 CAN 寄存器正常模式CAN 与总线同步开始收发数据睡眠模式降低功耗2. 测试模式测试模式作用静默模式只监听总线不主动影响总线适合统计总线流量环回模式发送数据直接回到接收路径适合自检环回静默模式内部自收自发且不影响外部总线学习 CAN 时环回模式很适合先验证 CAN 外设配置是否正确真正接入总线前再切换到正常模式。十一、bxCAN 内部结构bxCAN 内部主要由以下部分组成模块作用CAN 内核包含控制、状态、配置寄存器可配置模式和波特率发送邮箱缓存待发送报文最多可缓存 3 个接收 FIFO缓存接收到的有效报文接收过滤器判断哪些报文可以进入接收 FIFO发送过程大致是应用层准备报文 - 写入发送邮箱 - bxCAN 根据总线状态参与仲裁 - 仲裁成功后发送到 CAN 总线接收过程大致是CAN 总线收到报文 - bxCAN 检查帧格式和 CRC - 通过过滤器筛选 - 合格报文进入接收 FIFO - 软件读取 FIFO 中的报文十二、CAN 接收过滤器CAN 总线上所有节点都能看到总线上的报文。如果每条报文都交给软件处理CPU 压力会很大。因此 bxCAN 提供硬件接收过滤器。每个过滤器组都有两个 32 位寄存器CAN_FxR1和CAN_FxR2。过滤器的具体含义由两类配置决定位宽16 位或 32 位模式屏蔽位模式或标识符列表模式1. 屏蔽位模式屏蔽位模式用于“匹配一类 ID”。可以理解为FilterId 希望匹配的 ID FilterMask 哪些位需要比较哪些位可以忽略这种模式适合接收一段范围或一类规则相近的报文。2. 标识符列表模式标识符列表模式用于“精确匹配某些 ID”。适合只接收几个固定 ID 的场景例如只关心0x100、0x101、0x200这类指定报文。3. FIFO 关联过滤器命中的报文可以配置进入 FIFO0 或 FIFO1。项目中可以按消息类型划分重要实时消息进入 FIFO0普通状态消息进入 FIFO1这样软件处理时会更清晰。十三、CAN 常用寄存器理解 HAL 库时知道关键寄存器的职责很有帮助。寄存器作用CAN_MCRCAN 主控制寄存器主要配置工作模式CAN_BTR位时序寄存器配置分频、BS1、BS2、SJW 和测试模式CAN_(T/R)IxR标识符寄存器存放发送或接收报文 ID、IDE、RTR 等CAN_(T/R)DTxR数据长度和时间戳寄存器保存 DLC 等信息CAN_(T/R)DLxR低位数据寄存器保存 Data0~Data3CAN_(T/R)DHxR高位数据寄存器保存 Data4~Data7CAN_FM1R过滤器模式寄存器设置列表模式或屏蔽位模式CAN_FS1R过滤器位宽寄存器设置 16 位或 32 位CAN_FFA1RFIFO 关联寄存器设置过滤后进入哪个 FIFOCAN_FA1R过滤器激活寄存器开启对应过滤器组CAN_FxR1 / CAN_FxR2过滤器组寄存器保存具体过滤规则实际开发时不一定直接操作这些寄存器但它们能帮助理解 HAL 初始化结构体背后的含义。十四、CAN 常用 HAL 接口STM32 HAL 库中CAN 常用接口如下HAL 接口或宏作用__HAL_RCC_CANx_CLK_ENABLE使能 CAN 外设时钟HAL_CAN_Init初始化 CAN 外设HAL_CAN_ConfigFilter配置 CAN 接收过滤器HAL_CAN_Start启动 CAN 外设HAL_CAN_ActivateNotification使能 CAN 通知中断__HAL_CAN_ENABLE_IT使能指定 CAN 中断HAL_CAN_AddTxMessage添加待发送报文到发送邮箱HAL_CAN_GetTxMailboxesFreeLevel查询空闲发送邮箱数量HAL_CAN_GetRxFifoFillLevel查询接收 FIFO 中的报文数量HAL_CAN_GetRxMessage从接收 FIFO 读取报文常见结构体结构体作用CAN_InitTypeDef配置 CAN 工作模式、位时序、自动重传等CAN_FilterTypeDef配置接收过滤器CAN_TxHeaderTypeDef配置发送报文头CAN_RxHeaderTypeDef保存接收报文头十五、CAN 基本驱动配置思路CAN 的配置流程可以按下面几步理解。1. 初始化 CAN 参数通过HAL_CAN_Init配置 CAN 外设基础参数包括工作模式自动重传自动唤醒自动离线管理位时序分频BS1BS2SJW其中位时序参数直接决定 CAN 波特率必须和总线上其他节点一致。2. 初始化底层硬件在HAL_CAN_MspInit中通常完成使能 CAN 外设时钟使能对应 GPIO 时钟配置 CAN_TX 引脚为复用推挽输出配置 CAN_RX 引脚为输入或复用输入如需中断配置 NVIC如果使用外部收发器还要保证 CAN 收发器供电、模式控制引脚和终端电阻配置正确。3. 配置接收过滤器通过HAL_CAN_ConfigFilter配置硬件过滤器。至少需要保证目标报文能够通过过滤器进入 FIFO否则总线上有数据也可能读不到。调试初期可以先配置成接收所有 ID确认通信链路正常后再收紧过滤规则。4. 启动 CAN 外设调用HAL_CAN_Start后CAN 才真正进入可通信状态。如果只是初始化了参数但没有启动外设发送和接收都不会正常进行。5. 发送和接收数据发送时通常使用HAL_CAN_AddTxMessage接收时通常使用HAL_CAN_GetRxFifoFillLevel HAL_CAN_GetRxMessage如果使用中断方式还需要开启通知并实现对应回调函数。6. 可选使能中断如果项目需要及时接收报文可以使能 FIFO 消息挂起中断。典型流程是HAL_CAN_ActivateNotification - NVIC 配置 - 中断回调中读取 FIFO 报文中断中建议尽量只做数据搬运和状态标记复杂解析留到主循环或任务中处理。