目录
一、问题描述
STM32G491滤波器设置
本例子分别设置两个滤波器,其滤波器的ACR和MCR分别如下:
其中,MCR中的1表示ACR对应的位必须相等,MCR的0表示ACR对应的位可以不等。
二、滤波器相关代码
/* FDCAN1 init function */
void MX_FDCAN1_Init(void)
{
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1; //时钟分频器
hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC; //用于设置CAN帧格式
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL; //用于设置CAN操作模式
hfdcan1.Init.AutoRetransmission = ENABLE; //开启自动重传!
hfdcan1.Init.TransmitPause = DISABLE; //关闭传输暂停
hfdcan1.Init.ProtocolException = DISABLE; //关闭协议异常处理
hfdcan1.Init.NominalPrescaler = 2; //用于CAN FD仲裁阶段分频设置,产生标称位时间量,参数范围1-512
hfdcan1.Init.NominalSyncJumpWidth = 1; //设置FD CAN仲裁阶段最大支持的时间量来加长或者缩短一个bit来实现再同步,参数范围1-128
hfdcan1.Init.NominalTimeSeg1 = 8; //设置仲裁阶段Bit Segment 1的时间量,范围2 – 256。
hfdcan1.Init.NominalTimeSeg2 = 7; //设置仲裁阶段Bit Segment 2的时间量,范围2 – 128。
hfdcan1.Init.DataPrescaler = 1; //用于CAN FD数据阶段分频设置,范围1-32
hfdcan1.Init.DataSyncJumpWidth = 1; //设置FD CAN数据阶段最大支持的时间量来加长或者缩短一个bit来实现数据再同步,参数范围1-16
hfdcan1.Init.DataTimeSeg1 = 1; //设置数据阶段Data Bit Segment 1的时间量,范围1 – 32
hfdcan1.Init.DataTimeSeg2 = 1; //设置数据阶段Data Bit Segment 2的时间量,范围1 – 16
hfdcan1.Init.StdFiltersNbr = 0; //标准信息ID滤波器个数
hfdcan1.Init.ExtFiltersNbr = 2; //扩展信息ID滤波器个数
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; //发送FIFO序列模式
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK) //初始化FDCAN
{
Error_Handler();
}
FDCAN_FilterTypeDef FDCAN1_RXFilter;
//配置数据帧滤波器
FDCAN1_RXFilter.IdType=FDCAN_EXTENDED_ID; // 设置标准ID或者扩展ID
FDCAN1_RXFilter.FilterIndex=0; //用于过滤索引,如果是标准ID,范围0到127。如果是扩展ID,范围0到64
FDCAN1_RXFilter.FilterType=FDCAN_FILTER_MASK; //过滤器采样屏蔽位模式
FDCAN1_RXFilter.FilterConfig=FDCAN_FILTER_TO_RXFIFO0; //如果过滤匹配,将数据保存到Rx FIFO 0
FDCAN1_RXFilter.FilterID1=ext_id_data_ACR; // 屏蔽位模式下,FilterID1是消息ID
FDCAN1_RXFilter.FilterID2=ext_id_data_MCR; //屏蔽位模式下,FilterID2是消息屏蔽位
if(HAL_FDCAN_ConfigFilter(&hfdcan1, &FDCAN1_RXFilter)!= HAL_OK)
{
Error_Handler();
}
//配置广播帧滤波器
FDCAN1_RXFilter.IdType=FDCAN_EXTENDED_ID; //扩展ID
FDCAN1_RXFilter.FilterIndex=1; //滤波器索引
FDCAN1_RXFilter.FilterType=FDCAN_FILTER_MASK; //滤波器类型
FDCAN1_RXFilter.FilterConfig=FDCAN_FILTER_TO_RXFIFO0; //过滤器0关联到FIFO0
FDCAN1_RXFilter.FilterID1=ext_id_radio_ACR; //32位ID
FDCAN1_RXFilter.FilterID2=ext_id_radio_MCR; //如果FDCAN配置为传统模式的话,这里是32位掩码
if(HAL_FDCAN_ConfigFilter(&hfdcan1, &FDCAN1_RXFilter)!= HAL_OK) //滤波器初始化
{
Error_Handler();
}
/* Configure global filter:下面这一句是配置全局滤波器配置寄存器的,一定要写,否则配置了也没用
Filter all remote frames with STD and EXT ID
Reject non matching frames with STD ID and EXT ID */
if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
{
Error_Handler();
}
HAL_FDCAN_Start(&hfdcan1); //开启FDCAN
HAL_FDCAN_ActivateNotification(&hfdcan1,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0); //激活RX FIFO0的NEW_MESSAGE通知中断
}
三、验证滤波器是否配置正确
如下图,在CAN接收中断中,将接收缓存的内容在中断中发送出去,相当于接收什么发送什么。分别选择可通过ID和不可通过ID,测试是否可以通过滤波器。
000 101 0011 0 00001000 101 0011 000000 0x14C114C0 可通过ID
000 101 0111 0 00000000 101 0011 000000 0x15C014C0 不可通过ID
如果配置正确,使用CAN盒分别发送0x14C114C0和0x15C014C0,只有0x14C114C0的ID有返回数据。
本人水平有限,如有不足之处,欢迎批评指正。
参考文章:
【STM32H7教程】第91章 STM32H7的FDCAN总线基础知识和HAL库API_硬汉eric2013的博客-CSDN博客