You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F429 CAN无法接收上位机数据的排查求助

STM32F429 CAN1无法接收上位机消息问题排查

我正尝试使用STM32F429IGT6的CAN外设接收上位机发送的数据,数据为4个16位无符号整数(共8字节),消息ID为0x16,采用11位标准ID格式,上位机以2ms周期发送消息。

在STM32端,我启用了CAN1(CAN2未启用),使用中断函数接收并处理数据,但多数情况下STM32无CAN消息接收,HAL_CAN_GetRxFifoFillLevel()始终返回0,这让我十分困惑。

我的CAN挂载在APB1总线,总线频率为45MHz,上位机与STM32的CAN传输速率均为500kbps。

CAN初始化代码(can.c)

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 */
  }
}

CAN中断接收函数

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];
        }
    }
}

已完成的排查步骤

  • 确认CAN总线两端已添加120Ω终端电阻,CAN线缆为标准双绞线带DB9接口且连接正常。
  • 上位机CAN配置为发送模式,采用11位标准ID,ID值为18(0x12),数据段8字节,波特率500kbps(与STM32一致),消息发送周期2ms。
  • 通过调试模式实时监控CAN1的ESR寄存器(错误寄存器),未发现异常,所有标志位均为0。
  • 确认已正常调用HAL_CAN_Start()和HAL_CAN_ActivateNotification()函数。
  • 曾尝试禁用CAN过滤器,但结果仍相同。

目前仅剩的排查手段是用逻辑分析仪检测上位机发送的CAN消息电平(分析仪尚未到货),但我认为上位机出错概率较低。此前我也尝试在main.c的while(1)中使用轮询方式获取消息,仍无法接收任何数据。

内容的提问来源于stack exchange,提问作者Chen Aki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:17:08