STM32F103C6通过CAN总线唤醒CPU失败问题求助
CAN总线无法唤醒STM32F103C6的排查与解决
问题现象
尝试通过CAN总线唤醒STM32F103C6 CPU失败:总线数据可被处理器接收,但无法触发唤醒;GPIO中断可正常唤醒CPU,唤醒后能响应CAN总线上的最后3条数据。
硬件与配置信息
- CPU型号:STM32F103C6
- HAL中断配置:

相关代码
休眠处理代码
HAL_SuspendTick(); HAL_TIM_Base_Stop(&htim1); HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); HAL_TIM_Base_Start(&htim1); HAL_ResumeTick(); tick_sleep = HAL_GetTick();
CAN初始化配置代码
void MX_CAN_Init(void) { /* USER CODE BEGIN CAN_Init 0 */ /* USER CODE END CAN_Init 0 */ /* USER CODE BEGIN CAN_Init 1 */ /* USER CODE END CAN_Init 1 */ hcan.Instance = CAN1; hcan.Init.Prescaler = 6; hcan.Init.Mode = CAN_MODE_NORMAL; hcan.Init.SyncJumpWidth = CAN_SJW_1TQ; hcan.Init.TimeSeg1 = CAN_BS1_2TQ; hcan.Init.TimeSeg2 = CAN_BS2_1TQ; hcan.Init.TimeTriggeredMode = DISABLE; hcan.Init.AutoBusOff = ENABLE; hcan.Init.AutoWakeUp = ENABLE; hcan.Init.AutoRetransmission = ENABLE; hcan.Init.ReceiveFifoLocked = DISABLE; hcan.Init.TransmitFifoPriority = DISABLE; if (HAL_CAN_Init(&hcan) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN CAN_Init 2 */ HAL_CAN_Start(&hcan); CAN_FilterTypeDef sFilterConfig; sFilterConfig.FilterIdHigh = 0xFFFF; sFilterConfig.FilterIdLow = 0xFFFF; sFilterConfig.FilterMaskIdHigh = 0; sFilterConfig.FilterMaskIdLow = 0; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; sFilterConfig.FilterBank = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.SlaveStartFilterBank = 0; HAL_CAN_ConfigFilter(&hcan,&sFilterConfig); /* USER CODE END CAN_Init 2 */ }
排查与解决步骤
1. 确认CAN唤醒的核心前提
STM32F103C6的CAN模块在Sleep模式下触发唤醒,需满足:
- CAN控制器处于初始化完成且启动状态(代码中
HAL_CAN_Start(&hcan)已调用,此部分正常) - 系统时钟配置需保证CAN模块在Sleep模式下能接收总线信号:若用外部晶振,需确保Sleep模式下HSE未关闭;若用HSI,需确认其稳定性。
2. 检查CAN中断配置
从提供的中断配置图需确认:
- CAN RX中断已启用:必须开启CAN接收FIFO0满中断(
CAN_RX_FIFO0_MSG_PENDING),只有触发该中断才能唤醒WFI模式下的CPU。 - 中断优先级配置合理:确保CAN中断优先级未被低优先级中断屏蔽,且未设置为禁止唤醒的优先级(STM32F1需正确配置中断优先级分组,保证CAN中断的抢占/响应优先级不会被系统忽略)。
3. 修正CAN唤醒中断激活逻辑
代码中已开启AutoWakeUp = ENABLE,但需显式激活CAN接收中断:
在HAL_CAN_Start(&hcan)之后添加以下代码:
// 使能CAN RX FIFO0消息挂起中断,触发唤醒 HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
4. 调整CAN过滤配置顺序
建议将HAL_CAN_ConfigFilter移至HAL_CAN_Start之前,部分HAL版本要求先配置过滤规则再启动CAN控制器,否则过滤可能未生效。
5. 硬件层面排查
- 确认CAN收发器供电:Sleep模式下,CAN收发器需保持供电以接收总线信号并传递唤醒触发信号,若收发器进入低功耗模式则无法触发唤醒。
- 检查CAN总线终端电阻:确保终端电阻正常,避免信号衰减导致CAN模块无法识别唤醒帧。
验证步骤
- 添加CAN接收中断激活代码并调整过滤配置顺序
- 重新编译烧录后,发送CAN帧测试唤醒功能
内容的提问来源于stack exchange,提问作者Michał Skorupski
相关产品推荐
相关产品推荐

