stm32f103 RTC周期性待机唤醒(一)

来源:互联网 发布:手机淘宝截图生成器 编辑:程序博客网 时间:2024/05/01 15:15

转载于http://blog.csdn.net/u011732167/article/details/50958520

今天终于发现问题出在哪里了,对待机唤醒的问题做一个总结(只针对我遇到的问题,其他部分网上都有,基于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、下面是我的一些代码

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  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();           <span style="white-space:pre">    </span>//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);   </span>  
  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();     <span style="white-space:pre">    </span>//等待写入完成  
  32.   }  
  33.   RCC_ClearFlag();              //清除复位标志  
[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  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. }  
[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  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. }  
[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  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. }  
[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  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. }  
0 0
原创粉丝点击