你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32F407ZET6的CAN1能配置28个32位的掩码筛选器吗

[复制链接]
JQChirs 提问时间:2022-12-5 10:18 / 未解决
    需求:系统配置N个通道,CAN总线只接收0-N节点的数据。   example:系统通道总数为51,那么只接收0,1,2,3,4,....51的数据。
   如下为CAN协议格式。
   

CAN协议格式

CAN协议格式

          所以采用拓展帧,在筛选器的选择上选择了32位的掩码模式。
          通过查阅F4的参考手册得知,bxCAN具有28个筛选器。
         

bxCAN特性

bxCAN特性

                                           bxCAN的外设框图
         

CAN框图

CAN框图

         CAN共有28个筛选器组,每个筛选器可配置4种模式,分别是1个32位掩码,2个32位标识符,2个16位掩码,4个16位标识符。根据我32位的掩码模式使用场景,也就是说可以配置28个32位掩码的筛选器
         所以采用的算法思路:比如系统通道数为51,小于51的二次幂项是32,配置一个0-31的区间筛选器,然后32到51每个单独配置一个筛选器。所以筛选器数量为1个区间筛选器+20(51-32+1)指定筛选器。
         代码如下:
  1. void Bsp_Can_FilterConfig(void)
  2. {
  3.         CAN_FilterTypeDef sFilterConfig;
  4.         HAL_StatusTypeDef status;
  5.         const uint32_t Can_Id = 0x10000000;
  6.         const uint16_t packet_sum = 128;  //包总数
  7.         uint16_t ps_nearest_pow = 0;        //向上寻找包总数最近的二次幂
  8.         
  9.         struct
  10.         {
  11.                 uint8_t node_total;         //节点总数
  12.                 uint8_t pow_nearst_down;    //向下最近二次幂   
  13.                 uint8_t filter_num;         //滤波器编号
  14.                 uint8_t node_num;           //节点编号
  15.                
  16.                 uint32_t id;
  17.                 uint32_t mask_range;        //区间
  18.         }Can_Filter;

  19.         Can_Filter.filter_num = 0;
  20.         Can_Filter.node_total = Get_Mid_Property_Node_Total();
  21.         ps_nearest_pow = pow(2, ceil(log2(packet_sum)));
  22.         Can_Filter.pow_nearst_down = pow(2, floor(log2(Can_Filter.node_total)));
  23.         
  24.         Can_Filter.mask_range = 0x1fffffff;
  25.         Can_Filter.mask_range &= (~((ps_nearest_pow-1) << 0));
  26.         Can_Filter.mask_range &= (~((ps_nearest_pow-1) << 9));
  27.         Can_Filter.mask_range &= (~((Can_Filter.pow_nearst_down-1) << 20));
  28.         Can_Filter.mask_range <<= 3;
  29.         
  30.         /***************** 配置区间滤波器 *********************/
  31.         sFilterConfig.FilterActivation = ENABLE;                 
  32.         sFilterConfig.FilterBank = Can_Filter.filter_num;                           
  33.         sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;        
  34.         sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;      
  35.         sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;   

  36.         sFilterConfig.FilterMaskIdHigh = (Can_Filter.mask_range>>16)&0xffff;
  37.         sFilterConfig.FilterMaskIdLow =  (Can_Filter.mask_range&0xffff);
  38.         
  39.         sFilterConfig.FilterIdHigh = ((Can_Id<<3)>>16)&0xffff;
  40.         sFilterConfig.FilterIdLow = ((Can_Id<<3)&0xffff);        
  41.         sFilterConfig.SlaveStartFilterBank = 0;
  42.         HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
  43.         /********************************************************/
  44.         
  45.         /***************** 配置指定滤波器 *********************/
  46.         sFilterConfig.FilterMaskIdHigh = (0x0ff00000<<3) >> 16;
  47.         sFilterConfig.FilterMaskIdLow =  0;
  48.         
  49.         for(Can_Filter.node_num=Can_Filter.pow_nearst_down;
  50.                 Can_Filter.node_num<=Can_Filter.node_total;
  51.                 Can_Filter.node_num++)
  52.         {
  53.                 Can_Filter.id = 0;
  54.                 Can_Filter.filter_num++;
  55.                
  56.                 if( Can_Filter.filter_num < 14 )
  57.                 {
  58.                         sFilterConfig.SlaveStartFilterBank = 0;

  59.                 }
  60.                 else
  61.                 {
  62.                         sFilterConfig.SlaveStartFilterBank = 14;
  63.                 }
  64.                
  65.                 if( Can_Filter.filter_num > 28 )
  66.                 {
  67.                         log_i("Can Filter Num Over Range");
  68.                         break;
  69.                 }
  70.               
  71.                 sFilterConfig.FilterBank = Can_Filter.filter_num;
  72.                
  73.                 Can_Filter.id = Can_Filter.node_num << 20;
  74.                 sFilterConfig.FilterIdHigh = (Can_Filter.id <<3)>>16;
  75.                 sFilterConfig.FilterIdLow = 0;        
  76.                
  77.                 status = HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
  78.         }
复制代码
        测试方法:一个CAN发送设备,每隔100ms发送设备地址0-128的数据。作为接收设备,在接收中断把CAN EXID的设备地址打印出来。如系统设置为51通道,串口每隔100ms显示0-51。
         测试现象:只收到0-44。
         

测试现象

测试现象

         疑问点:从测试现象分析,31+13=44,CAN1好像只有14个筛选器起到了作用。只要筛选器编号超过14就不起作用,我在程序debug时查了所有筛选器硬件寄存器的值和算法是对应的。
         我再次查了资料,筛选器数量28还是14说的模棱两可。
          验收筛选器.png
         所以我的疑问是stm32F407ZET6,为什么CAN1的14-28筛选器不起作用
收藏 评论2 发布时间:2022-12-5 10:18

举报

2个回答
JQChirs 回答时间:2022-12-5 16:02:22
怎么发帖子看不到图片啊?
CAN特性.png
CAN外设框图.png
CAN协议格式.png
测试现象.png
验收筛选器.png
xmshao 回答时间:2022-12-16 15:00:30
你确认下 CAN_FMR寄存器里的 CAN2SB[5:0]是否配置得有问题, 你如果想把filter全部给CAN1用,这个地方的值应该是28,如果全部给CAN2用,这里就该配置为0.
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版