网上关于双CAN通信的例子很少,大多都是单CAN通信,即使有,也是关于用一个FIFO的通讯,过程中遇到很多问题,在手头只有一个很小的开发板的情况下,费劲周折,终于解决了问题,不多说,直接把入坑与出坑的事情说一下吧。
1. 工程制作
关于双CAN基础框架,使用CubeMX自己搭建即可:
配置波特率为500K,CAN1的接收中断对应RX0,CAN2的接收中断对应RX1。这是重要的第一点
2.代码补充
点击生产代码,并在can.c文件中/* USER CODE BEGIN 1 */和/* USER CODE END 1 */之间增加两个函数,分别为:HAL_CAN1_Config(void)和HAL_CAN1_Config(void),并在里面做Filter初始化。代码参照如下:
在Main函数中while(1)之前调用一下完成Filter的初始化调用,并开启CAN接收中断启动函数:
HAL_CAN_Receive_IT(&hcan1, CAN_Filter_FIFO0)
HAL_CAN_Receive_IT(&hcan2, CAN_Filter_FIFO1)
在main.c的/* USER CODE BEGIN 4 */和/* USER CODE END 4 */之重写接收回调函数HAL_CAN_Receive_IT(&hcan, CAN_FIFO0):
3. 遇到的坑以及出坑记录
1)CAN1和CAN2 共用FIFO时收发正常,但同时用FIFO0和FIFO1时,就不能正常收发数据,如下帖子描述:
问题帖: https://bbs.csdn.net/topics/392074227
出坑帖:https://blog.csdn.net/huan447882949/article/details/73478228
对于双CAN STM32芯片,如果sFilterConfig.BankNumber=0,则所有过滤器组分配给CAN2使用,CAN1没得用。若sFilterConfig.BankNumber=27,则所有过滤器组分配给CAN1使用,CAN2就没得用了。
具体结合到本案例,客户代码里对CAN1、CAN2的过滤器进行配置时,当前过滤器组始终为0,即sFilterConfig.FilterNumber=0,而分配给CAN2的过滤器组又是从BANK 14开始的,即sFilterConfig.BankNumber = 14。
这样配置的话,CAN1接收,CAN2发的确不会有问题。反过来,CAN1发送,CAN2接收就会有问题。因为他一方面只是将Filter BANK 14到27分配给CAN2,同时又选择Filter BANK 0来配置CAN2的接收滤波器。所以要想CAN1发送,CAN2接收正常,其它参数不动的话,为CAN2配置滤波器时选择的过滤器组【Filter BANK】至少为14才可以,即sFilterConfig.FilterNumber=14。
2)CAN1正常,但是无法进入CAN2 中断,如下帖子描述:
问题帖:http://www.openedv.com/forum.php?mod=viewthread&tid=94488&extra=
出坑帖:http://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=607712&highlight=can+cube
里面说的很详细,就不多说。
3)CAN1 正常,但是CAN1发送数据,CAN2在接收数据时,会出现接收硬件错误
问题帖:http://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=618832
这个的出坑还是自己出的:FIFO0和FIFO1对应的RXMSG是不一样的,因为没有注意到,结果写成了一样,
hcan1.pRxMsg=&RxMsg;
hcan2.pRxMsg=&RxMsg;
实际应为:
hcan1.pRxMsg=&RxMsg;
hcan2.pRx1Msg=&RxMsg;
也就是问题帖中二楼说的,没有定义pRx1Msg,造成了pRxMsg是一个空指针,故报硬件错误。
4.总结
有问题欢迎多讨论。希望大家解决了问题的都能把帖子结一下,为自己,也为大家做点贡献。