#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();
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
上来贴代码,不做任何说明,看到这样帖子,真是一股无名之火。
深呼吸,呼气,吸气,呼气,吸气,平复一下心情。
碰到这样的帖子,个人建议:1.审核不要通过;2.严重者直接封ID。
一周热门 更多>