打印
[研电赛技术支持]

GD32F103 CAN过滤器使用

[复制链接]
1093|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
CAN 过滤器的基本概念
​ CAN(Controller Area Network)过滤器是 CAN 控制器中的一个重要组件。其主要功能是对接收到的 CAN 消息进行筛选,决定哪些消息可以通过并被接收处理,哪些消息应该被过滤掉。这有助于减少不必要的消息干扰,提高系统对关键信息的处理效率。

​ CAN 消息都带有一个唯一的标识符(ID),过滤器通过比较 CAN 消息的 ID 与预设的过滤规则来实现消息筛选。例如,在一个汽车电子系统中,众多的电子控制单元(ECU)通过 CAN 总线进行通信,过滤器可以用于让发动机控制单元只接收与发动机相关的 CAN 消息,而忽略其他如座椅调节等无关消息。

​ GD32F103 每一个过滤器单元有2个寄存器CAN_FxDATA0和CAN_ FxDATA1,它们可以配置为2种位宽:

32-bit位宽和16-bit位宽. 32-bit位宽CAN_FDATA包含字段:SFID[10:0],EFID[17:0],FF和FT。



16-bit位宽CAN_FDATA包含字段:SFID[10:0],FT,FF和EFID[17:15]。



CAN 过滤器的工作模式介绍
掩码模式(Mask Mode)
​ 在掩码模式下,过滤器使用一个掩码(Mask)值和一个标识符(ID)值来进行消息过滤。掩码用于指定消息 ID 中哪些位需要精确匹配,哪些位可以有一定的灵活性。例如,掩码为0xFFFF表示所有位都需要精确匹配,而掩码为0xFF00则表示低 8 位可以有变化,只有高 8 位需要精确匹配过滤器设置的标识符部分。

​ 32 位掩码模式下,CAN_FxDATA0 和 CAN_FxDATA1 协同工作来实现灵活的消息过滤。CAN_FxDATA0 存储完整的 32 位期望匹配的 ID,这个 ID 是一个参考标准。CAN_FxDATA1 作为 32 位掩码,每一位对应 CAN 消息标识符(ID)中的一位,用于确定该位是否需要精确匹配。

​ 16 位掩码模式下,CAN_FxDATA0 的存储方式有所不同。它的高 16 位用于存储期望匹配的 ID 部分,低 16 位则充当掩码。这种模式下,对于消息 ID 的高 16 位,根据存储在 CAN_FxDATA0 高 16 位的值和低 16 位掩码(即 CAN_FxDATA0 本身)来判断是否匹配。



列表模式(List Mode)
​ 列表模式会维护一个可以接收的 CAN 消息 ID 列表。当一个 CAN 消息到达时,过滤器会将消息的 ID 与这个列表中的 ID 逐一进行比较。如果消息 ID 与列表中的某个 ID 完全匹配,那么这个消息就会通过过滤器被接收;否则,消息将被过滤掉。

​ 32 位列表模式下 CAN_FxDATA0 和 CAN_FxDATA1 表示过滤的ID,16位列表模式则可以过滤4个ID



#define FIFLTER_ID_1 0x01      
#define FIFLTER_ID_2 0x02     
#define FIFLTER_ID_3 0x03     
#define FIFLTER_ID_4 0x04     

void CAN_Filter_Config(uint16_t filterIdHigh, uint16_t filterIdLow, uint16_t filterMaskHigh, uint16_t filterMaskLow)
{
    can_filter_parameter_struct can_filter;
    can_struct_para_init(CAN_FILTER_STRUCT, &can_filter);

    can_filter.filter_number = 0; // 过滤器0       //
    /* initialize filter */
    can_filter.filter_mode = CAN_FILTERMODE_LIST;  //
    can_filter.filter_bits = CAN_FILTERBITS_16BIT; //
    can_filter.filter_list_high = filterIdHigh;    //
    can_filter.filter_list_low = filterIdLow;
    can_filter.filter_mask_high = filterMaskHigh;
    can_filter.filter_mask_low = filterMaskLow;
    can_filter.filter_fifo_number = CAN_FIFO0;
    can_filter.filter_enable = ENABLE;
    can_filter_init(&can_filter);
}

CAN_Filter_Config(FIFLTER_ID_1 << 5, FIFLTER_ID_2 << 5, FIFLTER_ID_3 << 5, FIFLTER_ID_4 << 5);
————————————————

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

原文链接:https://blog.csdn.net/pigliuxu/article/details/144457468

使用特权

评论回复
沙发
tpgf| | 2025-3-4 09:38 | 只看该作者
#include "gd32f10x.h"
#include "gd32f10x_can.h"

void can_filter_config(void) {
    can_filter_parameter_struct filter;
   
    // 初始化CAN控制器
    can_init_para init_struct;
    init_struct.working_mode = CAN_NORMAL_MODE;
    init_struct.resync_jump_width = CAN_BT_SJW_1TQ;
    init_struct.time_segment_1 = CAN_BT_BS1_5TQ;
    init_struct.time_segment_2 = CAN_BT_BS2_4TQ;
    init_struct.prescaler = 12; // 假设系统时钟为72MHz,波特率为500kbps
    can_init(&amp;init_struct);
   
    // 配置过滤器
    filter.filter_mode = CAN_FILTERMODE_MASK; // 选择掩码模式
    filter.filter_bits = CAN_FILTERBITS_32BIT; // 32位标识符
    filter.filter_list_high = 0x5FF << 5; // 设置高16位标识符
    filter.filter_list_low = 0x0000; // 设置低16位标识符(此处未使用)
    filter.filter_mask_high = (0x700 << 5); // 设置高16位掩码
    filter.filter_mask_low = (1U << 2); // 设置低16位掩码(仅关注高两位)
    filter.filter_fifo_number = CAN_FIFO1; // 指定接收FIFO
    filter.filter_enable = ENABLE; // 启用过滤器
   
    // 初始化过滤器
    can_filter_init(&amp;filter);
}

使用特权

评论回复
板凳
磨砂| | 2025-3-4 19:11 | 只看该作者
GD32F103的CAN过滤器总共有28个,通过过滤器控制寄存器(CAN_FCTL)打开或关闭

使用特权

评论回复
地板
晓伍| | 2025-3-4 21:00 | 只看该作者
配置CAN的波特率,这通常涉及到设置CAN的预分频器、时间段1和时间段2等参数

使用特权

评论回复
5
八层楼| | 2025-3-4 22:49 | 只看该作者
运行模式有三种。连续模式,当计数值超过周期寄存器中设置的值时,会回滚到零;单次可重触发模式,在重置事件发生时开始计数,并在达到周期值时停止,在此模式下用户可以随时重置;单次不可重触发模式,与单次可重触发模式原理相同,但如果在计数阶段结束之前发生重置事件,则会忽略这些事件

使用特权

评论回复
6
观海| | 2025-3-5 18:38 | 只看该作者
如果需要使用中断方式接收CAN数据,还需要配置中断优先级并使能相应的中断

使用特权

评论回复
7
guanjiaer| | 2025-3-5 20:27 | 只看该作者
GD32F103系列中的不同型号可能具有不同数量的CAN过滤器和其他资源限制

使用特权

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

本版积分规则

27

主题

90

帖子

0

粉丝