STM32 LPTIM中断与低功耗睡眠模式重复触发问题咨询
STM32 LPTIM中断与低功耗睡眠模式重复触发问题咨询
您好,针对您遇到的LPTIM无法重复触发中断的问题,我结合您的代码逻辑和STM32低功耗模式的运行机制,梳理出几个核心问题点和对应的解决方案:
一、当前代码的核心问题
您在LPTIM1_IRQHandler中断处理函数里直接调用HAL_PWREx_EnterSTOP2Mode和重启LPTIM的逻辑,是导致后续无法触发中断的主要原因:
- 中断处理完成后,系统会自动回到进入中断前的上下文(也就是第一次进入STOP模式前的代码位置),这种在中断内嵌套进入睡眠的操作会打乱系统的执行流程,甚至导致LPTIM的中断标志、寄存器状态没有被正确清理或恢复。
- STOP2模式下,若LPTIM的时钟源配置不正确(比如使用了在STOP模式下会停止的时钟),也会导致LPTIM无法重新计数。
二、修正后的代码逻辑与实现
我们需要把睡眠模式触发、LPTIM重启的逻辑放回主循环,中断处理函数只负责计数、状态更新和条件判断,这样就能保证每次唤醒后流程清晰,LPTIM可以重复触发。
1. 全局变量保持(假设您已定义)
uint8_t timeout_mov = 0; // 触发EXTI后的计数变量 uint8_t timeout = 0; // 未触发EXTI的计数变量 bool b_movement = false; // EXTI触发标志 bool b_wkup = true; // 主循环控制标志
2. 主循环调整
while (b_wkup) { // 每次唤醒后,重新启动LPTIM超时中断 HAL_LPTIM_TimeOut_Start_IT(&hlptim1, 0xFFFF, 2500); // 进入STOP2低功耗模式,等待中断唤醒 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); // 唤醒后重置标志,确保循环继续执行 b_wkup = true; }
3. EXTI中断处理函数(保持原有逻辑,增加计数器重置)
void EXTI15_10_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(INT2_Pin); // 标记EXTI触发,切换计数模式 b_movement = true; // 重置无运动状态的计数器,避免两种计数逻辑冲突 timeout = 0; }
4. LPTIM中断处理函数(简化逻辑,仅处理计数与复位)
void LPTIM1_IRQHandler(void) { // 先让HAL库处理底层中断标志清理等操作 HAL_LPTIM_IRQHandler(&hlptim1); if (b_movement) { timeout_mov++; // 达到3次计数,触发复位 if (timeout_mov >= 3) { timeout_mov = 0; b_movement = false; HAL_NVIC_SystemReset(); } } else { timeout++; // 达到15次计数,触发复位 if (timeout >= 15) { timeout = 0; HAL_NVIC_SystemReset(); } } // 无需在此处启动LPTIM或进入睡眠,主循环会处理后续流程 }
三、关键配置注意事项
LPTIM时钟源确认:
在STM32CubeMX中,务必将LPTIM的时钟源设置为LSI或LSE(这两个时钟在STOP2模式下会持续运行),并在RCC的Power Settings里开启对应时钟在STOP模式下的保持功能。中断优先级配置:
在NVIC配置中,确保EXTI中断的优先级高于LPTIM,这样EXTI触发时能及时打断当前的LPTIM计数逻辑,避免计数错误。HAL回调函数优化(可选):
您也可以将计数逻辑放到HAL的回调函数中,更符合HAL库的使用规范:void HAL_LPTIM_TimeOutCallback(LPTIM_HandleTypeDef *hlptim) { if (hlptim->Instance == LPTIM1) { if (b_movement) { timeout_mov++; if (timeout_mov >= 3) { timeout_mov = 0; b_movement = false; HAL_NVIC_SystemReset(); } } else { timeout++; if (timeout >= 15) { timeout = 0; HAL_NVIC_SystemReset(); } } } }
四、修正后的执行流程
- 主循环启动LPTIM超时中断,随后进入STOP2模式;
- 当LPTIM计数完成,触发中断唤醒MCU,中断处理函数完成计数判断后退出;
- 系统回到主循环,重新启动LPTIM并再次进入STOP2模式;
- 若EXTI中断触发,MCU被唤醒并切换计数模式,随后主循环重复上述流程;
- 当计数达到设定阈值时,触发系统复位。
备注:内容来源于stack exchange,提问作者Faiz-983654




