OpenEdv-开源电子网

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

STM32F103VET6的CAN模块怎么接受2个不同ID或者更多的不同ID的扩展帧报文?

[复制链接]

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2019-6-3
在线时间
32 小时
发表于 2019-6-11 16:03:22 | 显示全部楼层 |阅读模式
微信图片_20190611154147.png 如图所示,我要发送3不同ID(报文编号就是前面打√的0,1,2)的报文给单片机,目前我只能实现选中1个发送,单片机正常接受,如果选中2个或全选则前面的会被后面的替代掉(选中0和2,0会被2替代掉),请问程序怎么处理才能将所有报文正常接受过来且能实现接受更多不同ID的报文?使用接受中断的方式,想就用FIFO1的消息挂号中断实现
void CAN1_RX1_IRQHandler(void)
{
        CanRxMsg RxMessage;
        IWDG_ReloadCounter();//喂狗
        CAN_Cnt_1=0;
        CAN_Receive(CAN1,CAN_FIFO1,&RxMessage);       
        if(0 == RxMessage.FMI)   YuRe_Data_OK=1; //采用检查过滤器匹配序号的方式检查是哪个ID的报文
        else               YuRe_Data_OK=0;
        if(1 == RxMessage.FMI)   Water_Data_OK=1;
        else               Water_Data_OK=0;
        if(2 == RxMessage.FMI)   ZhuanSu_Data_OK=1;
        else               ZhuanSu_Data_OK=0;

        if(YuRe_Data_OK)
           CAN_YuRe_Data=RxMessage.Data[3];
         else
                 YuRe_CAN_LED_Flag=0;
        if(Water_Data_OK)
           CAN_Water_Data=RxMessage.Data[0];
         else
           Task_TempWaterAD();
         if(ZhuanSu_Data_OK)
         {
           ZhuanSu_L = RxMessage.Data[3];
           ZhuanSu_H = RxMessage.Data[4];
         }
        else
                HR_Signal = 0;
        CAN_ClearITPendingBit(CAN1,CAN_IT_FMP1);  // 清除挂起的中断       
}




请教各位大神指点,谢谢
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

109

主题

5564

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10571
金钱
10571
注册时间
2017-2-18
在线时间
1914 小时
发表于 2019-6-11 17:55:15 | 显示全部楼层
回复 支持 反对

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-6-11 18:01:37 | 显示全部楼层
你不过滤都来着不拒呀,只要收的过来,都会收了
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2019-6-3
在线时间
32 小时
 楼主| 发表于 2019-6-11 19:51:51 | 显示全部楼层
nashui_sx 发表于 2019-6-11 18:01
你不过滤都来着不拒呀,只要收的过来,都会收了

/***********************以下为存入FIFO1的报文的过滤器组***************/
         //待初始化的滤波器组:3,过滤器编号为0,按照初始化的顺序编号
   CAN_FilterInitStructure.CAN_FilterNumber=3;
   //屏蔽模式
   CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
   //32位寄存器
   CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
   //高16位,过滤器
   CAN_FilterInitStructure.CAN_FilterIdHigh=YuRe_ID>>13;
   //低16位,过滤器
   CAN_FilterInitStructure.CAN_FilterIdLow=((YuRe_ID<<3) | CAN_ID_EXT | CAN_RTR_DATA)&0x0000FFFF;
   //屏蔽位高16位
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;
   //屏蔽位低16位
   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xFFFF;
   //过滤器 0 关联到 FIFO0
   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO1;
   //使能过滤器
   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
   //初始化过滤器
   CAN_FilterInit(&CAN_FilterInitStructure);
         
         //待初始化的滤波器组:4,过滤器编号为1,按照初始化的顺序编号
   CAN_FilterInitStructure.CAN_FilterNumber=4;
   //屏蔽模式
   CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
   //32位寄存器
   CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
   //高16位,过滤器
   CAN_FilterInitStructure.CAN_FilterIdHigh=Water_ID>>13;
   //低16位,过滤器
   CAN_FilterInitStructure.CAN_FilterIdLow = ((Water_ID<<3) | CAN_ID_EXT | CAN_RTR_DATA)&0x0000FFFF;
   //屏蔽位高16位
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;
   //屏蔽位低16位
   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xFFFF;
   //过滤器 0 关联到 FIFO0
   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO1;
   //使能过滤器
   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
   //初始化过滤器
   CAN_FilterInit(&CAN_FilterInitStructure);
         
         //待初始化的滤波器组:5,过滤器编号为2,按照初始化的顺序编号
   CAN_FilterInitStructure.CAN_FilterNumber=5;
   //屏蔽模式
   CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
   //32位寄存器
   CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
   //高16位,过滤器
   CAN_FilterInitStructure.CAN_FilterIdHigh=ZhuanSu_ID>>13;
   //低16位,过滤器
   CAN_FilterInitStructure.CAN_FilterIdLow=((ZhuanSu_ID<<3) | CAN_ID_EXT | CAN_RTR_DATA)&0x0000FFFF;
   //屏蔽位高16位
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;
   //屏蔽位低16位
   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xFFFF;
   //过滤器 0 关联到 FIFO0
   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO1;
   //使能过滤器
   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
   //初始化过滤器
   CAN_FilterInit(&CAN_FilterInitStructure);


有的,我只收这三个ID的报文,其他ID都不要
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2019-6-3
在线时间
32 小时
 楼主| 发表于 2019-6-11 20:19:47 | 显示全部楼层
nashui_sx 发表于 2019-6-11 18:01
你不过滤都来着不拒呀,只要收的过来,都会收了

3个都能正常接收,只能勾选1个,单片机才正常接收,勾选2个或3个,前面的就被最后面的覆盖掉了
回复 支持 反对

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-6-11 22:49:20 | 显示全部楼层
龙的心098611227 发表于 2019-6-11 20:19
3个都能正常接收,只能勾选1个,单片机才正常接收,勾选2个或3个,前面的就被最后面的覆盖掉了

先不过滤,上位机每帧发送间隔加大试试
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2019-6-3
在线时间
32 小时
 楼主| 发表于 2019-6-12 09:19:02 | 显示全部楼层
nashui_sx 发表于 2019-6-11 22:49
先不过滤,上位机每帧发送间隔加大试试

试过的,间隔时间加的越大,越正常,不过我看过人家的产品在间隔设为0时,都能正常接受,我这个必须做到至少和人家一样
回复 支持 反对

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-6-12 13:05:37 | 显示全部楼层
龙的心098611227 发表于 2019-6-12 09:19
试过的,间隔时间加的越大,越正常,不过我看过人家的产品在间隔设为0时,都能正常接受,我这个必须做到 ...

那就是你发的太快,收不过来,can不是两个fifo嘛,两个中断都开开,快点试试
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2019-6-3
在线时间
32 小时
 楼主| 发表于 2019-6-12 13:37:25 | 显示全部楼层
nashui_sx 发表于 2019-6-12 13:05
那就是你发的太快,收不过来,can不是两个fifo嘛,两个中断都开开,快点试试

对,就是收不过来,两个中断都打开是完全没有问题的,早就验证过的,2个FIFO收2个不同ID,互不干扰,这样一搞,单片机所有资源用了才只能同时接受2个报文,即便三级深度用了,一共才6个,实际应用中远不止6个,别人家产品我也是用同样的方式发送的,没有问题的
回复 支持 反对

使用道具 举报

2

主题

25

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
247
金钱
247
注册时间
2014-10-22
在线时间
40 小时
发表于 2019-6-12 17:11:09 | 显示全部楼层
龙的心098611227 发表于 2019-6-12 13:37
对,就是收不过来,两个中断都打开是完全没有问题的,早就验证过的,2个FIFO收2个不同ID,互不干扰,这样 ...

你好,你的问题解决了没?我不知道你的代码写的如何,我这边并不存在你这个问题!~
微信图片_20190612170807.png
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2019-6-3
在线时间
32 小时
 楼主| 发表于 2019-6-12 20:07:14 | 显示全部楼层
zhouzhiqiao223 发表于 2019-6-12 17:11
你好,你的问题解决了没?我不知道你的代码写的如何,我这边并不存在你这个问题!~

你好,你这个是单片机接受后再用串口发到上位机显示的吧?我的中断接受处理函数和一些过滤设置在上面能看到,接受特定ID的报文,并读取其中特定字节数据的值,根据值的多少,再去做一些动作,目前我先用PIC单片机8个接受缓冲区来接受报文,每个ID对应一个缓冲区的。

帧与帧间隔设为0的,第一帧数据没有来及读走,第二帧来了,读到的永远是最后发送的那个,相当于你这个照片里的第8个
回复 支持 反对

使用道具 举报

2

主题

25

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
247
金钱
247
注册时间
2014-10-22
在线时间
40 小时
发表于 2019-6-13 09:23:37 | 显示全部楼层
龙的心098611227 发表于 2019-6-12 20:07
你好,你这个是单片机接受后再用串口发到上位机显示的吧?我的中断接受处理函数和一些过滤设置在上面能看 ...

你肯定没弄好!~我在中断中delay_ms(5);都没关系的
回复 支持 反对

使用道具 举报

2

主题

25

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
247
金钱
247
注册时间
2014-10-22
在线时间
40 小时
发表于 2019-6-13 09:48:43 | 显示全部楼层
zhouzhiqiao223 发表于 2019-6-13 09:23
你肯定没弄好!~我在中断中delay_ms(5);都没关系的

Q:754804854
回复 支持 反对

使用道具 举报

4

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
158
金钱
158
注册时间
2019-5-27
在线时间
22 小时
发表于 2019-7-24 10:23:33 | 显示全部楼层
龙的心098611227 发表于 2019-6-12 20:07
你好,你这个是单片机接受后再用串口发到上位机显示的吧?我的中断接受处理函数和一些过滤设置在上面能看 ...

你好,你的工程能共享一下吗
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-8 03:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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