Chen Aki
Chen Aki

Reputation: 1

STM32F429: CAN cannot receive message from host PC

I am trying to use my STM32F429IGT6 CAN to receive some data from the host computer. The data is basically 4 16-bit unsigned integers (8 bytes in total), the message ID is 0x16 and uses the 11-bit standard ID format. The host computer sends messages to the bus in a 2ms cycle.

On the STM32 part, I enabled CAN1 (CAN2 is disabled) and used the interrupt function to receive and process the data. However, most of the time, the STM32 does not show any CAN messages coming, and the HAL_CAN_GetRxFifoFillLevel() function always returns 0. This makes me really confused.

Below is the initialization code in my can.c file. My CAN1 is mounted on the APB1 bus with a frequency of 45Mhz, and the CAN transmission rate of the host computer and STM32 is 500kbps.

void MX_CAN1_Init(void)
{

  /* USER CODE BEGIN CAN1_Init 0 */
  
  /* USER CODE END CAN1_Init 0 */

  /* USER CODE BEGIN CAN1_Init 1 */

  /* USER CODE END CAN1_Init 1 */
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 6;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_8TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_6TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = ENABLE;
  hcan1.Init.AutoRetransmission = ENABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN1_Init 2 */
  
  CAN_FilterTypeDef sFilterConfig;

  sFilterConfig.FilterBank = 0;
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterIdHigh = 0x0000;
  sFilterConfig.FilterIdLow = 0x0000;
  sFilterConfig.FilterMaskIdHigh = 0x0000;
  sFilterConfig.FilterMaskIdLow = 0x0000;
  sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
  sFilterConfig.FilterActivation = ENABLE;
  sFilterConfig.SlaveStartFilterBank = 14;
  if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }

  if (HAL_CAN_Start(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE END CAN1_Init 2 */

}

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(canHandle->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspInit 0 */

  /* USER CODE END CAN1_MspInit 0 */
    /* CAN1 clock enable */
    __HAL_RCC_CAN1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**CAN1 GPIO Configuration
    PA11     ------> CAN1_RX
    PA12     ------> CAN1_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* CAN1 interrupt Init */
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
    HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
    HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
  /* USER CODE BEGIN CAN1_MspInit 1 */
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
  /* USER CODE END CAN1_MspInit 1 */
  }
}

and this is my interrupt funciton:

CAN_RxHeaderTypeDef RxHeader;
uint16_t RxData[4];
uint16_t canbuf[4];   /* CAN rx dest */

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, (uint8_t *)RxData) == HAL_OK)
    {
        for (int i = 0; i < RxHeader.DLC / 2; i++)
        {
            canbuf[i] = RxData[i];
        }
    }
}
  1. Confirm that the 120 ohm terminal resistors on both sides of the CAN have been added. The CAN cable is a standard twisted pair with a DB9 interface and is well connected.

  2. The CAN configuration of the host computer is in send mode, using the standard 11-bit ID mode, the ID value is 18 (0x12), the data segment is 8 bytes, the baud rate is 500kbps (consistent with STM32), and the message transmission rate is 2ms once.

  3. I tried to monitor the ESR register (error register) of CAN1 in real time through debug mode, but no abnormalities were found. All flag bits look normal (all 0).

  4. I confirmed that I have called the HAL_CAN_Start() and HAL_CAN_ActivateNotification() functions normally.

  5. I see someone else say that maybe is the filter cause the error, so I even tried disabling the filter, but same result.

The one thing I have left to do is to test the CAN message levels sent by the host computer through a logic analyzer (the analyzer is on the way), but I think the possibility of an error in the host computer is low.

Before this, I also tried to use the polling function in while(1) in main.c to get messages, but I still couldn't receive any messages.

Upvotes: 0

Views: 10

Answers (0)

Related Questions