历史上的今天
返回首页

历史上的今天

今天是:2025年03月29日(星期六)

2019年03月29日 | stm32f103 RTC周期性待机唤醒(一)

2019-03-29 来源:eefocus

做一个低功耗的东西,搞了好几天,程序一直卡在一个地方(见下图),今天终于发现问题出在哪里了,对待机唤醒的问题做一个总结(只针对我遇到的问题,其他部分网上都有,基于stm32f103)



1、解决我遇到的问题

       我的RTC初始化部分有个“保存在备份寄存器的RTC标志是否已经被配置过的判断”,如果已经配置过,则进入else部分,但是这个else部分没有“要使能电源时钟,使能备份时钟,取消后备区的写保护”这些配置语句,而待机唤醒后程序从主函数执行,会执行到else部分,因为没有那些配置语句,所以再次对闹钟赋值就会不成功,就会卡在那里。(那些配置语句在clock_ini函数里,有注释)


2、待机用不用加extiline17事件

如果把闹钟中断的服务程序放在void RTC_IRQHandler(void)里面处理的话,不需要extiline17事件也可以唤醒(亲测),如果闹钟中断的服务程序放在void RTCAlarm_IRQHandler(void)里面处理的话,需要extiline17事件


3、RTCAlarm_IRQn和RTC_IRQn优先级

我见到网上说要把RTCAlarm_IRQn的优先级设置比RTC_IRQn优先级高,但是把闹钟中断的服务程序放在void RTC_IRQHandler(void)里面处理的话,不用这样设置也可以。如果闹钟中断的服务程序放在void RTCAlarm_IRQHandler(void)里面处理的话需要设置优先级,最好根据情况先把优先级的问题解决清楚


4、下面是我的一些代码

 

 

  1. void Clock_ini(void)

  2. {

  3. if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) //判断保存在备份寄存器的RTC标志是否已经被配置过

  4. {

  5. printf("\r\n\n RTC not yet configured....");

  6. RTC_Configuration(); //RTC初始化

  7. printf("\r\n RTC configured....");

  8. Time_Adjust(); //设置RTC 时钟参数

  9. BKP_WriteBackupRegister(BKP_DR1, 0xA5A5); //RTC设置后,将已配置标志写入备份数据寄存器

  10. }

  11. else

  12. {

  13. if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET) //检查是否掉电重启

  14. {

  15. printf("\r\n\n Power On Reset occurred....");

  16. }

  17. else if(RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET) //检查是否reset复位

  18. {

  19. printf("\r\n\n External Reset occurred....");

  20. }

  21. printf("\r\n No need to configure RTC....");

  22. /***新加的,测试,待机唤醒后,程序不经过上面的if部分,所以没有这三步(两个语句),所以程序会卡,所以加上,果然***/

  23. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  24. /* 允许访问BKP区域 */

  25. PWR_BackupAccessCmd(ENABLE);

  26.  

  27. RTC_WaitForSynchro(); //等待RTC寄存器被同步

  28. RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能秒中断

  29. RTC_WaitForLastTask();

  30. RTC_ITConfig(RTC_IT_ALR, ENABLE); //naozhong

  31. RTC_WaitForLastTask(); //等待写入完成

  32. }

  33. RCC_ClearFlag(); //清除复位标志

 
  1. void NVIC_Configuration(void)

  2. {

  3. NVIC_InitTypeDef NVIC_InitStructure;

  4. EXTI_InitTypeDef EXTI_InitStructure;

  5.  

  6. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  7.  

  8. /* Enable the RTC Interrupt */

  9. NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //配置外部中断源(秒中断)

  10. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  11. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;

  12. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  13. NVIC_Init(&NVIC_InitStructure);

  14.  

  15. /* Enable the RTC Alarm Interrupt */

  16. NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn; //配置外部中断源(闹钟中断)

  17. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  18. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

  19. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  20. NVIC_Init(&NVIC_InitStructure);

  21.  

  22. //闹钟中断接到第17线外部中断

  23. EXTI_ClearITPendingBit(EXTI_Line17);

  24. EXTI_InitStructure.EXTI_Line = EXTI_Line17;

  25. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  26. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

  27. EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  28. EXTI_Init(&EXTI_InitStructure);

  29. }

 
  1. void RTC_Configuration(void)

  2. {

  3. /* 使能 PWR 和 BKP 的时钟 */

  4. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  5. /* 允许访问BKP区域 */

  6. PWR_BackupAccessCmd(ENABLE);

  7. /* 复位BKP */

  8. BKP_DeInit();

  9. #ifdef RTCClockSource_LSI

  10. /* 使能内部RTC时钟 */

  11. RCC_LSICmd(ENABLE);

  12. /* 等待RTC内部时钟就绪 */

  13. while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)

  14. {

  15. }

  16. /* 选择RTC内部时钟为RTC时钟 */

  17. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

  18. #elif defined RTCClockSource_LSE

  19. /* 使能RTC外部时钟 */

  20. RCC_LSEConfig(RCC_LSE_ON);

  21. /* 等待RTC外部时钟就绪 */

  22. while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)

  23. {

  24. }

  25. /* 选择RTC外部时钟为RTC时钟 */

  26. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  27. #endif

  28. /* 使能RTC时钟 */

  29. RCC_RTCCLKCmd(ENABLE);

  30.  

  31.  

  32. #ifdef RTCClockOutput_Enable

  33. /* Disable the Tamper Pin */

  34. BKP_TamperPinCmd(DISABLE); /* To output RTCCLK/64 on Tamper pin, the tamper

  35. functionality must be disabled */

  36.  

  37. /* 使能在TAMPER脚输出RTC时钟 */

  38. BKP_RTCCalibrationClockOutputCmd(ENABLE);

  39. #endif

  40.  

  41. /* 等待RTC寄存器同步 */

  42. RTC_WaitForSynchro();

  43.  

  44. /* 等待写RTC寄存器完成 */

  45. RTC_WaitForLastTask();

  46.  

  47. /* 使能RTC naozhong中断 */

  48. RTC_ITConfig(RTC_IT_ALR, ENABLE);

  49.  

  50. /* 等待写RTC寄存器完成 */

  51. RTC_WaitForLastTask();

  52.  

  53. /* 使能RTC秒中断 */

  54. RTC_ITConfig(RTC_IT_SEC, ENABLE);

  55.  

  56. /* 等待写RTC寄存器完成 */

  57. RTC_WaitForLastTask();

  58.  

  59. /* 设置RTC预分频 */

  60. #ifdef RTCClockSource_LSI

  61. RTC_SetPrescaler(31999); /* RTC period = RTCCLK/RTC_PR = (32.000 KHz)/(31999+1) */

  62. #elif defined RTCClockSource_LSE

  63. RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */

  64. #endif

  65.  

  66. /* 等待写RTC寄存器完成 */

  67. RTC_WaitForLastTask();

  68. }

 
  1. void RTCAlarm_IRQHandler(void)

  2. {

  3. RTC_WaitForSynchro();

  4. if(RTC_GetITStatus(RTC_IT_ALR) != RESET)

  5. {

  6. //printf("mmmmmm");

  7. EXTI_ClearITPendingBit(EXTI_Line17);

  8. RTC_WaitForLastTask();

  9. if(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)

  10. {

  11. // 清除唤醒标志

  12. PWR_ClearFlag(PWR_FLAG_WU);

  13. RTC_WaitForLastTask();

  14. }

  15. RTC_ClearITPendingBit(RTC_IT_ALR);

  16. RTC_WaitForLastTask();

  17. printf("\nIt will wake up after %d s\n",standbytime);

  18. RTC_Enter_StandbyMode(standbytime);//standbytime秒后唤醒

  19. }

  20. }

 
  1. void RTC_Enter_StandbyMode(u32 s)

  2. {

  3. RTC_WaitForLastTask();

  4. RTC_SetAlarm(RTC_GetCounter()+s);

  5. RTC_WaitForLastTask();

  6. // 进入待机模式, 此时所有1.8V域的时钟都关闭,HIS和HSE的振荡器关闭, 电压调节器关闭.

  7. // 只有WKUP引脚上升沿,RTC警告事件,NRST引脚的外部复位,IWDG复位.

  8. /* Request to enter STANDBY mode (Wake Up flag is cleared in PWR_EnterSTANDBYMode function) */

  9. PWR_EnterSTANDBYMode();

  10. }

5、接下来几天我要研究一下停机模式和功耗问题


推荐阅读

史海拾趣

弘凯光电(BRIGHTEK)公司的发展小趣事

2021年,弘凯光电在江苏南通投资建设了集成智慧光源项目,总投资额高达10亿元。这一项目的建成,不仅大幅提升了公司的产能和效率,更为汽车照明、智能家居、3C电子等LED高端应用领域提供了高品质的产品。项目的成功投产,标志着弘凯光电在光电半导体领域的技术实力和市场地位得到了进一步提升。

EUDYNA公司的发展小趣事

在光通信领域,EUDYNA凭借其10Gb/s速率的光调制集成DFB激光器模块,取得了重要突破。这款模块采用了先进的封装技术和内置光学隔离器,确保了信号的稳定性和可靠性。EUDYNA的这一创新,不仅提高了光通信的传输速度和效率,也为整个行业树立了新的标杆。

Exclara Inc公司的发展小趣事

随着LED技术的不断发展和市场需求的不断变化,Exclara看到了新的市场机遇。公司凭借在LED领域的技术积累和市场经验,成功进军了智能家居、智能照明等新兴市场。在这些新兴市场中,公司凭借其独特的技术优势和创新能力,迅速获得了市场份额和客户的认可。面对新的市场挑战和机遇,Exclara将继续保持创新精神和技术实力,为电子行业的发展贡献更多的力量。

请注意,以上故事框架仅供参考,具体内容和细节需要根据实际情况进行补充和完善。

Cogent_Computer_Systems公司的发展小趣事

随着国内市场的逐渐饱和,Cogent_Computer_Systems公司开始将目光投向海外市场。公司制定了一系列国际化战略,包括参加国际电子展会、建立海外销售网络、拓展国际合作伙伴等。这些举措使得公司的产品和服务逐渐走向全球,赢得了更多国际客户的认可。国际化战略的实施不仅拓宽了公司的市场版图,也提升了公司的品牌影响力和国际竞争力。

General Transistor Corp公司的发展小趣事

为了进一步巩固市场地位和提升竞争力,GTC开始实施并购整合战略。公司通过收购具有技术优势和市场潜力的企业,实现了技术、产品和市场的快速扩张。同时,GTC还积极寻求战略转型,从单一的电子元器件分销商和生产商向综合性电子解决方案提供商转变。这一战略转型为公司带来了新的增长点和发展机遇。

Acme Electric Corporation公司的发展小趣事

在1976年,GTC(General Transistor Corp.)作为一家独立的电子元器件分销商和生产商在美国正式成立。这一时期,电子行业正处于快速发展阶段,晶体管、集成电路等新型电子元件的应用日益广泛。GTC凭借其敏锐的市场洞察力和技术实力,迅速在市场中站稳脚跟。公司初期专注于分销高质量的晶体管、二极管等电子元器件,并逐渐建立起稳定的供应链和客户群。

问答坊 | AI 解惑

电阻在线测试的新方法

电阻在线测试的新方法* 沈达逊 田成凤 (华中理工大学 武汉 430074)   摘要 电阻在线测试一般采用“隔离”技术。本文提出一种采用电阻网络变换原理的电阻在线测试新方法。从设计思路、测试原理、实测数据和误差分析等方面论述该方法的可行 ...…

查看全部问答>

一起来制作EZ_ICD2调试器

乾隆盛电子的一个制作小资料 与初学者的交流中,经常有人问怎么学单片机,怎么入门。搜遍了网上所有资料,几乎所有回答都是:先看书,然后动手做实验。提到实验就少不了工具,如实验板、编程器、调试器(仿真器)。由于调试器配合PC 机可以 ...…

查看全部问答>

时钟恢复电路设计

难得一见的资料,其它中文网站几乎没下载…

查看全部问答>

xilinx ise 11.1 license破解

xilinx ise 11.1的license,序列号,破解。完全版的。包含 IPcore,PCIe...因为是和网卡绑定的,再给多一个,共两个license。xilinx ISE 11.1 破解,序列号,license file 文件。crack…

查看全部问答>

请教WinCE6+CDMA模块拨号上网问题

我使用WinCe6+CDMA(Simware C218)拨号上网,老报错“端口被占用”不知道如何解决? 相同的平台使用Sim300D  GPRS拨号上网没有问题。 拨号连接里面有一个拨号选项,里面有一个附件设置,GPRS是填“+CGDCONT=1,IP”,\"CMNET\"在CDMA里 ...…

查看全部问答>

关于ui和菜单,急!

大家好:   谁对UI比较熟,还有就是做菜单的技术,菜单就像是彩屏手机里的菜单或是数字电视里的菜单等,这项技术如何实现,我开发过程中要用到,挺急的,请大家帮忙给我点建议或资料吧。先谢谢了。…

查看全部问答>

TDI SEND效率问题

大家好,我写了一个TDI的驱动,采用tcp协议,这个驱动的目的主要是把数据发送到服务器。但是我奇怪的是,send的效率非常低,但是recv的效率非常高,我看到网上很多人都碰到这个问题,有没有把这个问题解决了的?大家能指点一下吗?感谢不尽! NTST ...…

查看全部问答>

驱动程序安装错误 0xE000022B

打包用DPInst安装驱动, 修改了Inf中是  \"AddServer = ........\" 服务名之后,再安装就会出现错误 DPinst.log 中错误是 Installation failed Error code 0xE000022B 类别安装程序拒绝安装或更新此设备, 我想可能是之前安装的驱动 ...…

查看全部问答>

哈哈,俺告别"落伍",用上了RealviewMDK

兴奋中.... 相关链接:http://group.ednchina.com/999/…

查看全部问答>