通过debug发现STM32的CAN总线在初始化时处于唤醒状态(MSR寄存器的CAN_MSR_SLAK位置1),导致执行初始化状态位(MSR寄存器的CAN_MSR_INAK位)是否置1时,发生超时错误。该初始化程序位于stm32f1xx_hal_can.c文件的HAL_CAN_Init函数内,如下:
/* Wait initialisation acknowledge */
while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
{
if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
{
/* Update error code */
hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
/* Change CAN state */
hcan->State = HAL_CAN_STATE_ERROR;
return HAL_ERROR;
}
}
为了解决该错误,可以在判断初始化状态位(MSR寄存器的CAN_MSR_INAK位)是否置1前加入CAN的唤醒操作即可。加入后代码如下:
/* Exit from sleep mode */
CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
/* Wait initialisation acknowledge */
while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
{
if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
{
/* Update error code */
hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
/* Change CAN state */
hcan->State = HAL_CAN_STATE_ERROR;
return HAL_ERROR;
}
}