关于GD32直接替换STM32时,CAN通讯接口初始化报错的解决方法__匿名好友的博客-CSDN博客
通过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的唤醒操作即可。加入后代码如下:
/* Request initialisation */
SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
/* Get tick */
tickstart = HAL_GetTick();
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;
}
}
问题
STM32的控制板(上面只有一个cpu最小系统),发现如果单独供电,程序经常不能正常启动;如果和系统连接起来,就是控制板插在卡槽里和外围板连起来后,就能正常启动。
最开始怀疑是boot引脚的问题,后来排查后发现不是这个原因。
最后问题定位在CAN的RX引脚悬空上。
原因
根本原因是: CAN_RX引脚悬空,导致CAN初始化失败。
(1) CAN硬件初始化,要求在RX引脚连续监测到11个隐形位。这里不太清楚隐性位对应stm32的RX引脚是高还是低。
(2) 当控制板和外围板分离时,RX引脚悬空,其电平不确定。容易造成can初始化失败。
(3) 程序启动初始化时,等待CAN初始化完成会超时,造成初始化失败。
(4) 初始化失败就会进入Error_Handler函数,就一直挂在那里。
三、解决办法
- 不要让RX引脚悬空,造成其电平未知。
- 修改Error_Handler函数,让其故障初始化时能报出故障来,比如闪灯或者发出故障报文。