打印
[STM32F4]

STM32F4系列单片机CAN过滤器和屏蔽器的配置

[复制链接]
1020|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
STM32单片机的CAN总线通讯,最难理解的地方就是过滤器和屏蔽器的配置。
最简单的配置:
void HAL_CAN1_Filter_Config(void)
{
CAN_FilterTypeDef CAN_FilterStructure;
CAN_FilterStructure.FilterActivation = ENABLE;
CAN_FilterStructure.FilterBank = 1;
CAN_FilterStructure.FilterMode = CAN_FILTERMODE_IDMASK;
CAN_FilterStructure.FilterScale = CAN_FILTERSCALE_32BIT;
CAN_FilterStructure.FilterFIFOAssignment = CAN_FILTER_FIFO0;
CAN_FilterStructure.FilterIdHigh = 0x0000;
CAN_FilterStructure.FilterIdLow = 0x0000;
CAN_FilterStructure.FilterMaskIdHigh = 0x0000;
CAN_FilterStructure.FilterMaskIdLow = 0x0000;
HAL_CAN_ConfigFilter(&hcan1,&CAN_FilterStructure);
}
解释:
FilterBank = 1,使用第1组屏蔽器和过滤器, 过滤器 F1R1(32bit),屏蔽器F1R2(32bit)
FilterIdHigh : F1R1(31-16bit) 高16位 ,包括 : STID10-STID0, EXID17-EXID13
FilterIdLow : F1R1(15-0bit) 低16位 ,EXID11-EXID0,IDE,RTR,0
FilterMaskIdHigh : F1R2(31-16bit)的 高16位
FilterMaskIdLow : F1R2(15-0bit) 的 低16位
帧格式:标准帧,帧类型:数据帧,帧ID:0x0000
屏蔽器设置:全部不屏蔽
按照上面的设置,上位机发送的数据包,只要波特率符合,全部都能接收,总线上的每个节点都会接收到同样的信息,这样就失去了CAN总线通讯的优势,与485通讯没有太大区别。合理设置过滤器和屏蔽器,不是发给本节点的信息,会被硬件屏蔽掉,软件根本“不知道”有信息发过来,只有确实发给本节点的信息,软件才能收到,提高了软件的效率。

使用特权

评论回复
沙发
等你下课|  楼主 | 2022-4-30 23:46 | 只看该作者
过滤器如何配置呢?看一下CAN过滤器完整的位图:

使用特权

评论回复
板凳
等你下课|  楼主 | 2022-4-30 23:46 | 只看该作者

使用特权

评论回复
地板
等你下课|  楼主 | 2022-4-30 23:47 | 只看该作者
过滤器为32位,帧ID位于bit31-bit21共11位,因此,已知本节点过滤器ID为FilterId,左移21位给寄存器F1R1,这样做是正确的,但是,HAL库把过滤器分成两个16位寄存器来配置,FilterIdHigh包括 F1R1的bit31-bit16, 因此, FilterId左移5位给 FilterIdHigh :
CAN_FilterStructure.FilterIdHigh = FilterId<<5;
F1R1的低16位CAN_FilterStructure.FilterIdLow包含扩展帧ID、IDE和RTR位,不使用扩展帧,IDE=0,接收数据帧RTR也=0, CAN_FilterStructure.FilterIdLow = 0;
再看屏蔽器的配置,屏蔽器的作用就是“告诉”过滤器在接收信息的时候,过滤器ID哪些位必须匹配,哪些位可以不匹配,凡是屏蔽器的位为1,相对应的过滤器的位就必须与接收信息包含的帧ID位相匹配,不匹配就不接收。相反,凡是屏蔽器的位为0,过滤器对应的位就不关心,因此,如果FilterMaskIdHigh 和 FilterMaskIdLow 都为0, 所有的信息都会全部接收,如果FilterMaskIdHigh 和 FilterMaskIdLow 都为0xFFFF, 只有与过滤器ID完全匹配的信息才接收。
在实际的信息接收过程中,我们既要接收数据帧,也要接收遥控帧(也叫远程帧),遥控帧用于发送不带数据的命令,RTR位也要匹配,过滤器低16位应为 :
CAN_FilterStructure.FilterIdLow = 0 | CAN_RTR_REMOTE;
屏蔽器的RTR位要为0,才能保证过滤器ID的RTR位不管为0或1都能接收,必须CAN_FilterStructure.FilterMaskIdLow = 0xFFFD;

使用特权

评论回复
5
等你下课|  楼主 | 2022-4-30 23:47 | 只看该作者
完整的配置代码:
void HAL_CAN1_Filter_Config(void)
{
CAN_FilterTypeDef CAN_FilterStructure;
unsigned int FilterId = 0x0B; // 帧ID举例
CAN_FilterStructure.FilterActivation = ENABLE;
CAN_FilterStructure.FilterBank = 1;
CAN_FilterStructure.FilterMode = CAN_FILTERMODE_IDMASK;
CAN_FilterStructure.FilterScale = CAN_FILTERSCALE_32BIT;
CAN_FilterStructure.FilterFIFOAssignment = CAN_FILTER_FIFO0;
CAN_FilterStructure.FilterIdHigh = FilterId<<5;
CAN_FilterStructure.FilterIdLow = 0x0000|CAN_RTR_REMOTE;
CAN_FilterStructure.FilterMaskIdHigh = 0xFFFF;
CAN_FilterStructure.FilterMaskIdLow = 0xFFFD;
HAL_CAN_ConfigFilter(&hcan1,&CAN_FilterStructure);
}、

使用特权

评论回复
6
等你下课|  楼主 | 2022-4-30 23:48 | 只看该作者
巧用遥控帧:
遥控帧发送的时候,DLC是无用的,但依然会发送出去,当我们发送遥控帧的时候,把不同的命令DLC赋不同的值,接收的时候,只要识别DLC的值就能知道接收的命令是什么,这样就能快速的传递命令,当然,发送端和接收端需事先约定好。

使用特权

评论回复
7
Pulitzer| | 2022-10-7 07:05 | 只看该作者

大部分单片机都带有加密锁定位或者加密字节

使用特权

评论回复
8
Uriah| | 2022-10-7 14:06 | 只看该作者

大部分能够读取或者识别Flash上的数据就能够获得Firmware文件

使用特权

评论回复
9
Bblythe| | 2022-10-7 17:05 | 只看该作者

如果在编程时加密锁定位被使能/锁定,就无法用普通编程器直接读取单片机内的程序

使用特权

评论回复
10
Pulitzer| | 2023-6-1 07:05 | 只看该作者

输出了5个频率为10KHz的PWM脉冲

使用特权

评论回复
11
公羊子丹| | 2023-6-1 08:08 | 只看该作者

使能主从模式,触发事件选择为更新事件,不需要开启中断。

使用特权

评论回复
12
公羊子丹| | 2023-6-1 09:01 | 只看该作者

从定时器为TIM2,从模式选择为门控模式,触发源选择ITR0,开启定时器2中断。

使用特权

评论回复
13
Wordsworth| | 2023-6-1 10:04 | 只看该作者

根据实际需求选择用哪种方式

使用特权

评论回复
14
Clyde011| | 2023-6-1 11:07 | 只看该作者

主定时器为TIM1,通道2配置为PWM输出

使用特权

评论回复
15
万图| | 2023-6-1 13:03 | 只看该作者

主从定时的方式占用CPU资源少

使用特权

评论回复
16
Uriah| | 2023-6-1 14:06 | 只看该作者

主从定时器门控的方式

使用特权

评论回复
17
帛灿灿| | 2023-6-1 16:02 | 只看该作者

中断计数的方式实现简

使用特权

评论回复
18
Bblythe| | 2023-6-1 17:05 | 只看该作者

当PWM频率较高时,频繁的中断将影响程序运行的效率

使用特权

评论回复
19
童雨竹| | 2023-6-1 19:01 | 只看该作者

都可以产生指定个数的PWM脉冲

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

389

帖子

0

粉丝