RTC实时时钟如何设置闹钟值

2019-07-20 14:26发布

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "rtc.h"
#include "lcd.h"
//Mini STM32开发板
//RTC实时时钟 驱动代码  
//正点原子@ALIENTEK
//2010/6/6
u32 seccount=0;
_calendar_obj calendar;//时钟结构体 
/*
void set_clock(u16 divx)
{
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟  
PWR_BackupAccessCmd(ENABLE); //使能RTC和后备寄存器访问 

RTC_EnterConfigMode();/// 允许配置
 
RTC_SetPrescaler(divx); //设置RTC预分频的值            
RTC_ExitConfigMode();//退出配置模式      
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成  
}   
*/
static void RTC_NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //RTC全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1位,从优先级3位
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //先占优先级0位,从优先级4位
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能该通道中断
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器


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


}


//实时时钟配置
//初始化RTC时钟,同时检测时钟是否工作正常
//BKP->DR1用于保存是否第一次配置的设置
//返回0:正常
//其他:错误代码
u32 flag;
u8 RTC_Init(void)
{
//检查是不是第一次配置时钟
u8 temp=0;
 
if (BKP_ReadBackupRegister(BKP_DR1) == 0x5050) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟   
PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问 
BKP_DeInit(); //复位备份区域
RCC_LSEConfig(RCC_LSE_ON); //设置外部低速晶振(LSE),使用外设低速晶振
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) //检查指定的RCC标志位设置与否,等待低速晶振就绪
{
temp++;
delay_ms(10);
}
if(temp>=250)return 1;//初始化时钟失败,晶振有问题    
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //设置RTC时钟(RTCCLK),选择LSE作为RTC时钟    
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟  
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_WaitForSynchro(); //等待RTC寄存器同步  
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_ITConfig(RTC_IT_ALR , ENABLE);
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_EnterConfigMode();/// 允许配置
RTC_SetPrescaler(32767); //设置RTC预分频的值
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_Set(23,59,55);  //设置时间
flag=RTC_GetCounter();
  RTC_SetAlarm(flag+1);  //设置时间
RTC_ExitConfigMode(); //退出配置模式  

RTC_WaitForLastTask();
BKP_WriteBackupRegister(BKP_DR1, 0X5050); //向指定的后备寄存器中写入用户程序数据
}
else//系统继续计时
{
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
RTC_ITConfig(RTC_IT_ALR , ENABLE);
RTC_WaitForSynchro(); //等待最近一次对RTC寄存器的写操作完成

}
RTC_NVIC_Config();//RCT中断分组设置

RTC_Get();//更新时间

return 0; //ok

}

//RTC时钟中断
//每秒触发一次  
//extern u16 tcnt; 

void RTC_IRQHandler(void)
{  
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)//秒钟中断
{
RTC_Get();//更新时间

LCD_ShowxNum(60+17,230,RTC_GetCounter(),6,16,0x80);

  }
if(RTC_GetITStatus(RTC_IT_ALR)!= RESET) //闹钟中断
{

LCD_ShowxNum(55,250,seccount,4,16,0x80);

RTC_ClearITPendingBit(RTC_IT_ALR); //清闹钟中断

  } 

RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW); //清闹钟中断
RTC_WaitForLastTask();          
}
  
//设置时钟
//把输入的时钟转换为秒钟
 
u8 RTC_Set(u8 hour,u8 min,u8 sec)
{
seccount+=(u32)hour*3600;//小时秒钟数
    seccount+=(u32)min*60; //分钟秒钟数
seccount+=sec;//最后的秒钟加上去

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟  
PWR_BackupAccessCmd(ENABLE); //使能RTC和后备寄存器访问 
RTC_SetCounter(seccount); //设置RTC计数器的值


RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成  
return 0;    
}
//得到当前的时间
//返回值:0,成功;其他:错误代码.
u8 RTC_Get(void)
{

u32 timecount=0; 
u32 temp=0; 
  timecount=RTC_GetCounter();
temp=timecount%86400;     //得到秒钟数     
calendar.hour=temp/3600;     //小时
calendar.min=(temp%3600)/60; //分钟
calendar.sec=(temp%3600)%60; //秒钟
  if(RTC_GetCounter()>=86399)
{
RTC_SetCounter(0);
}
return 0;
}

u8 alarm(u8 hour,u8 min,u8 sec)
{
seccount+=(u32)hour*3600;//小时秒钟数
    seccount+=(u32)min*60; //分钟秒钟数
seccount+=sec;//最后的秒钟加上去

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟  
PWR_BackupAccessCmd(ENABLE); //使能RTC和后备寄存器访问 
Set_Alarm(seccount ) ;
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成 
  RTC_Get();
return 0;  
  
}
void Set_Alarm(uint32_t alarm) 
  { u32 tempCountValue=0;
    tempCountValue = RTC_GetCounter(); //得到计数器目前的值 

tempCountValue = tempCountValue + alarm; //闹钟到时计数器中的值 
RTC_WaitForLastTask(); 
RTC_SetAlarm(tempCountValue); //设置闹钟的值 
RTC_WaitForLastTask(); 
  }





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