本帖最后由 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等,具体细节差异欢迎留言或私信。
|