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
相关产品推荐
相关产品推荐

