|
芯片內(nèi)集成了計(jì)數(shù)器+存儲(chǔ)器 外面接電源+晶振即可代碼表現(xiàn)為一個(gè)init+一個(gè)算法
#include "rtc.h"
void STEP1_RCC(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
}
void STEP2_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void Set_alarm(uint32_t AlarmValue)
{
if(RTC_GetITStatus(RTC_IT_ALR) != RESET) //alarm interrupt
{
RTC_ClearITPendingBit(RTC_IT_ALR);
}
RTC_ITConfig(RTC_IT_ALR, ENABLE);
RTC_WaitForLastTask();
RTC_SetAlarm(AlarmValue);
}
void Disable_alarm(void)
{
RTC_ITConfig(RTC_IT_ALR , DISABLE);
RTC_WaitForLastTask();
}
void RTC_Configuration(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
//允許訪問BKP區(qū)域
PWR_BackupAccessCmd(ENABLE);
//復(fù)位BKP
BKP_DeInit();
//使能外部低速晶振 32.768K
RCC_LSEConfig(RCC_LSE_ON);
//等待外部低速晶振就緒
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);
//選擇RTC外部時(shí)鐘為低速晶振 32.768K
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
//使能RTC時(shí)鐘
RCC_RTCCLKCmd(ENABLE);
//等待RTC寄存器同步
RTC_WaitForSynchro();
//等待寫RTC寄存器完成
RTC_WaitForLastTask();
//使能RTC秒中斷
RTC_ITConfig(RTC_IT_SEC,ENABLE);
Set_alarm(2);
//設(shè)置預(yù)分頻
RTC_SetPrescaler(32767);
//等待寫RTC寄存器完成
RTC_WaitForLastTask();
}
void Clock_Init(void)
{
if(BKP_ReadBackupRegister(BKP_DR1)!=0xA5A5)
{
//第一次運(yùn)行 初始化設(shè)置
//RTC初始化
RTC_Configuration();
//等待寫RTC寄存器完成
RTC_WaitForLastTask();
//設(shè)置時(shí)間初值
RTC_SetCounter(0xA442);
//等待寫RTC寄存器完成
RTC_WaitForLastTask();
//寫配置標(biāo)志
BKP_WriteBackupRegister(BKP_DR1,0xA5A5);
}
else
{
//等待RTC寄存器同步
RTC_WaitForSynchro();
//等待寫RTC寄存器完成
RTC_WaitForLastTask();
//使能RTC秒中斷
RTC_ITConfig(RTC_IT_SEC,ENABLE);
//等待寫RTC寄存器完成
RTC_WaitForLastTask();
Set_alarm(2);
}
RCC_ClearFlag();//清除復(fù)位標(biāo)志;
}
void RTC_Init(void)
{
STEP1_RCC();
STEP2_NVIC();
Clock_Init();
}
/***********************判斷是否為閏年********/
const uint8_t monthTable[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
/*
函數(shù)功能:判斷是否閏年
函數(shù)參數(shù):需要判斷的年份
返回值: 返回1成功 其他失敗
*/
static uint8_t isLeapYear(uint16_t mYear)
{
if (((mYear%4 == 0)&&((mYear%100) != 0))||(mYear%400) == 0)
{
return 1;
}else
{
return 0;
}
}
/********************************************************************************/
/*
函數(shù)功能:日期轉(zhuǎn)換為秒并配置RTC
函數(shù)參數(shù):年、月、日、時(shí)、分、秒
返回值: 返回0成功 其他失敗
*/
uint8_t RTC_SetSec(_TM* DATA)
{
uint32_t secCount = 0;
uint16_t i;
uint16_t year=DATA->year;
uint8_t month=DATA->mon;
uint8_t day=DATA->day;
uint8_t hour=DATA->hour;
uint8_t minute=DATA->min;
uint8_t sec=DATA->sec;
if (year <1970 || year >2099)
{
return 1;
}
for (i=1970; i<year; i++)
{
if (isLeapYear(i))
{
secCount += 31622400UL;
}
else
{
secCount += 31536000UL;
}
}
for (i=0; i<month-1; i++)
{
secCount += ((uint32_t)monthTable[i]*86400UL);
if (isLeapYear(year) && i==1) //潤年 多加一天
{
secCount += 86400UL;
}
}
secCount += (uint32_t)(day-1) * 86400UL;
secCount += (uint32_t)(hour)*3600;
secCount += (uint32_t)(minute)*60;
secCount += (uint32_t)(sec);
/*執(zhí)行以下操作可以使能對(duì)備份寄存器和 RTC 的訪問:
1)通過設(shè)置寄存器 RCC_APB1ENR 的 PWREN 和 BKPEN 位來打開電源和后備接口的時(shí)鐘
2)電源控制寄存器(PWR_CR)的 DBP 位來使能對(duì)后備寄存器和 RTC 的訪問
*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
RTC_SetCounter(secCount);
RTC_WaitForLastTask();
return 0;
}
/********************************************************************************/
/*
函數(shù)功能:從RTC獲取秒轉(zhuǎn)換為年、月、日、星期、時(shí)、分、秒
存入 struct thisDate 中
函數(shù)參數(shù):struct thisDate
返回值: 返回0成功 其他失敗
*/
uint8_t RTC_GetDate(_TM* thisDate)
{
uint32_t timeCount = 0;
uint32_t Count ;
uint16_t tmp = 0;
timeCount = RTC_GetCounter();
Count = timeCount/86400UL; //計(jì)算出天數(shù)
thisDate->week = (4+Count)%7;
if (Count !=0) //大于一天
{
tmp = 1970; //從1970年開始
while(Count>=365)
{
if (isLeapYear(tmp))//是閏年
{
if (Count>= 366) //天數(shù)大于366
{
Count -= 366;
}else
{
tmp++; //天數(shù)小于366 最后一年
break;
}
}else
{
Count -= 365; //平年
}
tmp++;
}
thisDate->year = tmp; //獲取到了年
tmp = 0;
while(Count>= 28)
{
if (isLeapYear(thisDate->year) && tmp == 1)
{
if (Count >= 29)
{
Count -= 29;
}
else
{
break; //當(dāng)年是閏年 二月 某時(shí)
}
}else
{
if (Count >= monthTable[tmp])
{
Count -= monthTable[tmp];
}else
{
break;
}
}
tmp ++;
}
thisDate->mon = tmp+1; //獲取到月
thisDate->day = Count+1; //獲取到日
}
Count = timeCount%86400UL;
thisDate->hour = Count/3600;
thisDate->min= (Count%3600)/60;
thisDate->sec = (Count%3600)%60;
return 0;
}
_RTC Rtc = {RTC_Init,RTC_GetDate,RTC_SetSec};
_TM Today={12,27,13,1,8,8,2018};
#ifndef __RTC_H
#define __RTC_H
#include "time.h"//等待研究
#include "stm32f10x_bkp.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_rtc.h"
#include "stm32f10x_pwr.h"
#include "misc.h"
typedef struct
{
u8 sec;
u8 min;
u8 hour;
u8 week;
u8 day;
u8 mon;
u16 year;
}_TM;
typedef struct
{
void (*init)(void);
u8 (*GetTime)(_TM *);
u8 (*SetTime)(_TM *);
}_RTC;
extern _RTC Rtc;
extern _TM Today;
#endif
|
評(píng)分
-
查看全部評(píng)分
|