STM32 CAN总线设置多个滤波器

在STM32中配置多个CAN滤波器时,需要理解其硬件过滤机制、工作模式、配置方法以及优先级规则。以下是根据搜索结果整理的详细配置指南。

一、CAN滤波器基础概念与硬件资源

STM32的bxCAN控制器提供了硬件过滤器,用于在接收报文时进行筛选,仅将符合条件的报文存入接收FIFO,从而节省CPU开销。不同型号的STM32过滤器组数量不同:

  • 互联型产品 (如STM32F105/107):CAN1和CAN2共享28个过滤器组
  • 其他产品 (如STM32F103系列):通常有14个独立的过滤器组
  • 当存在CAN3时,CAN1与CAN2共享28个过滤器,CAN3有独立的14个过滤器。

每个过滤器组由两个32位寄存器(CAN_FxR0CAN_FxR1FxR1FxR2)组成,可以根据配置变为不同数量和宽度的过滤器。

二、滤波器的工作模式与位宽组合

每组滤波器可以配置为两种模式和两种位宽,从而形成四种主要的配置形式:

  1. 32位屏蔽位(掩码)模式 :提供1个 过滤器。寄存器1(如FxR1)存储标识符匹配值,寄存器2(如FxR2)存储屏蔽码。屏蔽码为1的位需要严格匹配,为0的位则忽略。此模式常用于过滤一组具有共同特征的ID。
  2. 32位标识符列表模式 :提供2个过滤器。寄存器1和寄存器2各存储一个完整的标识符。只有报文ID与这两个ID之一完全相同时才能通过,实现精准过滤。适用于安全系统等需要严格接收特定ID的场景。
  3. 16位屏蔽位模式 :提供2个过滤器。每个寄存器的[31:16]位存储屏蔽码,[15:0]位存储匹配值,分别对应一个过滤器。
  4. 16位标识符列表模式 :提供4个过滤器。寄存器1的[15:0]和[31:16]位、寄存器2的[15:0]和[31:16]位分别存储一个标识符。

模式选择核心

  • 列表模式:精确匹配,但受限于列表容量。适合接收固定、少量的特定ID。
  • 掩码模式:范围匹配,通过设置屏蔽码可以过滤出一组ID,灵活性高,适合接收具有相同前缀(如某个模块的所有信号)的多个ID。

三、设置多个滤波器的配置步骤与示例

配置多个滤波器,本质上是依次配置多个过滤器组(FilterBank)。每个过滤器组必须关联到两个接收FIFO(FIFO0或FIFO1)中的一个,报文通过哪个过滤器组,就会被存入其关联的FIFO。

以下是以STM32 HAL库为例的配置流程:

  1. 初始化过滤器结构体 :为每个要配置的过滤器组填充 CAN_FilterTypeDef 结构体。
  2. 设置过滤器组编号FilterBank 参数指定使用哪个过滤器组,编号从0开始。
  3. 配置模式与位宽 :通过 FilterModeFilterScale 成员设置。
  4. 设置标识符与掩码
    • 对于32位扩展ID :需要将29位的扩展ID左移3位后,拆分到 FilterIdHighFilterIdLow 中。搜索结果中提供了宏 EXT_ID_TO_CAN_FILTER 用于此转换。掩码值也需同样处理。
    • 对于32位标准ID:需要将11位标准ID左移21位后拆分。
    • 注意:在掩码模式下,若某组掩码全部设为0(通配),则会使其他组的设置失效,因为任何报文都能通过该组。
  5. 关联FIFO :通过 FilterFIFOAssignment 指定该过滤器组关联到 CAN_RX_FIFO0CAN_RX_FIFO1
  6. 激活并写入配置 :设置 FilterActivation = ENABLE,然后调用 HAL_CAN_ConfigFilter() 函数将配置写入寄存器。
  7. 重复配置 :对下一个需要使用的过滤器组,重复以上步骤,并指定新的 FilterBank 编号。

配置示例:以下代码展示了配置两个过滤器组,分别以列表模式接收扩展ID 0x425和0x426的报文,并放入不同的FIFO。

复制代码
CAN_FilterTypeDef CAN_FilterType;

// 配置过滤器组0,接收ID 0x425,存入FIFO0
CAN_FilterType.FilterBank = 0;
EXT_ID_TO_CAN_FILTER(0x425, CAN_FilterType.FilterIdHigh, CAN_FilterType.FilterIdLow);
CAN_FilterType.FilterMaskIdHigh = 0;
CAN_FilterType.FilterMaskIdLow = 0;
CAN_FilterType.FilterFIFOAssignment = CAN_RX_FIFO0;
CAN_FilterType.FilterMode = CAN_FILTERMODE_IDLIST;
CAN_FilterType.FilterScale = CAN_FILTERSCALE_32BIT;
CAN_FilterType.FilterActivation = ENABLE;
HAL_CAN_ConfigFilter(&hcan1, &CAN_FilterType);

// 配置过滤器组1,接收ID 0x426,存入FIFO1
CAN_FilterType.FilterBank = 1;
EXT_ID_TO_CAN_FILTER(0x426, CAN_FilterType.FilterIdHigh, CAN_FilterType.FilterIdLow);
CAN_FilterType.FilterFIFOAssignment = CAN_RX_FIFO1; // 关联到另一个FIFO
HAL_CAN_ConfigFilter(&hcan1, &CAN_FilterType);

注意:SlaveStartFilterBank 参数在单CAN实例下无意义,在双CAN实例下用于分配过滤器组给CAN2。

四、多滤波器的匹配优先级规则

当一个报文可能匹配多个激活的过滤器时,STM32按照固定的优先级顺序决定其最终归属(存入哪个FIFO,以及获得哪个过滤器编号):

  1. 位宽优先32位 宽度的过滤器优先级高于16位宽度的过滤器。
  2. 模式优先 :位宽相同时,列表模式 的过滤器优先级高于掩码模式的过滤器。
  3. 编号优先 :位宽和模式都相同时,过滤器组编号小的优先级高。

系统会按照此优先级顺序,让报文从高到低尝试匹配过滤器,一旦通过第一个匹配的过滤器,匹配过程即停止,报文被存入该过滤器关联的FIFO。

五、应用场景建议

根据不同的应用需求,可以选择不同的多滤波器配置策略:

  • 汽车电子(多ID,范围过滤) :使用一个32位掩码模式过滤器,通过合理设置ID和掩码,覆盖一个范围内的多个ID(如0x120-0x12F),效率最高,且便于扩展。
  • 工业控制(安全,精准过滤) :使用多个32位列表模式过滤器,每个过滤器精确匹配1个或2个关键ID(如急停指令、安全门状态),确保无关报文被绝对屏蔽。
  • 混合通信(标准ID与扩展ID共存):可以分配不同的过滤器组,分别用掩码模式处理一组标准ID,用列表模式处理特定的扩展ID。

总结 :在STM32上设置多个CAN滤波器的核心是合理规划有限的过滤器组资源,根据ID的数量、特征和接收的严格性,选择列表模式或掩码模式,并正确配置标识符、掩码及FIFO关联。理解匹配优先级规则对于复杂配置下的行为预测至关重要。配置完成后,需启用相应的接收中断(如 CAN_IT_RX_FIFO0_MSG_PENDING)并在回调函数中处理数据。

相关推荐
秀秀更健康13 小时前
stm32: 系统时钟如何配置为72Mhz
stm32·单片机·嵌入式硬件
归零鸟18 小时前
WD Elements移动硬盘能识别出盘但不能出盘的修复记录
stm32·单片机·嵌入式硬件
追兮兮19 小时前
MCUQuickStart v1.1.0发布,一键生成Keil工程+RTOS模板
stm32·单片机·嵌入式硬件·freertos·gd32·keil5
rit843249919 小时前
STM32移植NES模拟器指南
stm32·单片机·嵌入式硬件
都在酒里19 小时前
STM32 I2C通信协议详解——标准库函数实现(通讯协议总结一)
stm32·嵌入式硬件·i2c
fengfuyao98520 小时前
STM32 HAL库实现串口DMA接收不定长数据
stm32·单片机·嵌入式硬件
yuan1999720 小时前
STM32直流无刷电机六拍方波控制器程序
stm32·单片机·嵌入式硬件
番茄灭世神21 小时前
PN学堂GD32教程第21篇——WiFiIOT
c语言·stm32·单片机·嵌入式·gd32
2zcode1 天前
基于STM32的直流电机串级PID伺服控制系统设计与实现
stm32·单片机·嵌入式硬件·直流电机
都在酒里1 天前
STM32低功耗休眠详解——睡眠、停止与待机模式实战,综合应用(三)
stm32·单片机·嵌入式硬件