最近的一个项目中,出现CAN总线中出现错误帧,导致MCU掉线的情况。认定是MCU进入了Bus-Off状态,所以原本应由MCU发送的CAN报文都无法从总线上读取到。
在这里记录一下,如何在STM32CubeMX中进行配置,以及如何使用STM32-HAL库中的CAN故障处理的中断服务函数。
首先,如果只是为了解决MCU进入Bus-Off的情况,可以直接在CubeMX中对相应的CAN通道进行配置,如下图所示:
完成该项配置后,重新编译工程,当MCU进入Bus-Off状态后,应该就可以自动恢复。
如果开发者希望在出现Bus-Off的状态后,进行一定的操作,可以在CubeMX中,先勾选对应CAN通道的中断使能选项(这里由于我使用的是CAN1通道,因此勾选CAN1的SCE interrupt即可),如下图所示:
在勾选此选项后,生成代码,可以在对应的工程中发现CAN的初始化代码中有以下代码:
之后,需要在can.c或是相对应的can通信的源文件中,编写故障处理中断函数,函数原型为:
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
在这个函数中可以对CAN的寄存器(CAN1->ESR)数值进行读取,从而判断当前的故障原因,也可以通过对hcan中的元素ErrorCode进行读取。我们简单地编写一下,如下图所示:
这样便可以在出现Bus-Off故障时进行一些额外操作了。
注意,进行完以上的所有工作,还需要在初始化时添加以下代码,该语句的功能是对CAN1通道使能Bus-Off中断:
__HAL_CAN_ENABLE_IT(&hcan1,CAN_IT_BUSOFF);
其他:
进行测试时,我注意到CAN的中断中还有一个CAN_IT_ERROR,但是在我只使能CAN_IT_ERROR而不使能CAN_IT_BUSOFF时,出现Bus-Off状态时,并不能进入HAL_CAN_ErrorCallback函数。这一点还需要注意。