应用笔记 · 2024年1月27日

GD32 CAN滤波器详解

1、CAN简介

CAN(Controller Area Network)总线是一种可以在无主机情况下实现微处理器或者设备之间
相互通信的总线标准。
CAN 总线控制器作为 CAN 网络接口,遵循 CAN 总线协议 2.0A 和 2.0B。 CAN 总线控制器可
以处理总线上的数据收发并具有 28 个过滤器, 过滤器用于筛选并接收用户需要的消息。 用户
可以通过 3 个发送邮箱将待发送数据传输至总线, 邮箱发送的顺序由发送调度器决定。并通过
2 个深度为 3 的接收 FIFO 获取总线上的数据,接收 FIFO 的管理完全由硬件控制。 同时 CAN
总线控制器硬件支持时间触发通信(Time-trigger communication) 功能。

2、CAN掩码模式下滤波器设置

2.1标准帧滤波器分析

一个待接收的数据帧会根据其标识符(Identifier)进行过滤:硬件会将通过过滤的帧送至接收FIFO, 并丢弃没有通过过滤器的帧。标准帧ID为11位(0x000-0x7FF),假设在32位掩码模式下,标准帧的过滤功能原理如下(基于GD32标准固件库):按图4原理要求,预设标识符(list_high和list_low:0x05FF 0000)左移5位后被填写进FxDATA0寄存器中,掩码(0xE000 0004)被填入FxDATA1中,通过过滤器0后绑定到FIFO1。即高16位0x5FF左移5位后填进FxDATA0高16位(0xBFE0),故FxDATA0[31:21]位是:1011 1111 111;同理,32位掩码高16位0x700左移5位, FxDATA1[31:21]位是:1110 0000 000;因此对于CAN接收的标准帧ID的第11位,第10位,第9位满足101即可通过该滤波器被CAN FIFO1接收.

因此0x500-0x5FF均可通过该滤波器,配置代码已附注,滤波器0的寄存器值如图5。区别于扩展帧,标准帧仅需关注SFID[10:0]即可。

图1 32-bit 位宽掩码模式过滤器

/* initialize filter */

can_filter.filter_mode = CAN_FILTERMODE_MASK;

can_filter.filter_bits = CAN_FILTERBITS_32BIT;

can_filter.filter_list_high = 0x5FF<<5;

can_filter.filter_list_low = 0x0000;

can_filter.filter_mask_high = (0x700 << 5) ;

can_filter.filter_mask_low = (1U << 2);

can_filter.filter_fifo_number=CAN_FIFO1;

can_filter.filter_enable = ENABLE;

can_filter_init(&can_filter);

注:在标准帧掩码模式下,FF为要置1,即“can_filter.filter_mask_low = (1U << 2);”

图2 滤波器0的寄存器值

2.2扩展帧滤波器分析

扩展帧ID为29位(0x0000 0000-0x1FFF FFFF),假设在32位掩码模式下,扩展帧的过滤功能原理如下(基于GD标准固件库):按图4原理要求,预设标识符(list_high和list_low:0x501E 0004)被填写进FxDATA0寄存器中,掩码(0xFFFF FF84)被填入FxDATA1中,通过过滤器0后绑定到FIFO1。需注意,扩展帧需要匹配SFID[10:0]和EFID[17:0]。故 FxDATA0[31:3]位是:0101 0000 0001 1110 0000 0000 0000 0;同理, FxDATA1[31:3]位是:1111 1111 1111 1111 1111 1111 1111 0。

因此对于CAN接收的扩展帧ID的前28位必须满足0 1010 0000 0011 1100 0000 0000,第29位不关注,满足该条件即可通过该滤波器被CAN FIFO1接收,即0x0a03c000-0x0a03c00f均可通过该滤波器,配置代码已附注,滤波器0的寄存器值如图6,扩展帧匹配需关注SFID[10:0]+EFID[17:0]。

can_filter.filter_mode = CAN_FILTERMODE_MASK;

can_filter.filter_bits = CAN_FILTERBITS_32BIT;

can_filter.filter_list_high =(uint16_t)(0x0a03c000 >> 13);

can_filter.filter_list_low = (uint16_t)(((uint16_t)0x0a03c000<<3)|(1U<< 2));

can_filter.filter_mask_high =(uint16_t)(0x1ffffff0>>13);

can_filter.filter_mask_low =(uint16_t)(((uint16_t)0x1ffffff0<<3)|(1U << 2));

can_filter.filter_fifo_number = CAN_FIFO1;

can_filter.filter_enable = ENABLE;

can_filter_init(&can_filter);

图3滤波器0的寄存器值

注:在扩展帧掩码模式下,FF为要置1,即“can_filter.filter_mask_low = (1U << 2);对应的FxDATA0位也要置1,详情参见代码。

3、CAN列表模式滤波器设置

3.1标准帧滤波器分析

在32位列表模式下,标准帧的过滤功能原理如下(基于GD标准固件库):按图7原理要求,预设标识符1(list_high和list_low:0x04C6 0000)左移5位后被填写进FxDATA0寄存器中,预设标识符2(Msak_high和Mask_low:0x0700 0000)被填入FxDATA1中,通过过滤器0后绑定到FIFO1。故 FxDATA0[31:21]位是:1001 1000 110(0x4C6);同理, FxDATA1[31:21]位是:1110 0000 000(0x700)。

因此对于CAN接收的标准帧ID是预设标识符1(0x4C6)或者预设标识符2(0x700)即可通过该滤波器被CAN FIFO1接收,配置代码已附注。区别于扩展帧,标准帧仅需关注SFID[10:0]即可

图4 32-bit 位宽列表模式过滤器

can_filter.filter_mode = CAN_FILTERMODE_LIST;

can_filter.filter_bits = CAN_FILTERBITS_32BIT;

can_filter.filter_list_high =0x4C6 << 5;

can_filter.filter_list_low =0x0000;

can_filter.filter_mask_high =0x700 << 5;

can_filter.filter_mask_low =0x0000;

can_filter.filter_fifo_number = CAN_FIFO1;

can_filter.filter_enable = ENABLE;

can_filter_init(&can_filter);

3.2扩展帧滤波器分析

在32位列表模式下,扩展帧的过滤功能原理如下(基于GD标准固件库):按图7原理要求,预设标识符1(list_high和list_low:0x0CF0 0400)右移13位后取高16位,左移3位后取低16位,填写进FxDATA0寄存器中,预设标识符2(Msak_high和Mask_low: 0x18FE E900)被填入FxDATA1中,通过过滤器0后绑定到FIFO0。故 FxDATA0[31:3]位是:0110 0111 1000 0000 0010 0000 0000 0 (0x0CF0 0400);同理, FxDATA1[31:21]位是:0001 1000 1111 1110 1110 1001 0000 0 (0x18FE E900)。

因此对于CAN接收的扩展帧ID是预设标识符1(0x0CF0 0400)或者预设标识符2(0x18FE E900)即可通过该滤波器被CAN FIFO1接收,配置代码已附注。扩展帧匹配需关注SFID[10:0]+EFID[17:0]。

can_filter.filter_mode = CAN_FILTERMODE_LIST;

can_filter.filter_bits = CAN_FILTERBITS_32BIT;

can_filter.filter_list_high =(uint16_t)(0x0CF00400 >> 13);

can_filter.filter_list_low =(uint16_t)(((uint16_t)0x0CF00400 << 3) | (1U << 2));

can_filter.filter_mask_high =(uint16_t)(0x18FEE900 >> 13);

can_filter.filter_mask_low =(uint16_t)(((uint16_t)0x18FEE900 << 3) | (1U << 2));

can_filter.filter_fifo_number = CAN_FIFO1;

can_filter.filter_enable = ENABLE;

can_filter_init(&can_filter);

4、16位CAN列表模式滤波器设置和掩码模式原理和32位一致,不再赘述,对于16位掩码模式可通过4组符合条件的帧ID,16位列表模式可通过4个符合条件的帧ID,此外如果客户想要绑定多个滤波器,可以将配置过程封装成一个函数。
————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/weixin_43530677/article/details/129911561