请选择 进入手机版 | 继续访问电脑版
搜索
查看: 1051|回复: 3

【实战经验】基于Cube库无法检测CAN2的接收中断

[复制链接]

521

主题

1993

帖子

2

精华

Rank: 9Rank: 9Rank: 9

管理员

注册时间
2016-6-1
发表于 2016-8-30 15:47:16 | 显示全部楼层 |阅读模式
基于 Cube库无法 检测 CAN2的接收中断

1 前言
       本文将针对客户在使用Cube库时CAN2不能产生接收中断进行分析。

2 问题描述
       客户使用的是STM32F105,同时用到了CAN1与CAN2,使用cube库,但有个奇怪的现象,CAN1能正常工作,CAN2却无**常产生接收中断,CAN1与CAN2的代码几乎没有什么差别。


3 重现问题
       实验使用STM3210C-EVAL评估板,这款板子有同时将CAN1和CAN2引出,此板上的MCU为STM32F107VC,与客户所用到的STM32F105只多了个Ethernet外设,其他无差别,正适合用来验证此问题。

3.1 工程制作
       使用cubemx生成工程,cubemx得配置如下图:


1.png

2.png

3.png


       配置波特率为500K,自动离线使能。
       点击生产代码,在main函数内的/* USER CODE BEGIN 2 */与/* USER CODE END 2 */添加:
4.png

5.png

6.png


       在main函数内的/* USER CODE BEGIN 3 */与/* USER CODE END 3 */添加:
7.png


3.2 测试重现问题现象
       使用ZLG的USBCAN-2E-U盒子与STM3210C-EVAL评估板以及PC连接进行测试:

8.png

       在调试下,在PC端软件CANTest下都能看到CAN1与CAN2发送的数据,这说明连接上是完全没有问题的,但是,在调试CAN接收时,在CAN2的接收中断处设置断点,使用PC端软件CAN_Test向CAN2发送数据发现并不能产生中断,而对比CAN1时,发现CAN1却可以产生接收中断。


4 问题分析
       仔细对比CAN1与CAN2的代码,发现并没有什么不同之处。仔细思考一下,由于CAN接收中断是与CAN过滤器有关,因此,着重对比CAN1与CAN2设置过滤器时的代码差异。
       CAN1设置过滤器代码如下:

9.png


       而CAN1设置过滤器代码如下:
10.png

      
       看来好像没有什么不妥的地方,基本差不多,只不过调用HAL_CAN_ConfigFilter函数配置过滤器传入的第一个参数一个是&hcan1,一个是&hcan2,
查看参考手册,对比CAN1与CAN2的差别:
       在参考手册的24.4节中对CAN的功能介绍时有下面一段话:

11.png

       上面一段话的意思是说,CAN1是作为主,而CAN2做为从,做为从的CAN2不能直接访问这个专用的512bytes的SRAM,而只能通过作为主的CAN1来间接访问,且CAN1与CAN2是共享这个专用的512bytes的SRAM。打开图222,如下所示:
12.png

      
      如上图可知,CAN1与CAN2共用过滤器(Acceptance Filters),CAN2是通过CAN1的Memory Access Controler来访问过滤器的。过滤器共有28个,占用512专用字节其中一部分。
       接着在数据手册中查下内存映射,如下图所示:
13.png


      可知,CAN1的地址为:
14.png

      
      然后查看bxCAN的寄存器,在参考手册的24.9.5节中,发现有这么一段话:
15.png

      
      也就是说,从偏移地址0x200开始到0x31C之间的寄存器只存在于CAN1中,在CAN2中并不存在,那么这些都是些什么寄存器呢?
查看参考手册的CAN寄存器映射表,如下内容所示:

16.png

17.png


      可知这些都是CAN过滤器相关的寄存器,可知离CAN1起始地址0x4000 6400偏移0x200~0x320之间是CAN过滤器寄存器的地址,且这些过滤器由CAN1和CAN2共享,且最重要的一点信息是,离CAN2起始地址0x4000 6800偏移0x200~0x320之间是没有寄存器的,这个非常重要!
      再回过头来看CAN2过滤器的设置代码:

18.png


      这几行设置过滤器的代码到底是将参数设置到CAN1偏移0x200~0x320之间还是CAN2偏移的0x200~0x320之间?这个问题要弄清楚,非常重要的!继续看HAL_CAN_ConfigFilter函数内:

19.png


      由上代码可知,设置的参数实际上是设置到传入的句柄hcan的示例Instance下的成员FS1R,sFilterRegister[]中去了,查看这些成员的定义:
20.png

21.png

      
      由以上代码可知,HAL_CAN_ConfigFilter函数实际上就是对传入的CAN起始地址偏移0x200~0x320之间的过滤器相关寄存器进行参数设置,但是,对于CAN2来说,实际并不存在这个这些寄存器,因此不会生效。这个可以在调试过程中查看CAN2寄存器值来验证,如下图:
22.png

      
      在运行过HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig)之后,CAN2相关的过滤器还是没有变化,进一步说明此函数对于CAN2来说是无效的。



      那么要解决这个问题,该如何修改呢?很明显,通过CAN1来设置即可。CAN1和CAN2共享过滤器,但设置过滤器时可以通过CAN1的偏移来访问过滤器,这么说来,也可以将这个理解为CAN1作为“主”的确切含义吧。
      修改后如下:

23.png

24.png


      在CAN2中断设置断点,使用PC端软件CANTest向STM3210C-EVAL评估板的CAN2通道发送数据进行测试验证:
25.png

      如上图可见,CAN2的接收中断已经可以正常捕获到了。

5 横向扩展
      此问题是在使用Cube库下时发现的,那么标准库是否也会存在同样的问题?
其实,在使用标准库下,在设置过滤器时,并不需要传入CAN1或CAN2的句柄,因此也就不会这这种问题,如下基于标准库的示例代码:

26.png

27.png

      在函数CAN_FilterInit中,内部自始至终操作的都是CAN1,如下所示:
28.png


      因此,不会出现在Cube库下出现的问题。


6 总结
      此文所描述的问题之会出现在使用Cube库的情况下,且基本覆盖包含双CAN的所有系列,在使用HAL函数HAL_CAN_ConfigFilter配置过滤器时,将第一个参数固定指向CAN1的句柄就可以了。





F107_2CAN_Test.zip (3.54 MB, 下载次数: 547)
欢迎加入STM32/STM8社区技术交流群: 313887143    STM32Lxx开发群:571793578
回复

使用道具 举报

59

主题

2752

帖子

0

精华

Rank: 6Rank: 6

金牌会员

注册时间
2010-4-9
发表于 2016-8-31 09:48:30 | 显示全部楼层
回复

使用道具 举报

2

主题

136

帖子

0

精华

Rank: 3Rank: 3

中级会员

注册时间
2016-8-12
发表于 2016-10-27 10:04:55 | 显示全部楼层
欢迎加入STM32/STM8社区技术交流群: 313887143    STM32Lxx开发群:571793578
回复

使用道具 举报

1

主题

9

帖子

0

精华

Rank: 2

初级会员

注册时间
2014-12-27
发表于 2016-11-27 16:22:50 | 显示全部楼层
F4就没有这个问题了,这样不是感觉很坑人啊。左边是 F4 右边是F1

Snap1.jpg

回复 支持 反对

使用道具 举报

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

本版积分规则

关闭

站长推荐上一条 /1 下一条

Archiver|手机版|小黑屋|意法半导体STM32/STM8技术社区    

GMT+8, 2017-5-25 07:20 , Processed in 0.166182 second(s), 13 queries , Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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