OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5427|回复: 9

关于F2xx的库函数CAN_FilterInit

[复制链接]

13

主题

37

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
258
金钱
258
注册时间
2014-11-5
在线时间
46 小时
发表于 2014-11-13 11:52:59 | 显示全部楼层 |阅读模式
5金钱
CAN_FilterInit 这个函数为什么只是对can1的设置,没有对can2?难道是我理解错了,can1 和can2 共用过滤器?
原函数:



/**
  * @brief  Configures the CAN reception filter according to the specified
  *         parameters in the CAN_FilterInitStruct.
  * @param  CAN_FilterInitStruct: pointer to a CAN_FilterInitTypeDef structure that
  *         contains the configuration information.
  * @retval None
  */
void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct)
{
  uint32_t filter_number_bit_pos = 0;
  /* Check the parameters */
  assert_param(IS_CAN_FILTER_NUMBER(CAN_FilterInitStruct->CAN_FilterNumber));
  assert_param(IS_CAN_FILTER_MODE(CAN_FilterInitStruct->CAN_FilterMode));
  assert_param(IS_CAN_FILTER_SCALE(CAN_FilterInitStruct->CAN_FilterScale));
  assert_param(IS_CAN_FILTER_FIFO(CAN_FilterInitStruct->CAN_FilterFIFOAssignment));
  assert_param(IS_FUNCTIONAL_STATE(CAN_FilterInitStruct->CAN_FilterActivation));

  filter_number_bit_pos = ((uint32_t)1) << CAN_FilterInitStruct->CAN_FilterNumber;

  /* Initialisation mode for the filter */
  CAN1->FMR |= FMR_FINIT;

  /* Filter Deactivation */
  CAN1->FA1R &= ~(uint32_t)filter_number_bit_pos;

  /* Filter Scale */
  if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_16bit)
  {
    /* 16-bit scale for the filter */
    CAN1->FS1R &= ~(uint32_t)filter_number_bit_pos;

    /* First 16-bit identifier and First 16-bit mask */
    /* Or First 16-bit identifier and Second 16-bit identifier */
    CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = 
       ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow) << 16) |
        (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow);

    /* Second 16-bit identifier and Second 16-bit mask */
    /* Or Third 16-bit identifier and Fourth 16-bit identifier */
    CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 = 
       ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |
        (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh);
  }

  if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_32bit)
  {
    /* 32-bit scale for the filter */
    CAN1->FS1R |= filter_number_bit_pos;
    /* 32-bit identifier or First 32-bit identifier */
    CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = 
       ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh) << 16) |
        (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow);
    /* 32-bit mask or Second 32-bit identifier */
    CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 = 
       ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |
        (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow);
  }

  /* Filter Mode */
  if (CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdMask)
  {
    /*Id/Mask mode for the filter*/
    CAN1->FM1R &= ~(uint32_t)filter_number_bit_pos;
  }
  else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
  {
    /*Identifier list mode for the filter*/
    CAN1->FM1R |= (uint32_t)filter_number_bit_pos;
  }

  /* Filter FIFO assignment */
  if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_Filter_FIFO0)
  {
    /* FIFO 0 assignation for the filter */
    CAN1->FFA1R &= ~(uint32_t)filter_number_bit_pos;
  }

  if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_Filter_FIFO1)
  {
    /* FIFO 1 assignation for the filter */
    CAN1->FFA1R |= (uint32_t)filter_number_bit_pos;
  }
  
  /* Filter activation */
  if (CAN_FilterInitStruct->CAN_FilterActivation == ENABLE)
  {
    CAN1->FA1R |= filter_number_bit_pos;
  }

  /* Leave the initialisation mode for the filter */
  CAN1->FMR &= ~FMR_FINIT;
}

最佳答案

查看完整内容[请看2#楼]

回复【6楼】yyisme1988: --------------------------------- 嗯,我看了下你说的那个寄存器,这里的can1其实改成can就不会误导了。CAN_FMR的CAN2SB复位默认是0x0E,当设置 CAN_FilterNumber >=14就是can2设置了。 我加上这个 CAN_FilterInitStructure.CAN_FilterNumber=14; CAN_FilterInit(&CAN_FilterInitStructure); can2就好用了。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

13

主题

37

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
258
金钱
258
注册时间
2014-11-5
在线时间
46 小时
 楼主| 发表于 2014-11-13 11:53:00 | 显示全部楼层
回复【6楼】yyisme1988:
---------------------------------
嗯,我看了下你说的那个寄存器,这里的can1其实改成can就不会误导了。CAN_FMR的CAN2SB复位默认是0x0E,当设置
CAN_FilterNumber >=14就是can2设置了。
我加上这个
CAN_FilterInitStructure.CAN_FilterNumber=14;
CAN_FilterInit(&CAN_FilterInitStructure);
can2就好用了。
回复

使用道具 举报

26

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
209
金钱
209
注册时间
2012-5-31
在线时间
0 小时
发表于 2014-11-13 11:53:00 | 显示全部楼层
回复【7楼】jklw0713:
---------------------------------
是的,默认为14~27号为can2使用,如果单独想使用can2也是可以的
在设置前加上
CAN_SlaveStartBank(N);
CAN_FilterInitStructure.CAN_FilterNumber=N;
当N= 0 的时候就只能用CAN2.
应该不是简单的把CAN1改成CAN,这个是硬件上的设计。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-11-13 16:50:04 | 显示全部楼层
是不是固件太老了?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

13

主题

37

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
258
金钱
258
注册时间
2014-11-5
在线时间
46 小时
 楼主| 发表于 2014-11-14 08:12:07 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
也许是吧,反正我用can1 可以通信,改成can2没反应,我进去CAN_FilterInit 这个过滤器只是对can1的设置,请问can2要用过滤器不需要设置吗?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-11-14 21:38:24 | 显示全部楼层
回复【3楼】jklw0713:
---------------------------------
can2也有过滤器啊,不过我也没用过can2
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

13

主题

37

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
258
金钱
258
注册时间
2014-11-5
在线时间
46 小时
 楼主| 发表于 2014-11-15 13:01:59 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
嗯,谢谢,还是改硬件管脚吧,用can1
回复

使用道具 举报

26

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
209
金钱
209
注册时间
2012-5-31
在线时间
0 小时
发表于 2015-7-22 06:57:04 | 显示全部楼层
lz,你好。我也一直被这个问题困扰,在网上找了一些资料也没有明确的答案,个人理解是应为CAN2没有直接访问SRAM的权限,所以对共用Filter组来说,只能通过CAN1来访问,那么如何实现CAN2的Filter设置呢?
不知道你有没有在意到CAN筛选器主寄存器CAN_FMR这个寄存器,当中有一个CAN2SB[5:0]这一个6位的操作位,当你设置这个位之后,硬件将对应的filter配置给CAN2,假设设置为N. 当你设置的CAN_FilterNumber >= N时,硬件就自动关联到CAN2的filter设置当中了。虽然你看的库函数一直只有CAN1->XXX操作,但实际上是可以对CAN2的filter进行设置的。 这是我的个人理解,不知道对不对,如lz有新的发现望指正
回复

使用道具 举报

16

主题

147

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7140
金钱
7140
注册时间
2015-1-23
在线时间
106 小时
发表于 2015-9-2 16:23:09 | 显示全部楼层
是的,默认为14~27号为can2使用,如果单独想使用can2也是可以的 
在设置前加上 
CAN_SlaveStartBank(N); 
CAN_FilterInitStructure.CAN_FilterNumber=N; 
当N= 0 的时候就只能用CAN2. 
应该不是简单的把CAN1改成CAN,这个是硬件上的设计。


受教了
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2016-1-18
在线时间
0 小时
发表于 2016-1-18 10:10:37 | 显示全部楼层
jklw0713 发表于 2014-11-13 11:53
回复【6楼】yyisme1988:
---------------------------------
嗯,我看了下你说的那个寄存器,这里的can1其 ...

你说的这两句CAN_FilterInitStructure.CAN_FilterNumber=14;
CAN_FilterInit(&CAN_FilterInitStructure); 应该加在什么地方?这里是要做一个case语句么请问。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 18:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表