STM32F1的RTC调试记录
闲来无事,折腾一个电子手表。
发现需要一个低功耗模式。
查资料发现,有三种低功耗模式,睡眠、停止、待机。其中待机最低功耗。
于是搜索怎么进入。很简单
void Sys_Enter_Standby(void) { __HAL_RCC_APB2_FORCE_RESET(); //复位所有 IO 口 __HAL_RCC_PWR_CLK_ENABLE(); //使能 PWR 时钟 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); //清除 Wake_UP 标志 HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); //设置 WKUP 用于唤醒 HAL_PWR_EnterSTANDBYMode(); //进入待机模式 }
几句话就进入了。问题来了,怎么唤醒。
查到有4步。目前这个板可以试的只有2.3.4。镊子试了一下NRST,不行。
看起来试一下RTC闹钟事件最快。
在RTC的配置里面发现可以配置一个闹钟
/** Initialize RTC and set the Time and Date */ sTime.Hours = 0x19; sTime.Minutes = 0x48; sTime.Seconds = 0x0; if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } DateToUpdate.WeekDay = RTC_WEEKDAY_SUNDAY; DateToUpdate.Month = RTC_MONTH_MAY;//RTC_MONTH_OCTOBER; DateToUpdate.Date = 0x18; DateToUpdate.Year = 0x22; if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } /** Enable the Alarm A */ sAlarm.AlarmTime.Hours = 0x19; sAlarm.AlarmTime.Minutes = 0x50; sAlarm.AlarmTime.Seconds = 0x30; sAlarm.Alarm = RTC_ALARM_A; HAL_RTC_SetAlarm(&hrtc, &sAlarm, RTC_FORMAT_BCD); if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); }
但中断函数在哪呢。
在rtc库函数发现这个
/** * @brief This function handles Alarm interrupt request. * @param hrtc pointer to a RTC_HandleTypeDef structure that contains * the configuration information for RTC. * @retval None */ void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc) { if (__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA)) { /* Get the status of the Interrupt */ if (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != (uint32_t)RESET) { /* AlarmA callback */ #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) hrtc->AlarmAEventCallback(hrtc); #else HAL_RTC_AlarmAEventCallback(hrtc); #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ /* Clear the Alarm interrupt pending bit */ __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF); } } /* Clear the EXTI's line Flag for RTC Alarm */ __HAL_RTC_ALARM_EXTI_CLEAR_FLAG(); /* Change RTC state */ hrtc->State = HAL_RTC_STATE_READY; }
那中断函数应该是这个
HAL_RTC_AlarmAEventCallback(hrtc);
写了一个指示灯函数在里面,测试发现达到时间后并没有进入。看来是中断没有配置好。又增加这个:
HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 1, 0); // __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF); HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn); HAL_NVIC_SetPriority(RTC_IRQn, 2, 1); HAL_NVIC_EnableIRQ(RTC_IRQn);
发现一到时间,程序就死机,中断进不去。判断应该是中断入口不对。
查看启动文件,发现中断函数是 EXPORT RTC_Alarm_IRQHandler [WEAK]
搜索整个工程,发现没有这个函数。
果断加入这个函数
void RTC_Alarm_IRQHandler(void) { HAL_RTC_AlarmIRQHandler(&hrtc); }
这回中断可以进入了。
期间发现两个问题,一是想用cubemx配置闹钟中断,发现rtc配置里面根本就没有闹钟这一项。
以为是版本问题,升级到最新也没有。网上查询发现有些型号有,就F1系列没有。
NVIC栏倒是有一个闹钟中断可以配置优先级。配置之后生成,也没有生成
void RTC_Alarm_IRQHandler(void)函数。这绝对是cube软件问题,坑。
另外发现一个问题,RTCAlarm_IRQn(高优先级)和RTC_IRQn(低优先级)
像这个链接说的事情确实:https://www.86ic.net/ziliao/beidong/255921.html
"发现闹钟中止使能后,假如使能了秒中止,则秒中止标志会置位:"
处理方式是,让RTCAlarm_IRQn中断优先级比RTC_IRQn高。而且实测发现,RTCAlarm_IRQn响应的时候,RTC_IRQn也会响应;但
RTCAlarm_IRQn不响应,RTC_IRQn秒中断时间到它也不响应。还有一个方式是禁用RTC_IRQn中断。
现在闹钟中断可以进入了,试一下唤醒待机。还是不行。
查询网上说,RTCAlarm_IRQn连接到了EXTILine17,甚至在标准库里面还有这个配置:
EXTI_InitStructure.EXTI_Line = EXTI_Line17;//LINE17 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能LINE17 EXTI_Init(&EXTI_InitStructure);//配置[/mw_shl_code]
说是这样配置,才能唤醒。但是在hal库里面,没有找到EXTI_Line17的定义。黑人问号??百思不得其解情况下,查了很久没有HAL库唤醒的代码涉及到EXTI的。
后来查到一个关键信息:
从RTC的定时器特性来说,它是一个32位的计数器,只能向上计数。它使用的时钟源有三种,分别为高速外部时钟的128分频(HSE/128)、低速内部时钟LSI以及低速外部时钟LSE;使HSE分频时钟或LSI的话,在主电源VDD掉电的情况下,这两个时钟来源都会受到影响,因此没法保证RTC正常工作。因此RTC一般使用低速外部时钟LSE,在设计中,频率通常为实时时钟模块中常用的32.768KHz,这是因为32768=2^15,分频容易实现,所以它被广泛应用到RTC模块。在主电源Vpp有效的情况下(待机),RTC还可以配置闹钟事件使STM32退出待机模式。
查了一下,目前程序竟然是用的HSE!但板上没有LSE,只能改成LSI试试。
万幸是我的板子待机后,主电源VDD不是掉电的,所以待机后LSI可以工作,但HSE就不行了!应该是待机后切断了。
这样测试可以唤醒后,EXTI_Line17的事就清楚了:HAL根本不需要配置什么EXTI17,只要RTC闹钟可以进中断,并且闹钟时钟源选择LSE或LSI即可。
从停止模式进入闹钟中断,唤醒后从进入中断,然后回到停止地方继续执行;从待机模式进入闹钟中断,唤醒后相当于Reset;reset后没有标志位可以标记是从待机恢复的,需要使用备份寄存器才行。
进入停止模式,是需要配置唤醒方式的,
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE); // 进入STOP模式
PWR_STOPENTRY_WFE事件唤醒,PWR_STOPENTRY_WFI,引脚唤醒。
整个调试过程,其实很简单,发现这位写的比较好
https://blog.csdn.net/qq_39061579/article/details/107061185
感谢。https://zhuanlan.zhihu.com/p/515982984
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律