问题一描述:CAN初始化就返回到Error_Handler,无法初始化通过。
经过单步调试,程序一直while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)卡在这步,无法退出休眠模式响应,直到超时:
/* Exit from sleep mode */
CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
/* Get tick */
tickstart = HAL_GetTick();
/* Check Sleep mode leave acknowledge */
while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 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;
}
}
原因分析:
通过示波器抓到波形,发现CAN_RX引脚一直时低电平,而在初始化时,是有上拉的(CAN要上线的话必须等待RX上有足够长的"隐性"信号,如果没有加收发器或者没有上拉的话,这个RX上的信号是不对的,所以就会超时了):
所以,软件配置是没有错的。需要确认硬件,发现硬件CAN芯片有边东,由之前的TJA1042改成了TJA1042T/3/1J,由于时间原因,没有具体去分析两者之间的区别(待有时间再去分析)。直接替换成之前的TJA1042即正常。
解决方案:
替换了芯片原因导致,换回之前的TJA1042芯片即可。
问题二描述:串口接收不到数据
在调试过程中,因为用到的串口比较多,数据接收比较频繁,其中某一路串口一直接收不到数据,其他的串口正常。
原因分析:
因为串口数据接收比较频繁,各路串口的优先级配置都是一样,发现某一路串口一直出现ORE错误,导致此路串口数据接收不到,一直进入ORE错误处理函数中。
解决方案:
针对不同的串口接收,按照数据的输出频率和接收数据优先级进行重新分配,针对每一组串口对ORE错误处理。
问题三描述:每次从boot跳到App后,就立马进入hardfault。
单独跑APP的代码没问题,每次从Boot跳到APP后,就立马进入hardfault。无法进入main入口。
原因分析:
单步调试发现,应用每次SystemInit完成后,一退出SystemInit进入main,就进入hardfault。发现程序根本没办法运行,可是单独跑boot和app都没问题,就说明boot和app代码都是没问题的。整合后在一起就出问题。而整合后只有代码空间变大,所以,怀疑是不是因为芯片选型导致。经过一番查找,终于在keil—>Option—>debug—>settings—>Flash Download—>Programming Algorithm中选择的文件仍然还stm32的,导致flash空间范围不对。
进入低功耗模式,发现设备可以正常进入休眠,但是无法用外部中断唤醒。
原因分析:
1.先确认外部中断是否能正常触发。在正常工作时,通过配置外部中断并达到触发条件,查看外部中断是否正常产生。
2.在HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI)前后,配置一个LED的灭亮,来判断是否可以通过外部中断唤醒。有以下两种情况:
a. 如果触发中断后,LED灯一直都是灭的状态,说明外部中断无法唤醒。需要查看HAL_PWR_EnterSTOPMode接口。
b. 如果触发中断后,LED灯从灭到亮,可以判断外部中断其实是唤醒的,是因为后面唤醒后重新初始化导致系统未跑起来。
解决方案:
对于上述a情况而言,跟厂商这边有进一步沟通,答复说是因为使用的是HAL库,调用这个接口时,其实还需要对HAL_PWR_EnterSTOPMode接口中,增加修改内核相关的一些代码,添加如下:
对于上述b情况很好解决,只需要一步步去重新初始化各部分外设,再判断问题是出在哪里。