关于STM32F4的RTC闹铃和唤醒中断不工作

2019-07-20 21:01发布

在用RTC实验时我采用的是内部晶振LSI,在时间显示这一块没有问题,但是闹铃和周期唤醒中断不工作。代码如下,请高手指点一下。

#include "rtc.h"
#include "delay.h"
#include "uart.h"
#include "lcd.h"

void RTCSet_Time(uint8_t hour,uint8_t min,uint8_t sec,uint8_t RTC_H12)
{
        RTC_TimeTypeDef RTC_TimeStruct;
        RTC_TimeStruct.RTC_H12=RTC_H12_AM;
        RTC_TimeStruct.RTC_Hours=hour;
        RTC_TimeStruct.RTC_Minutes=min;
        RTC_TimeStruct.RTC_Seconds=sec;
        RTC_SetTime(RTC_Format_BIN,&RTC_TimeStruct);
}

void RTCSet_Date(uint8_t dat,uint8_t mon,uint8_t year,uint8_t week)
{       
        RTC_DateTypeDef RTC_DateStruct;
        RTC_DateStruct.RTC_Date=dat;
        RTC_DateStruct.RTC_Month=mon;
        RTC_DateStruct.RTC_WeekDay=week;
        RTC_DateStruct.RTC_Year=year;  
        RTC_SetDate(RTC_Format_BIN,&RTC_DateStruct);
}

u8 myrtc_init()
{
        RTC_InitTypeDef RTC_InitStruct;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能PWR时钟
        PWR_BackupAccessCmd(ENABLE);        //使能后备寄存器访问
        RCC_LSICmd(ENABLE);             //使能内部时钟
        while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)   //等待就绪
        {
                ;
        }
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);            //配置RTC为内部低速时钟
    RCC_RTCCLKCmd(ENABLE);                             //使能RTC
    RTC_WaitForSynchro();                              //等待同步
        if(RTC_ReadBackupRegister(RTC_BKP_DR0)!=0x5050)   //判断是否第一次配置
        {
                RTC_WriteProtectionCmd(DISABLE);              //关闭写保护
        RTC_EnterInitMode();                          //进入初始化模式
        /*外部时钟32KHZ   spre=32KHZ/[(0X63+1)*(0X13F+1)]刚好是1HZ*/               
                RTC_InitStruct.RTC_HourFormat=RTC_HourFormat_24;
                RTC_InitStruct.RTC_AsynchPrediv=0x63;
                RTC_InitStruct.RTC_SynchPrediv=0x13f;     
                RTC_Init(&RTC_InitStruct);                                        //初始化RTC参数
                RTCSet_Time(12,47,56,RTC_H12_AM);
                RTCSet_Date(1,10,16,6);                                           //设置时间,日期
                RTC_ExitInitMode();                            //退出写保护
                RTC_WriteBackupRegister(RTC_BKP_DR0,0x5050);  //标记已经初始化RTC
                RTC_WriteProtectionCmd(ENABLE);
        }
        PWR_BackupAccessCmd(DISABLE);                     //关闭后备寄存器访问
        return 0;
}

void RTC_setArma(u8 day,u8 hour,u8 min,u8 sec)
{
        RTC_AlarmTypeDef RTC_AlarmStruct;
        RTC_TimeTypeDef RTC_AlarmTime;
        NVIC_InitTypeDef NVIC_InitStruct;
        EXTI_InitTypeDef EXTI_InitStruct;
        RTC_AlarmCmd(RTC_Alarm_A,DISABLE);                //关定时器A
       
        RTC_AlarmTime.RTC_H12=RTC_H12_AM;
        RTC_AlarmTime.RTC_Hours=hour;
        RTC_AlarmTime.RTC_Minutes=min;
        RTC_AlarmTime.RTC_Seconds=sec;
        RTC_AlarmStruct.RTC_AlarmDateWeekDay=day;   
        RTC_AlarmStruct.RTC_AlarmDateWeekDaySel=RTC_AlarmDateWeekDaySel_Date; //按天定时
        RTC_AlarmStruct.RTC_AlarmMask=RTC_AlarmMask_None;                     //精确定时
        RTC_AlarmStruct.RTC_AlarmTime=RTC_AlarmTime;
        RTC_SetAlarm(RTC_Format_BIN,RTC_Alarm_A,&RTC_AlarmStruct);                     //设置闹铃
       
        EXTI_ClearITPendingBit(EXTI_Line22);  //清除外部中断22
        RTC_ClearITPendingBit(RTC_IT_ALRA);   //清除RTC闹铃A中断
        RTC_ITConfig(RTC_IT_ALRA,ENABLE);    //开启闹铃A中断
       
       
        EXTI_InitStruct.EXTI_Line=EXTI_Line22;
        EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;
        EXTI_InitStruct.EXTI_LineCmd=ENABLE;
        EXTI_Init(&EXTI_InitStruct);               //初始化中断
       
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        NVIC_InitStruct.NVIC_IRQChannel=RTC_Alarm_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;
        NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
        NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStruct);                                                          //中断初始化
}

void RTC_Alarm_IRQHandler()//RTC Alarm (A and B) through EXTI Line
{
        if(RTC_GetFlagStatus(RTC_FLAG_ALRAF))  //AlarmA中断
        {
                RTC_ClearFlag(RTC_FLAG_ALRAF);//清除AlarmA中断
                printf(" RTC_Alarm_IRQHandler() ");
        }
        EXTI_ClearITPendingBit(EXTI_Line22);  //清除外部中断22
}

/************************************************
wkse:Configures the RTC Wakeup clock source,
cnt:Configures the RTC Wakeup counter,自动重装载,减到零中断
**********************************************/
void RTC_Wakeup(u32 wkse,u16 cnt)  //周期性唤醒定时器
{
        EXTI_InitTypeDef EXTI_InitStruct;
        NVIC_InitTypeDef NVIC_InitStruct;
       
        RTC_WakeUpCmd(DISABLE);              //关闭Wake Up
        RTC_WakeUpClockConfig(wkse);         //唤醒时钟选择
        RTC_SetWakeUpCounter(cnt);           //设置自动重装载值
       
        RTC_ClearITPendingBit(RTC_IT_WUT);   //清除Wake Up中断标志
        EXTI_ClearITPendingBit(EXTI_Line17);  //清除外部中断17
        RTC_ITConfig(RTC_IT_WUT,ENABLE);      //开启Wake Up中断
       
        EXTI_InitStruct.EXTI_Line=EXTI_Line17;
        EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;
        EXTI_InitStruct.EXTI_LineCmd=ENABLE;
        EXTI_Init(&EXTI_InitStruct);               //初始化中断
               
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        NVIC_InitStruct.NVIC_IRQChannel=RTC_WKUP_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;
        NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;
        NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStruct);                                //WKUP中断初始化
        RTC_WakeUpCmd(ENABLE);                      //开启Wake Up
}

void RTC_WKUP_IRQHandler()//RTC_WKUP_IRQHandler
{

        if(RTC_GetFlagStatus(RTC_FLAG_WUTF))
        {
                RTC_ClearFlag(RTC_FLAG_WUTF);   //清除唤醒中断
                printf(" RTC_GetITStatus(RTC_IT_WUT) ");
        }
        EXTI_ClearITPendingBit(EXTI_Line17);  //清除外部中断17
       
}


还有一个问题是当中断处理函数采用RTC_GetITStatus(),EXTI_ClearITPendingBit(),这对函数判断时,用usmart调试中断函数会直接让串口崩溃,提示检测不到串口了,只能重启电脑才能检测到串口。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。