CAN帧

帧的分类:

  • 数据帧:用于发送单元向接受单元传送数据的帧;
  • 遥控帧(远程帧):用于接收单元向具有相同ID的发送单元请求数据的帧;
  • 错误帧:用于当检测出错误时向其他单元通知错误的帧;
  • 过载帧:用于接收单元通知其尚未做好接受准备的帧;
  •  数据帧结构:

    最常见使用的就是数据帧,下面就详细捋一捋数据帧。

    参考【1】根据CAN2.0的标准知数据帧有标准格式和扩展格式,用来传输数据。
    图片来自文章【1】
    从图上看标准格式与扩展格式的区别只有ID的差距;

      标准格式与扩展格式仲裁段

    图片来自文章【1】
    关于ID:

  • ID的高位在前,低位在后。
  • 基本ID,禁止高7位都为隐性,即不能:ID=1111111XXXX。(参考文章【4】)
  • 标准格式的ID共11位,即最大的ID为:0x7ef;
  • 扩展格式的ID有29位,即最大的ID为:0x1f bf ff ff;
  • 关于标识符:

  • RTR – 用于表示是否为遥控帧(0-数据帧,1-遥控帧);
  • SRR – 为代替遥控请求位(0-数据帧,1-遥控帧),它代替了标准帧中的 RTR 位。
  • IDE – 为标识符选择位,标准帧 扩展帧(0-标准帧,1-扩展帧)注:在实际使用STM32F4时将IDE位设置为0时也会接受扩展帧ID

  • 32单片机CAN的过滤器设置

    知道上面的ID设定,下面看看STM32的CAN控制器是怎么将ID过滤的。

    过滤器组

    32单片机有好多个滤波器组,每个滤波器组可以配置为掩码模式和列表模式,每个模式都可以配置为16位和32位过滤器。
    只有一个CAN外设的MCU一般有编号为0~13共14个过滤器可用;
    在有两个CAN外设的MCU中:CAN0使用的是过滤器编号为0-13;而CAN1使用的是14-27;共有28个过滤器;

  • 设置为掩码模式主要是为了过滤出一组(多个)符合要求的ID;
  • 设置为列表模式主要是为了过滤出一个或多个符合要求的ID;
  • 设置16位过滤器只能用来过滤标准帧ID;
  • 设置32位过滤器一般用来过滤扩展帧ID(当然也可以过滤标准帧);

    一个过滤器组是由两个32位寄存器组成,CAN_FxR1与CAN_FxR2组成;可以将其配置为:
  • 四个16位列表模式的过滤器,可以过滤出来四个ID号的信息;
  • 两个16位掩码模式过滤器
  • 一个32位掩码模式过滤器
  • 掩码模式

    当我们设置为掩码模式时:一般我们称R1寄存器为ID寄存器(或者验证码寄存器),R2为掩码寄存器。
    掩码模式的过滤器计算逻辑为:

    ID码: 0110 0110 //0x66
    掩码: 0101 0101 //0x55
    计算结果:
    x1x0 x1x0 //
    0100 0100-0x44;
    0100 0110-0x46;
    0100 1100-0x4b;
    0100 1110-0x4e;
    0110 0100-0x64;
    0110 0110-0x66;
    0110 1100-0x6b;
    0110 1110-0x6e;
    1100 0100-0xb4;
    1100 0110-0xb6;
    1100 1100-0xbb;
    1100 1110-0xbe;
    1110 0100-0xe4;
    1110 0110-0xe6;
    1110 1100-0xeb;
    1110 1110-0xee;
    这些结果都是可以通过过滤器的。

    16位掩码模式应用实例

    项目要求:过滤出来0x62a-0x62c和0x64a-0x64c的ID

    因为是标准ID所以选择16位模式,设置两个过滤器;

    0x62a – 0000 0110 0010 1010
    0x62b – 0000 0110 0010 1011
    0x62c – 0000 0110 0010 1100
    看到只有低三位不一样,所以:

    ID码为: 0000 0110 0010 1000 - 0x628
    掩码为: 1111 1111 1111 1000 - 0xff8
    这样就可以将0x628-0x62f全部过滤出来了(其中包括我们想要的0x62a-0x62c)
    

    STM32滤波器寄存器格式
    看上图寄存器每一个位的映射关系可以看出高11位存的是STID,所以要把掩码和ID移位到对应的位上;

    can_filter.filter_list_high  = (uint16_t)(0x628<<5);//设置接受地址为0x628-0x62f的数据
    can_filter.filter_mask_high  = (uint16_t)(0xfff8<<5);//
    

    同样的,过滤0x64a-0x64c的设置为:

    can_filter.filter_list_low   = (uint16_t)(0x648<<5);//设置接受地址为0x648-0x64f的数据
    can_filter.filter_mask_low   = (uint16_t)(0xfff8<<5);//
    

    由此可见,掩码模式可以过滤掉大部分不想要的ID,但是也会有一些不想要的ID会通过。所以掩码模式的优势和缺点显而易见。

    32位掩码模式

    明白16位掩码模式,32位掩码模式也就明白了。32位掩码模式可用于扩展帧的ID(标准帧也可以用),只需要根据下图将ID和掩码的每一位与CAN_FxR1和CAN_FxR2寄存器的每一位的映射对应起来就好了。

    列表模式

    列表模式相对来说比较简单,把想要的ID移位后赋给CAN_FxRx寄存器就可以了;
    还是上面的项目场景设计为列表模式就需要至少两个滤波器组;
    将滤波器设置为16位列表模式,一个过滤器组可以设置4个滤波器;总共要过滤6个ID,需要两个;

     /* filter config */
        can_filter.filter_number = 1;//过滤器编号
    	can_filter.filter_list_high  = (uint16_t)0x62a<<5;//
    	can_filter.filter_mask_high  = (uint16_t)(0x62b<<5);//
    	can_filter.filter_list_low   = (uint16_t)0x62c<<5;//
    	can_filter.filter_mask_low   = (uint16_t)(0x64a<<5);//
    
    	can_filter.filter_number = 2;//过滤器编号
    	can_filter.filter_list_high  = (uint16_t)0x64b<<5;//
    	can_filter.filter_mask_high  = (uint16_t)(0x64c<<5);//
    	can_filter.filter_list_low   = (uint16_t)0x0000;//
    	can_filter.filter_mask_low   = (uint16_t)0x0000;//
    

    当然也可以将过滤器设置为32位列表模式,那就需要3个过滤器组了,没有太大的必要;

    参考文章:
    【1】CAN协议帧结构-part1
    【2】CAN筛选器之ID配置
    【3】CAN总线笔记(2)-CAN通信的数据帧与遥控帧
    【4】CAN总线通信协议(总结篇)
    【5】CAN总线基础知识(2)——CAN的数据帧

    物联沃分享整理
    物联沃-IOTWORD物联网 » CAN 滤波器设置的指南

    发表评论