rtc.c
#include "sys.h"
#include "delay.h"
#include "rtc.h"
//实时时钟配置
//初始化RTC时钟,同时检测时钟是否工作正常
void RTC_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE);//使能PWR和BKP外设时钟
//默认情况下,RTC 所属的备份域禁止访问,可使用库函数 PWR_BackupAccessCmd 使能访问
PWR_BackupAccessCmd(ENABLE);//允许访问备份区域,后备区域解锁
if(PWR_GetFlagStatus(PWR_FLAG_SB)!=RESET) //如果现在处于待机模式
{
PWR_ClearFlag(PWR_FLAG_SB); //清除待机模式
RTC_ITConfig(RTC_IT_SEC, ENABLE); //打开RTC中断
RTC_WaitForSynchro(); //等待RTC寄存器同步
}
else
{
BKP_DeInit();//复位备份区域 使用此函数必须调用RCC_APB1PeriphClockCmd()函数
RCC_LSEConfig(RCC_LSE_ON);//设置外部低速晶振(LSE),外部32.768KHZ晶振开启
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) //等待稳定
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //设置RTC时钟(RTCCLK),选择LSE(晶振频率为 32.768KHz)作为RTC时钟
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
RTC_WaitForLastTask(); //等待RTC寄存器同步,因为RTC时钟是低速的,内环时钟是高速的,所以要同步
RTC_WaitForSynchro(); //写寄存器之前要确保上一次RTC的操作完成
//下面这两条语句是开启RTC秒中断的函数,每过1秒钟产生一次中断,就进入了中断服务函数
RTC_ITConfig(RTC_IT_SEC, ENABLE);//使能RTC秒中断
RTC_WaitForLastTask(); //确保上一次 RTC 的操作完成
RTC_EnterConfigMode(); //进入RTC配置模式
RTC_SetCounter(0); //初始值设定为0s 在使用本函数前必须先调用函数RTC_WaitForLastTask();等待标志位RTOFF被设置
RTC_WaitForLastTask();
RTC_SetPrescaler(32767); //设置RTC分频: 使 RTC周期为1s RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) = 1HZ 在使用本函数前必须先调用函数RTC_WaitForLastTask();等待标志位RTOFF被设置
RTC_WaitForLastTask(); //确保上一次 RTC 的操作完成
RTC_ExitConfigMode(); //退出RTC 配置模式
}
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void RTC_IRQHandler()
{
if(RTC_GetITStatus(RTC_IT_SEC)!=RESET) //是否秒中断发生
{
printf("Time is =%d rn",RTC_GetCounter()); //输出此时的秒数
}
RTC_WaitForLastTask();
RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW); //清除秒中断标志位和溢出位
}
|