资讯动态

第四章:CAN 波特率计算、过滤器与掩码原理

发布时间:2026/8/24 13:45:46 来源:尧图企业网站定制
导读很多初学者直接复制网上 CAN 初始化代码只修改波特率参数遇到通讯不上、只能发不能收、部分 ID 收不到报文等问题完全无从下手。本章讲解 CAN 位时序、波特率计算过滤器掩码底层逻辑提供完整可直接工程使用的初始化代码同时拆解每一个配置参数的实际含义。4.1 CAN 波特率与时序基础CAN 总线通讯的首要前提总线上所有节点波特率必须完全一致只要任意一个节点波特率不匹配整个网络就会出现乱码、丢包、BusOff。常见工程波特率波特率典型应用场景最大总线长度1000Kbps短距离板间、机器人底盘40m500Kbps车载设备、工业模块100m250Kbps中等距离工控组网250m125Kbps远距离分布式设备500mCAN 的一个 bit 位由多个时间量子tq组成。tq时间量子CAN 控制器的最小时间单位由 APB 时钟 预分频器计算得来。一个完整 bit SYNC_SEG BS1 BS2位段组成SYNC_SEG同步段固定 1 个tq。用于总线节点同步跳变沿总线上检测到电平跳变就在此段完成同步。BS1位段 1可以设置 1‑16 个tq包含 PROP_SEG PHASE_SEG1用于补偿网络物理延迟。BS2位段 2可以设置 1‑8 个tqPHASE_SEG2补偿相位误差。公式一个 bit 总时间量子数 1 (SYNC_SEG) BS1 BS2波特率 外设时钟 / (预分频器 * (1 BS1 BS2))工程惯例推荐 1BS1BS2 16 tq这是行业最常用配置兼容性最好。 例APB1 时钟 36MSTM32F103目标 500K 波特率。 目标每 bit 16 tq。 每 bit 时间 1 / 500000 2us 每个 tq 2us /16 125ns 预分频 36M * 125ns 4.5取整数预分频 4。 此时tq 4 / 36M 111.11ns16tq 1.7778us波特率≈562.5K不是标准 500K。 所以调整总 tq181BS1BS2 18BS113BS24预分频 4。 波特率 36M/(418)500K得到标准 500K。STM32F103 经典配置表APB136MHz目标波特率Prescaler 预分频BS1BS2总 tq1000K46316310500K4134113418250K813418125K1613418注意STM32 不同系列 APB1 时钟不一样F4 APB1 最大 42MF1 是 36M不能直接复制别人的 BS1 BS2 和预分频要按照自己芯片时钟计算。4.2 过滤器与掩码深度原理CAN 控制器硬件过滤器作用硬件层面过滤不需要的报文减少 CPU 中断压力。如果不配置过滤器收到总线上全部报文配置过滤器之后只有 ID 匹配的报文才存入 FIFO触发接收中断。很多人记不住掩码公式这里讲透匹配逻辑(接收报文ID 掩码Mask) (过滤ID 掩码Mask)Mask 掩码位 1对应 ID 位必须严格相等才匹配通过Mask 掩码位 0对应 ID 位不管是 0 还是 1都忽略直接放行举工程实例标准帧 11bit ID 实例 1只想接收 ID0x200 的报文。 ID Filter0x200Mask0x7FF二进制 111 1111 1111。掩码全部置 1每一位 ID 必须完全等于 0x200其他 ID 全部过滤丢弃。实例 2接收 0x100 ~ 0x10F 这一组 ID只看高 7bit低 4bit 忽略。 ID Filter0x100Mask0x7F0。 Mask 低 4bit0代表低 4bit 不做校验只要 ID 高 7 位等于 0x100无论低 4 位是什么全部接收。 报文 ID0x101、0x105、0x10F 都会匹配进入接收 FIFO。掩码通俗记忆掩码为 1 代表管掩码为 0 代表不管。过滤器两种工作模式列表模式每个过滤器存完整 ID只接收这几个 ID适合少量固定 ID。掩码模式屏蔽模式FilterMask 组合匹配一组 ID适合接收连续 ID 区间。STM32CAN 拥有 14 个过滤器Filter0~Filter13可以分配给 CAN1、CAN2支持 32 位模式、16 位模式支持标准帧和扩展帧。常见踩坑过滤器配置错误想要接收 0x100但是 Mask 写 0总线上所有报文全部进来CPU 中断爆满。过滤器模式选错列表模式却传入 Mask匹配逻辑错乱。过滤器序号冲突双 CAN 芯片过滤器归属分配错误收不到报文。过滤器开启之后不符合条件报文硬件直接丢弃软件收不到。调试阶段建议先配置 Mask0x0接收全部报文确认通讯正常后再收紧过滤条件。4.3 STM32 HAL 库 CAN 完整初始化代码硬件前提hcan 实例PA11 CAN_RX PA12 CAN_TXAPB1 时钟 36M波特率 500K。 代码包含CAN 初始化、过滤器配置、开启接收中断。#include can.h /** * brief CAN初始化500K标准帧FIFO0接收中断开启 */ uint8_t CAN_Init_500K(void) { hcan.Instance CAN1; hcan.Init.Prescaler 4; //预分频 hcan.Init.Mode CAN_MODE_NORMAL; //正常工作模式回环测试模式CAN_MODE_LOOPBACK hcan.Init.SyncJumpWidth CAN_SJW_1TQ; hcan.Init.TimeSeg1 CAN_BS1_13TQ; hcan.Init.TimeSeg2 CAN_BS2_4TQ; hcan.Init.TimeTriggeredMode DISABLE; hcan.Init.AutoBusOff ENABLE; //自动恢复BusOff工程建议开启 hcan.Init.AutoWakeUp DISABLE; hcan.Init.AutoRetransmission ENABLE; //传输出错自动重发 hcan.Init.ReceiveFifoLocked DISABLE; hcan.Init.TransmitFifoPriority DISABLE; if (HAL_CAN_Init(hcan) ! HAL_OK) { return 1; } //配置过滤器过滤器0掩码模式接收ID0x100以及0x100~0x10F一组报文示例 CAN_FilterTypeDef sFilterConfig; sFilterConfig.FilterBank 0; sFilterConfig.FilterMode CAN_FILTERMODE_IDMASK; //掩码模式 sFilterConfig.FilterScale CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh 0x100 5; //标准ID左移5位STM32寄存器要求 sFilterConfig.FilterIdLow 0x0000; sFilterConfig.FilterMaskIdHigh 0x7F0 5; //掩码 sFilterConfig.FilterMaskIdLow 0x0000; sFilterConfig.FilterFIFOAssignment CAN_RX_FIFO0; sFilterConfig.FilterActivation ENABLE; sFilterConfig.SlaveStartFilterBank 14; if(HAL_CAN_ConfigFilter(hcan, sFilterConfig) ! HAL_OK) { return 2; } //开启FIFO0消息挂起中断 if (HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING)!HAL_OK) { return 3; } //启动CAN外设 if(HAL_CAN_Start(hcan)!HAL_OK) { return 4; } return 0; }重要知识点STM32 标准 ID 写入 FilterIdHigh 的时候需要左移 5 位。 寄存器格式11 位标准 ID 放在 bit22~bit12所以赋值ID 5。很多教程没有讲这个点复制代码过滤器完全失效。回环自测模式开发无硬件时软件自测 CAN 代码//把初始化Mode改为CAN_MODE_LOOPBACK hcan.Init.Mode CAN_MODE_LOOPBACK;回环模式下MCU 内部自发自收不需要外接 TJA1050 收发器用来验证初始化、发送接收回调、过滤器逻辑是否正确调试软件逻辑非常好用。注意回环模式只是内部仿真无法和外部真实 CAN 设备通讯。调试完务必切回 CAN_MODE_NORMAL。4.4 常用参数配置说明AutoBusOff ENABLE当进入 Bus‑Off硬件自动尝试恢复总线如果关闭BusOff 之后必须软件手动调用 HAL_CAN_Init 重新初始化。工业项目建议开启。AutoRetransmission ENABLE传输出错硬件自动重发关闭则出错放弃报文。绝大多数场景开启。FilterBank 过滤器编号F1 系列一共 0‑13 共 14 组过滤器。4.5 完整收发函数整合承接第二章把第二章的安全发送函数放进来组成完整业务调用接口。extern CAN_HandleTypeDef hcan; /** * brief CAN安全发送标准数据帧 * param std_id 标准ID * param data 数据缓冲区 * param len 0~8 * retval 0成功1参数错误2总线故障3发送失败 */ uint8_t CAN_Send_StdData(uint16_t std_id,uint8_t *data,uint8_t len) { if(len8 || data NULL) { return 1; } if(hcan.State ! HAL_CAN_STATE_READY) { return 2; } CAN_TxHeaderTypeDef tx_header{0}; uint32_t tx_mailbox; tx_header.StdId std_id; tx_header.IDE CAN_ID_STD; tx_header.RTR CAN_RTR_DATA; tx_header.DLC len; tx_header.TransmitGlobalTime DISABLE; if(HAL_CAN_AddTxMessage(hcan,tx_header,data,tx_mailbox) HAL_OK) { return 0; } return 3; }调用示例主循环发送 ID0x2004 字节数据uint8_t send_buf[4]{0x11,0x22,0x33,0x44}; CAN_Send_StdData(0x200,send_buf,4);4.6 本章调试排错清单发送成功但是收不到外部设备报文检查波特率 BS1 BS2 预分频确认芯片 APB 时钟检查过滤器 ID、掩码标准 ID 是否左移 5 位确认中断是否开启HAL_CAN_ActivateNotification 是否调用能收到报文但是只有部分 ID 进来过滤器掩码条件过严调大掩码掩码值减小回环模式收发正常接上外部硬件完全不通检查 Mode 是不是忘记切回 NORMAL硬件收发器、120Ω 电阻。频繁 BusOff优先排查硬件接线不要单纯调软件参数。第四章到此结束。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价