stm32f103RTC闹钟唤醒时间不能设置

2019-08-17 05:06发布

本帖最后由 mousie 于 2016-12-20 17:26 编辑

新人求助,用RTC(LSI)唤醒停机模式是出现问题,不管"RTC_SetAlarm(10);"这里设置成多少,系统都在休眠后3-4s后唤醒,不知道怎么回事。
相关代码如下:
void RTC_Configuration(void)
{  
  PWR_BackupAccessCmd(ENABLE);//允许访问BKP

  BKP_ClearFlag();

  BKP_DeInit();//复位备份域

  RCC_LSICmd(ENABLE);//允许LSI时钟

  while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)//等待LSI准备好
  {
  }

  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);//任命LSI作为RTC时钟

  RCC_RTCCLKCmd(ENABLE);//使能RTC时钟  

  /* 设置RTC中断 */
  RTC_WaitForSynchro();//等待RTC寄存器同步

  RTC_WaitForLastTask();//等待上次RTC寄存器写操作完成

  RTC_ITConfig(RTC_IT_ALR, ENABLE);//允许闹钟中断

  RTC_WaitForLastTask();//等待上次RTC寄存器写操作完成 */  

  RTC_SetPrescaler(39999);//为RTC中断设置预分频
  // RTC period = RTCCLK/RTC_PR = (40.000 KHz)/(39999+1)

  RTC_WaitForLastTask();//等待上次RTC寄存器写操作完成

  /* 设置闹钟 */
  RTC_SetCounter(0);//初始计数值  

  RTC_WaitForLastTask();  

  RTC_SetAlarm(10);//设置闹钟时间

  RTC_WaitForLastTask();  
}


void RTC_IRQHandler(void)
{
  RTC_WaitForSynchro();

  if(RTC_GetITStatus(RTC_IT_ALR) != RESET)
  {
    RTC_ClearITPendingBit(RTC_IT_ALR);//清闹钟中断   

    RTC_WaitForLastTask();//等待上次RTC寄存器写操作完成

    /* 唤醒操作 */  
    if(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)// 检查唤醒标志是否设置  
    {  
      PWR_ClearFlag(PWR_FLAG_WU);//清除唤醒标志            
    }  

    /* 闹钟设置 */  
    RTC_SetCounter(0);

    RTC_WaitForLastTask();

    Println("FLAG1;");

    RTC_SetAlarm(10);  

    RTC_WaitForLastTask();

    RTC_WaitForSynchro();
  }

  RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);//清除RTC其他中断

  RTC_WaitForLastTask();         
}


void RCC_Configuration(void)
{   
  ErrorStatus HSEStartUpStatus;

  RCC_DeInit();//恢复默认值

  RCC_HSEConfig(RCC_HSE_ON);//使能外部高速时钟振荡器(外部晶振)

  HSEStartUpStatus = RCC_WaitForHSEStartUp();//等待HSE启动正常

  if(HSEStartUpStatus == SUCCESS)
  {
    RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB时钟是主时钟一分频(等于没有分)

    RCC_PCLK2Config(RCC_HCLK_Div1); //APB2时钟是AHB的一分频

    RCC_PCLK1Config(RCC_HCLK_Div2);//APB1是AHB的二分频

    FLASH_SetLatency(FLASH_Latency_2);
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//Flash操作

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_2);//PLL时钟源是HSE,采用2倍频,11.0592*2=22M

    RCC_PLLCmd(ENABLE);//使能PLL时钟

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }//等待PLL时钟就绪

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//PLL作为系统时钟(可以是HSE,HSI,PLL)

    while(RCC_GetSYSCLKSource() != 0x08)//等待就绪:0=HSI,4=HSE,8=PLL
    {
    }
  }  

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB1Periph_USART3 |
                         RCC_APB1Periph_UART4  | RCC_APB1Periph_UART5  |
                         RCC_APB1Periph_PWR    | RCC_APB1Periph_BKP , ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
                         RCC_APB2Periph_AFIO  | RCC_APB2Periph_SPI1  |
                         RCC_APB2Periph_USART1 , ENABLE);
}


void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  //#ifdef  VECT_TAB_RAM
  #if defined (VECT_TAB_RAM)
    /* Set the Vector Table base location at 0x20000000 */
    NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
  #elif defined(VECT_TAB_FLASH_IAP)
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2000);
  #else  /* VECT_TAB_FLASH  */
    /* Set the Vector Table base location at 0x08000000 */
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
  #endif

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//设置优先级分组:2个抢先级,6个子级

  /* 设置 RTC 中断 */
    NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* 设置 USART1 中断 */
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 1 ;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;               
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        
  NVIC_Init(&NVIC_InitStructure);

//………………下面还有其他中断啦
}


然后主程序运行大概1-2s之后通过“PWR_EnterSTANDBYMode(); ”进入休眠


现在的问题是,如果我在主程序里把“PWR_EnterSTANDBYMode(); ”注释掉,可以确定每10s进入闹钟中断(打印出Println("FLAG1;");)


一旦主程有休眠,每次确实能够唤醒,但是唤醒时间固定在3-4s不能调。然后,如果我插着J-LINK仿真器,就能准确10s唤醒,简直是醉了


求助论坛大神们吧。




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。