STM32 HAL库配置CAN滤波代码分享

在STM32上只用CAN,一定离不开滤波器配置,现总结下各种场景下的配置方法及注意事项。

在这里插入图片描述

1、一路CAN有14组滤波器,每组滤波器可关联FIFO0或FIFO1;

2、14组滤波器为或关系,CAN报文通过任一组滤波器即可进入FIFO;

3、每组滤波器可以配置为4种工作模式:

(1) 1个32位屏蔽位模式,用于扩展帧。

    //只接收ID匹配的扩展数据帧
    CAN_FilterTypeDef  stFilterConfig;
    stFilterConfig.FilterBank = 0;
    stFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    stFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
    stFilterConfig.FilterIdHigh = (((uint32_t)Id<<3)&0xFFFF0000)>>16;
    stFilterConfig.FilterIdLow = (((uint32_t)Id<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
    stFilterConfig.FilterMaskIdHigh = (((uint32_t)Mask<<3)&0xFFFF0000)>>16; 
    stFilterConfig.FilterMaskIdLow = (((uint32_t)Mask<<3)|0x06)&0xFFFF;
    stFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
    stFilterConfig.FilterActivation = ENABLE;   //must ENABLE
    stFilterConfig.SlaveStartFilterBank = 14;

(2) 2个32位列表模式,用于扩展帧,2个之间为或关系,若只使用1个,2个可配置相同参数。

   //只接收ID匹配的扩展数据帧
    CAN_FilterTypeDef CAN_FilterType;
    CAN_FilterType.FilterBank = 0;
    CAN_FilterType.FilterIdHigh = (((uint32_t)Id1<<3)&0xFFFF0000)>>16;
    CAN_FilterType.FilterIdLow =  (((uint32_t)Id1<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
    CAN_FilterType.FilterMaskIdHigh = (((uint32_t)Id2<<3)&0xFFFF0000)>>16;
    CAN_FilterType.FilterMaskIdLow = (((uint32_t)Id2<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
    CAN_FilterType.FilterFIFOAssignment = CAN_RX_FIFO0;
    CAN_FilterType.FilterMode = CAN_FILTERMODE_IDLIST;
    CAN_FilterType.FilterScale = CAN_FILTERSCALE_32BIT;
    CAN_FilterType.FilterActivation = ENABLE;
    CAN_FilterType.SlaveStartFilterBank = 14;

(3) 2个16位屏蔽位模式,用于标准帧,2个之间为或关系,若只使用一个,两个可配置相同参数。

   //只接收ID匹配的标准数据帧
    CAN_FilterTypeDef  stFilterConfig;
    stFilterConfig.FilterBank = 0;
    stFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    stFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
    stFilterConfig.FilterIdHigh =(((uint32_t)Id1<<5)|((CAN_ID_STD|CAN_RTR_DATA)<<2))&0xFFFF;
    stFilterConfig.FilterIdLow = (((uint32_t)Id2<<5)|((CAN_ID_STD|CAN_RTR_DATA)<<2))&0xFFFF;
    stFilterConfig.FilterMaskIdHigh = (((uint32_t)Mask1<<5)|(0x06<< 2))&0xFFFF;
    stFilterConfig.FilterMaskIdLow = (((uint32_t)Mask2<<5)|(0x06<<2))&0xFFFF;
    stFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
    stFilterConfig.FilterActivation = ENABLE;   //must ENABLE
    stFilterConfig.SlaveStartFilterBank = 14;

(4) 4个16位列表模式,用于标准帧,4个之间为或关系,若只使用一个,四个可配置相同参数。

    CAN_FilterTypeDef CAN_FilterType;
    CAN_FilterType.FilterBank = 0;
    CAN_FilterType.FilterIdHigh = (Id1 << 5)|(CAN_ID_STD<<1)|(CAN_RTR_DATA << 3);
    CAN_FilterType.FilterIdLow =  (Id2 << 5)|(CAN_ID_STD<<1)|(CAN_RTR_REMOTE << 3);
    CAN_FilterType.FilterMaskIdHigh = (CAN_ID_EXT<<1);//也可以这样配置禁用该组
    CAN_FilterType.FilterMaskIdLow = (CAN_ID_EXT<<1);//也可以这样配置禁用该组
    CAN_FilterType.FilterFIFOAssignment = CAN_RX_FIFO0;
    CAN_FilterType.FilterMode = CAN_FILTERMODE_IDLIST;
    CAN_FilterType.FilterScale = CAN_FILTERSCALE_16BIT;
    CAN_FilterType.FilterActivation = ENABLE;
    CAN_FilterType.SlaveStartFilterBank = 14;

4、即使接收所有CAN报文不需要滤波,也要配置至少一组滤波器;

    CAN_FilterTypeDef CAN_FilterType;
    CAN_FilterType.FilterBank = 0;
    CAN_FilterType.FilterIdHigh = 0;
    CAN_FilterType.FilterIdLow =  0;
    CAN_FilterType.FilterMaskIdHigh = 0;
    CAN_FilterType.FilterMaskIdLow = 0;
    CAN_FilterType.FilterFIFOAssignment = CAN_RX_FIFO0;
    CAN_FilterType.FilterMode = CAN_FILTERMODE_IDMASK;
    CAN_FilterType.FilterScale = CAN_FILTERSCALE_32BIT;
    CAN_FilterType.FilterActivation = ENABLE;
    CAN_FilterType.SlaveStartFilterBank = 14;

##以上代码在STM32F103C8T6上亲测有效,欢迎大家参考反馈;

### STM32 HAL CAN 配置教程 使用 STM32HAL (Hardware Abstraction Layer) 配置 CAN 模块是一个相对复杂的过程,涉及多个步骤和参数设置。以下是关于如何通过 STM32 HAL 实现 CAN 配置的相关说明。 #### 1. 初始化项目环境 为了开始配置 CAN 模块,首先需要创建一个新的 Keil 工程并导入 STM32CubeMX 或其他工具生成的初始化代码。确保在 `FreeRTOSConfig.h` 文件中已经包含了必要的宏定义[^1]。如果未使用 FreeRTOS,则可以跳过此部分。 #### 2. 使用 STM32CubeMX 进行初步配置 STM32CubeMX 是一个强大的图形化工具,用于快速配置微控制器外设。对于 CAN 模块的配置: - 打开 STM32CubeMX 并选择目标 MCU 型号。 - 在 Pinout & Configuration 页面上启用 CAN 外设。 - 设置 CAN 参数,例如波特率、模式(正常/回环)、同步跳跃宽度等。 - 生成代码并将工程导出到 Keil MDK 环境。 这些操作会自动生成基础框架代码以及一些默认函数调用模板。 #### 3. 编写 CAN 初始化代码 下面是基于 HAL 的手动编写 CAN 初始化的一个简单例子: ```c #include "stm32f1xx_hal.h" void MX_CAN_Init(void) { hcan.Instance = CAN1; // 定义 CAN 初始化结构体变量 hcan.Init.Prescaler = 9; /* 波特率为500kbps */ hcan.Init.Mode = CAN_MODE_NORMAL;// 正常模式 hcan.Init.SyncJumpWidth = CAN_SJW_1TQ; hcan.Init.TimeSeg1 = CAN_BS1_13TQ; hcan.Init.TimeSeg2 = CAN_BS2_2TQ; 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(); // 错误处理程序 } } ``` 上述代码片段展示了如何利用 HAL 提供的功能完成基本的硬件抽象层接口设定过程[^2]。 #### 4. 创建过滤器以接收消息 除了初始化之外还需要建立相应的滤波机制以便于筛选特定ID的数据包: ```c static void CAN_Filter_Configuration(void) { CAN_FilterConfTypeDef sFilterConfig; sFilterConfig.FilterBank = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT ; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.SlaveStartFilterBank = 14; HAL_CAN_ConfigFilter(&hcan, &sFilterConfig); } ``` 这段脚本解释了怎样构建标准格式下的接受条件判断逻辑[^3]。 #### 5. 发送与接收数据 最后一步就是实际发送或者读取来自网络上的帧信息了。这里给出两个常用方法作为示范用途——分别对应传输请求命令及其回调响应动作执行情况分析报告功能展示如下所示: ##### 数据发送示例 ```c uint8_t TxData[8]={0}; CAN_TxHeaderTypeDef TxHeader; uint32_t TxMailbox; TxHeader.StdId = 0x321; TxHeader.ExtId = 0; TxHeader.RTR = CAN_RTR_DATA; TxHeader.IDE = CAN_ID_STD; TxHeader.DLC = sizeof(TxData)/sizeof(uint8_t); if(HAL_CAN_AddTxMessage(&hcan,&TxHeader,TxData,&TxMailbox)==HAL_OK){ // Message successfully added to transmit mailbox. }else { // Handle error here... } ``` ##### 接收中断服务子程序 ```c void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *CanHandle) { uint8_t RxData[8]; CAN_RxHeaderTypeDef RxHeader; memset(RxData,0,sizeof(RxData)); if(HAL_CAN_GetRxMessage(CanHandle,CAN_RX_FIFO0,&RxHeader,RxData)==HAL_OK){ // Process received message content inside this block of code. }else{ // Deal with any errors encountered during reception phase accordingly. } } ``` 以上即完成了整个流程概述及相关重要环节的技术要点阐述工作。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值