打印

GD32 CAN滤波器设置

[复制链接]
892|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 GD32爱好者111 于 2023-4-2 19:25 编辑

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]即可。



图4 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);”



                                               图5 滤波器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);



图6 滤波器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]即可



图7 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,此外如果客户想要绑定多个滤波器,可以将配置过程封装成一个函数。

注:该篇文章滤波器设置适用GD32F10x、GD32F30x、GD32F4xx、GD32E50x等,具体细节差异欢迎留言或私信。

图7.png (146.44 KB )

图7.png

图6.png (50.79 KB )

图6.png

图5.png (57.53 KB )

图5.png

图4.png (129.79 KB )

图4.png

使用特权

评论回复
沙发
daph| | 2023-12-12 14:07 | 只看该作者
楼主好!最近刚接触GD32的CAN滤波功能,请问以上贴出来的配置代码是例程吗?因为在很多地方都看到这部分代码,但是里面结构体的定义却么有找到,不知道哪里可以找到这个例程呢?

使用特权

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

本版积分规则

3

主题

6

帖子

0

粉丝