OpenEdv-开源电子网

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

STM32 CAN通信接收带不同标识符的数据帧问题

[复制链接]

2

主题

4

帖子

0

精华

新手入门

积分
32
金钱
32
注册时间
2014-1-7
在线时间
0 小时
发表于 2014-1-7 12:06:00 | 显示全部楼层 |阅读模式

            如题,我有STM32 CAN通信能够接收某一标识符的数据,使用IdMask模式。

void CAN_Configuration(void)
{
  CAN_InitTypeDef        CAN_InitStructure;
  CAN_FilterInitTypeDef  CAN_FilterInitStructure;

  //NVIC_Configuration();
  GPIO_Configuration();
  /* CAN register init */
  CAN_DeInit(CAN1);
  CAN_StructInit(&CAN_InitStructure);

  /* CAN cell init */
  CAN_InitStructure.CAN_TTCM = DISABLE;
  CAN_InitStructure.CAN_ABOM = DISABLE;
  CAN_InitStructure.CAN_AWUM = DISABLE;
  CAN_InitStructure.CAN_NART = DISABLE;
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;
  CAN_InitStructure.CAN_Prescaler = 45;

  if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED)   
  {
  } 

  CAN_FilterInitStructure.CAN_FilterNumber=0;
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh=(((u32)0x0111<<21)&0xffff0000)>>16;
  CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)0x0111<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xFFFF;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);
  CAN_FilterInit(&CAN_FilterInitStructure);
}

 

这样设置后,可以接受标识符为0x0111的数据帧。

       但现在想接收不同标识符的数据。根据STM32中文手册:

                一旦收到的报文被存入FIFO,就可被应用程序访问。通常情况下,报文中的数据被拷贝到
               SRAM 中;为了把数据拷贝到合适的位置,应用程序需要根据报文的标识符来辨别不同的数
               据。bxCAN提供了过滤器匹配序号,以简化这一辨别过程。
              根据过滤器优先级规则,过滤器匹配序号和报文一起,被存入邮箱中。因此每个收到的报文,
              都有与它相关联的过滤器匹配序号。
             过滤器匹配序号可以通过下面两种方式来使用:
                       ●  把过滤器匹配序号跟一系列所期望的值进行比较
                       ●  把过滤器匹配序号当作一个索引来访问目标地址

              过滤器匹配序号存放在CAN_RDTxR 寄存器的FMI 域中。

        那么我是不是可以在程序中多设置几个CAN_Configuration(void),里面的设置不同的CAN_FilterNumber和CAN_FilterIdHigh,CAN_FilterIdLow。比如

void CAN_Configuration1(void)
{
  CAN_InitTypeDef        CAN_InitStructure;
  CAN_FilterInitTypeDef  CAN_FilterInitStructure;

  //NVIC_Configuration();
  GPIO_Configuration();
  /* CAN register init */
  CAN_DeInit(CAN1);
  CAN_StructInit(&CAN_InitStructure);

  /* CAN cell init */
  CAN_InitStructure.CAN_TTCM = DISABLE;
  CAN_InitStructure.CAN_ABOM = DISABLE;
  CAN_InitStructure.CAN_AWUM = DISABLE;
  CAN_InitStructure.CAN_NART = DISABLE;
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;
  CAN_InitStructure.CAN_Prescaler = 45;

  if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED)   
  {
  } 

  CAN_FilterInitStructure.CAN_FilterNumber=1;
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh=(((u32)0x0112<<21)&0xffff0000)>>16;
  CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)0x0112<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xFFFF;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);
  CAN_FilterInit(&CAN_FilterInitStructure);
}

 

最后在接收中断函数里面读取RxMessage.FMI的值,判断是哪帧数据? 

 

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-1-7 15:04:45 | 显示全部楼层
回复【楼主位】qianzhang:
---------------------------------
设置多个CAN_Configuration1函数,是不对的.
因为在你的CAN_Configuration1函数里面,会把之前的CAN初始化全给清掉了,也就前面代码都白忙活了...
你只需要设置多个过滤器即可.
也就是:
  CAN_FilterInitStructure.CAN_FilterNumber=1;
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh=(((u32)0x0112<<21)&0xffff0000)>>16;
  CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)0x0112<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xFFFF;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);
  CAN_FilterInit(&CAN_FilterInitStructure);
这部分代码,可以设置多次
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

4

帖子

0

精华

新手入门

积分
32
金钱
32
注册时间
2014-1-7
在线时间
0 小时
 楼主| 发表于 2014-1-7 17:28:20 | 显示全部楼层
回复【2楼】正点原子:

回复【楼主位】qianzhang:
---------------------------------
设置多个CAN_Configuration1函数,是不对的.
因为在你的CAN_Configuration1函数里面,会把之前的CAN初始化全给清掉了,也就前面代码都白忙活了...
你只需要设置多个过滤器即可.
也就是:
  CAN_FilterInitStructure.CAN_FilterNumber=1;
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh=(((u32)
......
---------------------------------
嗯,开始试了不行,不知道为什么,原来是清掉了
现在在一个函数蝻设置多次,可以运行,谢谢原子哥
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-11 11:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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