打印
[STM32F1]

奇怪的STM32 rtc alarm 中断

[复制链接]
6468|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wilson970|  楼主 | 2014-5-10 23:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 wilson970 于 2014-5-11 09:20 编辑

在调试STM32 RTC ALARM中断退出STOP模式时,刚开始中断能进入,走着走着就不进去苏醒了。
只有在单步运行的时候才可以醒过来,不然一直在 __WFI();这句停留着;
但接着下一次又退不出低功耗了,很奇怪的问题。
众高手有何高见呀?

代码:
/***********************/
void RTC_Configuration1(void)
{
    if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)
    {
        PWR_ClearFlag(PWR_FLAG_SB);
        RTC_WaitForSynchro();
    }
    else
    {
        BKP_DeInit();
        RCC_LSEConfig(RCC_LSE_ON);
        //  RCC_LSICmd(ENABLE);
        while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
        {
        }
        /* 选择 LSE 为 RTC 时钟源 */
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

        //   RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
        RCC_RTCCLKCmd(ENABLE);
        RTC_WaitForSynchro();
        //    RTC_SetPrescaler(39999);
        RTC_SetPrescaler(32767);

        RTC_WaitForLastTask();
    }
    RTC_ITConfig(RTC_IT_ALR, ENABLE);
    RTC_ITConfig(RTC_IT_SEC, ENABLE);
    RTC_WaitForLastTask();
}

/***********************/
void NVIC_Configuration1(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

      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);

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;// 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

}

/***********************/
int main(void)
{
    RCC_Configuration();
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    //PWR_WakeUpPinCmd(ENABLE);
    PWR_BackupAccessCmd(ENABLE);
    GPIO_Configuration();


   // GPIO_Configuration1();
    EXTI_Configuration();
    RTC_Configuration1();
    NVIC_Configuration1();
    #ifndef  EMB_FLASH
        /* Set the Vector Table base location at 0x20000000 */
        NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
    #else  /* VECT_TAB_FLASH  */
        /* Set the Vector Table base location at 0x08000000 */
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    #endif

        USART1_Init();
        TIM3_PWM_Init();
        Beep_PWMOff();
        TIM2_Config();
        Applications_Init();



    while(1)
    {

        LCD_PowerOff(); //LCD power off
        Beep_PWMOff();
        LCD_BackLightOff();
       // SysTick_ITConfig(DISABLE);
        RTC_ClearFlag(RTC_FLAG_SEC);
        while (RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET)
            ;
        RTC_WaitForSynchro();
        RTC_SetAlarm(RTC_GetCounter() + 3);
        RTC_WaitForLastTask();
        PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

        //RCC_Configuration();
        SetHsiSysClock();
       // SysTick_ITConfig(ENABLE);
       // LCD_BackLightOn();
        Beep_PWMOn();
        LCD_BackLightOff();
       // SysTick_ITConfig(DISABLE);
        RTC_ClearFlag(RTC_FLAG_SEC);
        while (RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET)
            ;
        RTC_WaitForSynchro();
        RTC_SetAlarm(RTC_GetCounter() + 3);
        RTC_WaitForLastTask();
        PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
        //RCC_Configuration();
        SetHsiSysClock();


    }

}




/*******************************************************************************
* Function Name  : RTC_IRQHandler
* Description    : This function handles RTC global interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RTC_IRQHandler(void)
{

//    NVIC_ClearPendingIRQ(RTC_IRQn);

    if (RTC_GetITStatus(RTC_IT_SEC) != RESET)//秒钟中断
    {
       // LowPowerFlag |= BIT0;
        RTCInterruptCount_Handler();

    }

//        if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)//闹钟中断
//        {
//            RTC_ClearITPendingBit(RTC_IT_ALR);  //清闹钟中断
//            RTC_SetAlarm(RTC_GetCounter()+1);
//            LowPowerFlag |= BIT0;
//
//        }

          NVIC_ClearPendingIRQ(RTC_IRQn);
         // NVIC_ClearPendingIRQ(RTCAlarm_IRQn);
          RTC_ClearITPendingBit(RTC_IT_SEC);
         // RTC_ClearITPendingBit(RTC_IT_OW);  //清闹钟中断
}



/*******************************************************************************
* Function Name  : RTCAlarm_IRQHandler
* Description    : This function handles RTC Alarm interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RTCAlarm_IRQHandler(void)
{

    if (RTC_GetITStatus(RTC_IT_ALR) != RESET)
    {
        LowPowerFlag |= BIT0;
    //  RCC_ClearFlag();
    }
         EXTI_ClearITPendingBit(EXTI_Line17);
         RTC_WaitForLastTask();
         RTC_ClearITPendingBit(RTC_IT_ALR);
         RTC_WaitForLastTask();
  //  RTC_WaitForSynchro();

}


沙发
598330983| | 2016-3-22 11:32 | 只看该作者
/*
该模块启动STM32的AWU功能,采用LSI作为RTC时钟,周期性待机和唤醒单片机
移植该模块 :
1、只需调用RTC_Alarm_Configuration配置启动函数,
2、修改工作时间WORK_TIMES、待机时间STANDBY_TIMES,单位秒s,
        设置的为32为闹钟寄存器,0-4294967295s(71582788.25min)

*/
#ifndef __RTC_Alarm_H
#define __RTC_Alarm_H

//外部提供接口
#include "main.h"

//宏定义,单位s,0-4294967295s(71582788.25min)
//运行时间
#define WORK_TIMES 2
//待机时间
#define STANDBY_TIMES 2

extern void RTC_Alarm_Configuration(void);

#endif



#include "RTC_Alarm.h"

//RTC中断配置
static void RTC_NVIC_Config(void)
{   
    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQChannel;        //RTC全局中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;    //先占优先级1位,从优先级3位
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;   
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //使能该通道中断
    NVIC_Init(&NVIC_InitStructure);        //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}

//RTC闹钟初始化:启动时钟、配置LSI做RTC时钟、设置预分频40000得到1Hz
//设置运行时间WORK_TIMES
void RTC_Alarm_Configuration(void)
{
        /* Enable PWR and BKP clocks */
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
        /* Allow access to BKP Domain */
        PWR_BackupAccessCmd(ENABLE);       
        /* Reset Backup Domain */
        BKP_DeInit();

    /* RTC clock source configuration ----------------------------------------*/
        /* Enable the LSI OSC */
          RCC_LSICmd(ENABLE);
    /* Wait till LSI is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
    {
    }
    /* Select the RTC Clock Source */
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
    /* Enable the RTC Clock */
    RCC_RTCCLKCmd(ENABLE);
        /* Wait for RTC registers synchronization */
        RTC_WaitForSynchro();
        /* Wait until last write operation on RTC registers has finished */
        RTC_WaitForLastTask();
        /* 使能RTC闹钟中断*/
        RTC_ITConfig(RTC_IT_ALR, ENABLE);       
        /* Wait until last write operation on RTC registers has finished */
        RTC_WaitForLastTask();       
        /* Set RTC prescaler: set RTC period to 1sec */
        RTC_SetPrescaler(40000);       
        /* Wait until last write operation on RTC registers has finished */
        RTC_WaitForLastTask();
               
        //中断配置
        RTC_NVIC_Config();

        //设置运行WORK_TIMES
        RTC_SetAlarm(RTC_GetCounter() + WORK_TIMES);
        RTC_WaitForLastTask();
}

//设置闹钟时长并进入待机
//s为中断秒数
void RTC_Enter_StandbyMode(u32 s)
{

    RTC_SetAlarm(RTC_GetCounter() + s);
    RTC_WaitForLastTask();
    // 进入待机模式, 此时所有1.8V域的时钟都关闭,HIS和HSE的振荡器关闭, 电压调节器关闭.
    // 只有WKUP引脚上升沿,RTC警告事件,NRST引脚的外部复位,IWDG复位.
        /* Request to enter STANDBY mode (Wake Up flag is cleared in PWR_EnterSTANDBYMode function) */
    PWR_EnterSTANDBYMode();
}

//中断服务函数
void RTC_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)//闹钟中断
{
          RTC_ClearITPendingBit(RTC_IT_ALR);  //清闹钟中断

        RTC_Enter_StandbyMode(STANDBY_TIMES);//进入待机
}                 
}



使用特权

评论回复
板凳
zhuomuniao110| | 2016-3-22 15:38 | 只看该作者
谁有这个报警中断的教程啊,不是很理解这个概念。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

13

帖子

0

粉丝