GD32F103 CAN过滤器使用
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,EFID,FF和FT。
16-bit位宽CAN_FDATA包含字段:SFID,FT,FF和EFID。
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
#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(&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(&filter);
}
GD32F103的CAN过滤器总共有28个,通过过滤器控制寄存器(CAN_FCTL)打开或关闭
配置CAN的波特率,这通常涉及到设置CAN的预分频器、时间段1和时间段2等参数
运行模式有三种。连续模式,当计数值超过周期寄存器中设置的值时,会回滚到零;单次可重触发模式,在重置事件发生时开始计数,并在达到周期值时停止,在此模式下用户可以随时重置;单次不可重触发模式,与单次可重触发模式原理相同,但如果在计数阶段结束之前发生重置事件,则会忽略这些事件
如果需要使用中断方式接收CAN数据,还需要配置中断优先级并使能相应的中断
GD32F103系列中的不同型号可能具有不同数量的CAN过滤器和其他资源限制
页:
[1]