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

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

[复制链接]
zero99 提问时间:2016-8-30 15:47 /
基于 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, 下载次数: 1272)

评分

参与人数 1 ST金币 +1 收起 理由
engerHi + 1 很给力!不错不错,可以借鉴一下..

查看全部评分

2 收藏 6 评论6 发布时间:2016-8-30 15:47

举报

6个回答
stary666 回答时间:2016-8-31 09:48:30
zhulikai 回答时间:2016-10-27 10:04:55
makc 回答时间:2016-11-27 16:22:50
F4就没有这个问题了,这样不是感觉很坑人啊。左边是 F4 右边是F1

Snap1.jpg

shuichengwen 回答时间:2018-7-28 16:20:29
没有使用Cube
qiaoy1988 回答时间:2018-11-8 18:32:14
遇到同样的问题  太好了
Morpher 回答时间:2021-10-13 14:42:24
太感谢了,从昨天晚上开始,CAN1发送接收中断都正常,但是CAN2只能进入发送中断,谢谢大佬。

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版