Through debugging, it is found that the CAN bus of STM32 is in the wake-up state during initialization (the CAN_MSR_SLAK bit of the MSR register is set), resulting in a timeout error when the initialization status bit (the CAN_MSR_INAK bit of the MSR register) is set to 1. The initialization program is located in the HAL_CAN_Init function of the stm32f1xx_hal_can.c file, as follows:
/* 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;
}
}
In order to solve this error, you can add the CAN wake-up operation before judging whether the initialization status bit ( CAN_MSR_INAK bit of the MSR register) is set to 1. The code after joining is as follows:
/* 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 can initialize pin stm32
question
The STM32 control board (there is only one cpu minimum system on it), found that if it is powered by itself, the program often cannot start normally; if it is connected to the system, it can be started normally after the control board is inserted into the card slot and connected to the peripheral board.
At first, it was suspected to be a problem with the boot pin, but after investigation, it was found that it was not the reason.
Finally, the problem is located in the floating RX pin of CAN.
reason
The root cause is: the CAN_RX pin is floating, causing the CAN initialization to fail.
(1) CAN hardware initialization requires continuous monitoring of 11 invisible bits on the RX pin. It is not clear here whether the recessive bit corresponds to the RX pin of stm32 is high or low.
(2) When the control board is separated from the peripheral board, the RX pin is floating, and its level is uncertain. It is easy to cause can initialization failure.
(3) When the program starts to initialize, waiting for CAN initialization to complete will time out, resulting in initialization failure.
(4) If the initialization fails, it will enter the Error_Handler function and hang there all the time.
Three, the solution
- Do not leave the RX pin floating, causing its level to be unknown.
- Modify the Error_Handler function so that it can report a fault when the fault is initialized, such as flashing a light or sending a fault message.