CAN过滤器基础知识

编程入门 行业动态 更新时间:2024-10-26 18:29:51

CAN<a href=https://www.elefans.com/category/jswz/34/1771166.html style=过滤器基础知识"/>

CAN过滤器基础知识

文章目录

    • 过滤器
    • 过滤器的过滤模式
    • 掩码(不常用掩码模式)
    • CAN的双接收中断
    • 使用CAN2过滤ID号(实验)
    • 参考资料

过滤器

  • STM32的bxCAN接收时必须使用过滤器接收
  • 根据CAN外设数量的不同有以下情况:
    • 只有CAN1:CAN1有14个过滤器
    • 有CAN1和CAN2:CAN1和CAN2共享28个过滤器
    • 有CAN1~3:CAN1和CAN2共享28个过滤器,CAN3有独立的14个过滤器
  • 过滤器可以过滤CAN总线上帧的ID号
    • 可以不处理不想接收的ID号,只接收想要的ID号

过滤器的过滤模式

  • 过滤器总长度64位,可以分为2个32位单元或4个16位单元
  • 两种过滤模式:掩码和列表
    • 掩码模式:由两个单元组成通过掩码匹配
    • 列表模式:由一个单元组成,ID号完全匹配即通过
  • ID号对齐最高位(MSB)
  • 仅32位单元可以过滤拓展ID
  • 在列表模式下,scale为32时,每个过滤器的列表只能写入两个报文ID,若scale为16时,每个过滤器的列表最多可写入4个CAN ID

掩码(不常用掩码模式)

  • 两个单元分别组成匹配ID和掩码(MASK)

  • 被过滤的ID号和匹配ID号会和掩码进行按位与运算后再进行匹配

    • 也就是只有对应的掩码为1的位才会被匹配
  • 例如:

    • 匹配ID为0x200,掩码为0x000,则所有ID号都能通过
    • 匹配ID为0x200,掩码为0x700,则ID为0x200~0x2FF均可通过
    • 匹配ID为0x200,掩码为0x7FF,则只有0x200能通过
  • 可以指定一个ID号的范围,在这个范围内的ID号可以通过我们的过滤器

    过滤器一共有4种工作模式:

    32位宽的掩码模式,  配置过滤2个不同的ID号
    32位宽的列表模式,  配置过滤4个不同的ID号
    16位宽的列表模式,  配置过滤2个不同的ID号
    16位宽的掩码模式    配置过滤1个不同的ID号
    

    过滤器的位宽:

    16位过滤器
    32位过滤器
    

CAN的双接收中断

  • 每个CAN有两个接收中断,对应两组接收邮箱(FIFO)
  • 每个过滤器可以绑定一个CAN接收中断
  • 经过过滤器过滤的帧会进入该过滤器绑定的接收中断对应的邮箱
  • 匹配时,列表模式的优先级高于掩码模式,其次过滤器编号更小的优先级更高

使用CAN2过滤ID号(实验)

  • CAN1给CAN2发送不同ID号的数据帧
  • CAN2使用过滤器进行过滤
  • RX0和RX1分别对应不同过滤器,接收到不同数组中

在之前CAN实验的代码上修改

这里我们只需要修改CAN2,把CAN_Configfilter()函数中的sFiterconfig拷贝下来

覆盖掉之前的sFiterconfig.FilterBank

  sFiterconfig.FilterActivation = CAN_FILTER_ENABLE;//激活过滤器sFiterconfig.FilterBank=0;//过滤器编号,CAN1是0~13sFiterconfig.FilterFIFOAssignment=CAN_FILTER_FIFO0;sFiterconfig.FilterMode=CAN_FILTERMODE_IDMASK;//设置为掩码模式sFiterconfig.FilterScale=CAN_FILTERSCALE_32BIT;//设置为32位宽sFiterconfig.FilterIdHigh=0x0000;//设置验证码sFiterconfig.FilterIdLow=0x0000;sFiterconfig.FilterMaskIdHigh=0x0000;sFiterconfig.FilterMaskIdLow=0x0000;sFiterconfig.SlaveStartFilterBank=14;
  1. 列表模式

    绑定FIFO0
    把下面的FilterBank设置为14,FilterMode改为CAN_FILTERMODE_IDLIST,FilterScale改为CAN_FILTERSCALE_16BIT,下面的ID号改为我们需要的ID号,这里我们可以设为0x200左移5位(左移5是为了对齐msb)

  sFiterconfig.FilterActivation = CAN_FILTER_ENABLE;sFiterconfig.FilterBank=14;//过滤器编号,CAN2是14~27sFiterconfig.FilterFIFOAssignment=CAN_FILTER_FIFO0;//接收到的报文放入到FIFO0中sFiterconfig.FilterMode=CAN_FILTERMODE_IDLIST;//列表模式sFiterconfig.FilterScale=CAN_FILTERSCALE_32BIT;//设置32位宽sFiterconfig.FilterIdHigh=0x200<<5;//基本ID放入到STID中  sFiterconfig.FilterIdLow=0x201<<5;sFiterconfig.FilterMaskIdHigh=0x202<<5;//设置为0时,表示不过滤,可以接收任意的CANID数据,sFiterconfig.FilterMaskIdLow=0x203<<5;//不为0时,则表示过滤 对应MaskID为1的bit必须与FilterID中的bit位相同的CANID才能接收过来。sFiterconfig.SlaveStartFilterBank=14;
  1. 掩码模式

    绑定FIFO1
    在HAL库中FilterIdHigh,FilterIdLow,FilterMaskIdHigh,FilterMaskIdLow

    FilterBank是过滤器编号,为了避免重复,这里设置为15,FilterMode选择CAN_FILTERMODE_IDMASK,因为我们这里过滤标准帧,没必要使用32位,所以FilterScale选择16位,FilterIdHigh,FilterIdLow在16位模式下指代两个不同的掩码组,FilterIdHigh对应FilterMaskIdHigh,FilterIdLow对应FilterMaskIdLow,一共是两组;如果是32位,就要把他们整个拼成一段整体,因此这里我们需要把它们拼成两组

  sFiterconfig.FilterActivation = CAN_FILTER_ENABLE;sFiterconfig.FilterBank=15;//过滤器编号,CAN2是14~27sFiterconfig.FilterFIFOAssignment=CAN_FILTER_FIFO1;sFiterconfig.FilterMode=CAN_FILTERMODE_IDLIST;sFiterconfig.FilterScale=CAN_FILTERSCALE_16BIT;sFiterconfig.FilterIdHigh=0x200<<5;//ID和掩码都要移5位sFiterconfig.FilterMaskIdHigh=0x202<<5;sFiterconfig.FilterIdLow=0x201<<5;sFiterconfig.FilterMaskIdLow=0x203<<5;sFiterconfig.SlaveStartFilterBank=14;

把FilterMaskIdHigh设置为0x700,这样就表示过滤0x200到0x2FF的ID号

把FilterMaskIdHigh设置为0x7F0,这样就表示过滤0x200到0x20F的ID号

这里我们设置为0x7F0,更方便我们观察现象

然后把FilterFIFOAssignment改为CAN_FILTER_FIFO1,即绑定FIFO1,对应RX1的中断,这样就完成了掩码模式的配置

最终CAN_Configfilter()代码如下:

/* USER CODE BEGIN 4 */
void CAN_Configfilter()
{CAN_FilterTypeDef sFiterconfig;sFiterconfig.FilterActivation = CAN_FILTER_ENABLE;sFiterconfig.FilterBank=0;sFiterconfig.FilterFIFOAssignment=CAN_FILTER_FIFO0;sFiterconfig.FilterMode=CAN_FILTERMODE_IDMASK;sFiterconfig.FilterScale=CAN_FILTERSCALE_32BIT;sFiterconfig.FilterIdHigh=0x0000;sFiterconfig.FilterIdLow=0x0000;sFiterconfig.FilterMaskIdHigh=0x0000;sFiterconfig.FilterMaskIdLow=0x0000;sFiterconfig.SlaveStartFilterBank=14;if( HAL_CAN_ConfigFilter(&hcan1,&sFiterconfig)!=HAL_OK){Error_Handler();}
//列表模式sFiterconfig.FilterActivation = CAN_FILTER_ENABLE;sFiterconfig.FilterBank=14;sFiterconfig.FilterFIFOAssignment=CAN_FILTER_FIFO0;sFiterconfig.FilterMode=CAN_FILTERMODE_IDLIST;sFiterconfig.FilterScale=CAN_FILTERSCALE_16BIT;sFiterconfig.FilterIdHigh=0x200<<5;sFiterconfig.FilterIdLow=0x201<<5;sFiterconfig.FilterMaskIdHigh=0x202<<5;sFiterconfig.FilterMaskIdLow=0x203<<5;sFiterconfig.SlaveStartFilterBank=14;if( HAL_CAN_ConfigFilter(&hcan2,&sFiterconfig)!=HAL_OK){Error_Handler();}//掩码模式sFiterconfig.FilterActivation = CAN_FILTER_ENABLE;sFiterconfig.FilterBank=15;sFiterconfig.FilterFIFOAssignment=CAN_FILTER_FIFO0;sFiterconfig.FilterMode=CAN_FILTERMODE_IDMASK;sFiterconfig.FilterScale=CAN_FILTERSCALE_16BIT;sFiterconfig.FilterIdHigh=0x200<<5;sFiterconfig.FilterIdLow=0x201<<5;sFiterconfig.FilterMaskIdHigh=0x202<<5;sFiterconfig.FilterMaskIdLow=0x203<<5;sFiterconfig.SlaveStartFilterBank=14;if(HAL_CAN_Start(&hcan1)!=HAL_OK){Error_Handler();}if(HAL_CAN_Start(&hcan2)!=HAL_OK){Error_Handler();}if(HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO1_MSG_PENDING)!=HAL_OK){Error_Handler();}if(HAL_CAN_ActivateNotification(&hcan2,CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO1_MSG_PENDING)!=HAL_OK){Error_Handler();}}
void HAL_can_RxFifo0MsgPendingCallback(CAN_HandleTypeDef*hcan)//接收数据的回调函数
{if(hcan==&hcan2){HAL_CAN_GetRxMessage(&hcan2,CAN_RX_FIFO0,&rxHeader0,rxDateBuffer0);}
}//RX0
void HAL_can_RxFifo1MsgPendingCallback(CAN_HandleTypeDef*hcan)//接收数据的回调函数
{if(hcan==&hcan2){HAL_CAN_GetRxMessage(&hcan2,CAN_RX_FIFO1,&rxHeader1,rxDateBuffer1);}
}//RX1
/* USER CODE END 4 */

然后就可以编译烧录。

参考资料

CH4.2 CAN 第2讲 过滤器【南工骁鹰嵌入式软件培训】
STM32 CAN过滤器配置详解
对于can通信过滤器的理解

更多推荐

CAN过滤器基础知识

本文发布于:2024-03-04 02:32:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1708037.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:过滤器   基础知识

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!