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

查看: 10139|回复: 5

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

[复制链接]

1182

主题

3785

回帖

1

蝴蝶豆

论坛元老

最后登录
2020-3-17
发表于 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, 下载次数: 1220)

评分

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

查看全部评分

<
回复

使用道具 举报

100

主题

3617

回帖

1

蝴蝶豆

论坛元老

最后登录
2020-12-8
发表于 2016-8-31 09:48:30 | 显示全部楼层
回复 支持 反对

使用道具 举报

2

主题

134

回帖

0

蝴蝶豆

中级会员

最后登录
2017-8-3
发表于 2016-10-27 10:04:55 | 显示全部楼层
回复 支持 反对

使用道具 举报

1

主题

8

回帖

0

蝴蝶豆

初级会员

最后登录
2017-3-1
发表于 2016-11-27 16:22:50 | 显示全部楼层
F4就没有这个问题了,这样不是感觉很坑人啊。左边是 F4 右边是F1

Snap1.jpg

回复 支持 反对

使用道具 举报

0

主题

11

回帖

0

蝴蝶豆

初级会员

最后登录
2020-9-14
发表于 2018-7-28 16:20:29 | 显示全部楼层
没有使用Cube
回复 支持 反对

使用道具 举报

0

主题

1

回帖

0

蝴蝶豆

新手上路

最后登录
2018-11-9
发表于 2018-11-8 18:32:14 | 显示全部楼层
遇到同样的问题  太好了
回复 支持 反对

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版