- CAN初始化时,程序会在函数HAL_CAN_Init执行时报错,仿真发现是在等待初始化确认时超时导致。查阅了ST和GD的参考手册,二者对初始化确认位的描述并无差异,推测是GD的bug。
ST的描述,见下图:

GD的描述,见下图:

对此,解决办法是屏蔽掉对初始化确认位的检测,需注释掉stm32f4xx_hal_can.c文件中的部分代码,如下:
/* 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;
// }
// }
- 使用函数HAL_CAN_AddTxMessage连续发送数据时,只有第一帧数据正常发送。查阅了ST和GD的参考手册,二者在发送状态寄存器对邮箱代码位的描述有差异,ST邮箱代码位代表的含义为下一个空闲发送邮箱号,GD对应位代表的含义为下一个将要发送的邮箱号。
ST的描述,见下图:

GD的描述,见下图:

对此,解决办法是修改stm32f4xx_hal_can.c文件中函数HAL_CAN_AddTxMessage的部分代码,如下:
/* Select an empty transmit mailbox */
// transmitmailbox = (tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos;
if (CAN_TSR_TME0 == (tsr & CAN_TSR_TME0))
transmitmailbox = 0;
else if (CAN_TSR_TME1 == (tsr&CAN_TSR_TME1))
transmitmailbox = 1;
else if(CAN_TSR_TME2 == (tsr&CAN_TSR_TME2))
transmitmailbox = 2;
else
transmitmailbox = 3;
参考文献
GD32F303 CAN记录

博客详细讨论了在STM32和GD32微控制器上使用CAN接口时遇到的初始化超时和数据发送异常问题。针对CAN初始化时的初始化确认超时,解决方案是屏蔽初始化确认位的检测。而在发送数据时,由于ST和GD对于发送状态寄存器的描述差异,导致只有第一帧数据能正常发送,修复方法是调整查找空闲邮箱的逻辑。这些问题的出现揭示了不同供应商芯片间可能存在兼容性问题,需要对硬件和固件进行适配调整。
1万+





