| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- /**
- ******************************** STM32F10x *********************************
- * @文件名 : rtc.c
- * @作者 : sun
- * @库版本 : V3.5.0
- * @文件版本 : V1.0.0
- * @日期 : 2018年02月04日
- * @摘要 : RTC源文件
- ******************************************************************************/
- /*----------------------------------------------------------------------------
- 更新日志:
- 2018-02-04 V1.0.0:初始版本
- ----------------------------------------------------------------------------*/
- /* 包含的头文件 --------------------------------------------------------------*/
- #include "rtc.h"
- #include "systick.h"
- #include "delay.h"
- RTC_DateTimeTypeDef DeviceRTC={16,5,19,15,26,0};
- // DeviceRTC.Year = 16;
- // DeviceRTC.Month = 5;
- // DeviceRTC.Date = 19;
- // DeviceRTC.Hour = 15;
- // DeviceRTC.Minute = 26;
- // DeviceRTC.Second = 0;
-
- /************************************************
- 函数名称 : RTC_Configuration
- 功 能 : RTC配置
- 参 数 : 无
- 返 回 值 : 无
- 作 者 : sun
- *************************************************/
- void RTC_Configuration(void)
- {
- BKP_DeInit(); //复位后备区域
- RCC_LSEConfig(RCC_LSE_ON); //使能低速外部时钟(LSE)
- while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
- RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //选择LSE作为RTC时钟源
- RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
- RTC_WaitForSynchro(); //等待同步
- RTC_WaitForLastTask(); //等待操作完成
- // RTC_ITConfig(RTC_IT_ALR, ENABLE); //使能闹钟中断
- // RTC_WaitForLastTask(); //等待操作完成
- RTC_SetPrescaler(32767); //分频值
- RTC_WaitForLastTask(); //等待操作完成
- }
- /************************************************
- 函数名称 : RTC_Initializes
- 功 能 : RTC初始化
- 参 数 : 无
- 返 回 值 : 无
- 作 者 : sun
- *************************************************/
- void RTC_Initializes(void)
- {
- RTC_DateTimeTypeDef RTC_DateTimeStructure;
- RTC_DateTimeStructure.Year = 16;
- RTC_DateTimeStructure.Month = 7;
- RTC_DateTimeStructure.Date = 18;
- RTC_DateTimeStructure.Hour = 18;
- RTC_DateTimeStructure.Minute = 0;
- RTC_DateTimeStructure.Second = 0;
- PWR_BackupAccessCmd(ENABLE); //允许操作后备区域
- /* 判断是否首次操作RTC */
- if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
- {
- RTC_Configuration(); //配置RTC
- RTC_SetDateTime(RTC_DateTimeStructure); //初始化日历(2016年7月18日 18:00:00)
- BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
- }
- else
- {
- if(RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
- {
- }
- else if(RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
- {
- }
- RTC_WaitForSynchro(); //等待RTC与RTC_APB时钟同步
- }
- // RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能秒中断
- RTC_WaitForLastTask(); //等待TRC最后一次操作完成
- }
- static void RTC_NVIC_Config(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; //RTC全局中断
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级1位,从优先级3位
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //先占优先级0位,从优先级4位
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能该通道中断
- NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
- }
- //实时时钟配置
- //初始化RTC时钟,同时检测时钟是否工作正常
- //BKP->DR1用于保存是否第一次配置的设置
- //返回0:正常
- //其他:错误代码
- uint8_t RTC_Init(void)
- {
-
- uint8_t temp=0;
-
- //检查是不是第一次配置时钟
-
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
- PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问
- if (BKP_ReadBackupRegister(BKP_DR1) != 0x5050) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
- {
- BKP_DeInit(); //复位备份区域
-
- /////////////////////(时钟配置部分)////////////////////////////
-
- //RCC_LSEConfig(RCC_LSE_ON); //设置外部低速晶振(LSE),使用外设低速晶振
- RCC_LSICmd(ENABLE);//开启内部低速晶振LSI,changed by scx
- while( RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == 0 && temp<11)
- //while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) //检查指定的RCC标志位设置与否,等待低速晶振就绪
- {
- temp++;
- delay_ms(10);
- }
- if(temp>=10)return 1;//初始化时钟失败,晶振有问题
- RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
- //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_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
-
- ///////////////// ////(寄存器配置部分)////////////////////////////
- RTC_EnterConfigMode();/// 允许配置
- RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
-
- RTC_SetPrescaler(39000);//分频后为1HZ
- //RTC_SetPrescaler(32767); //设置RTC预分频的值
- RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
-
- RTC_SetDateTime(DeviceRTC); //设置时间
- RTC_ExitConfigMode(); //退出配置模式
- BKP_WriteBackupRegister(BKP_DR1, 0X5050); //向指定的后备寄存器中写入用户程序数据
- }
- else//系统继续计时
- {
- /////////////////////(时钟配置部分)////////////////////////////
- RCC_LSICmd(ENABLE);//开启内部低速晶振LSI
- while( RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == 0 && temp<11)
- //while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) //检查指定的RCC标志位设置与否,等待低速晶振就绪
- {
- temp++;
- delay_ms(10);
- }
- if(temp>=10)return 1;//初始化时钟失败,晶振有问题
-
- RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
- RCC_RTCCLKCmd(ENABLE);//选择使能RTC时钟
-
- RTC_WaitForLastTask();//等待上一次写RTC任务完成(常用,只要涉及对RTC里值的修改,都需要在修改后加上此函数)
- RTC_WaitForSynchro();//等待与APB1的同步,才能读RTC寄存器
-
- RTC_EnterConfigMode();//允许RTC配置
- RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
-
-
- RTC_WaitForLastTask();//等待上一次写RTC任务完成(常用,只要涉及对RTC里值的修改,都需要在修改后加上此函数)
-
- RTC_SetPrescaler(39000);//分频后为1HZ
- RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
-
- RTC_ExitConfigMode(); //等待最近一次对RTC寄存器的写操作完成
- RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
- }
- RTC_NVIC_Config();//RCT中断分组设置
- RTC_GetDateTime(&DeviceRTC);//更新时间
- return 0; //ok
- }
- /************************************************
- 函数名称 : RTC_SetDateTime
- 功 能 : 设置RTC日期时间
- 参 数 : RTC_DateTimeStructure --- RTC日期时间结构体
- 返 回 值 : RTC_OK ------------------ 成功
- RTC_OVERFLOW ------------ 失败(越界)
- 作 者 : sun
- *************************************************/
- RTC_RESULT RTC_SetDateTime(RTC_DateTimeTypeDef RTC_DateTimeStructure)
- {
- uint32_t num_leapyear; //闰年天数
- uint32_t conut_year; //计秒(年)
- uint32_t conut_month_day; //月日的秒计数
- /*------------------------- 判断是否越界 --------------------------*/
- //年、月、星期、时、分、秒
- if((130 < RTC_DateTimeStructure.Year) || (12 < RTC_DateTimeStructure.Month) ||
- (24 <= RTC_DateTimeStructure.Hour) || (60 <= RTC_DateTimeStructure.Minute) || (60 <= RTC_DateTimeStructure.Second))
- {
- return RTC_OVERFLOW;
- }
- //日
- if((RTC_DateTimeStructure.Month==1)|(RTC_DateTimeStructure.Month==3)|(RTC_DateTimeStructure.Month==5)|(RTC_DateTimeStructure.Month==7)|(RTC_DateTimeStructure.Month==8)|(RTC_DateTimeStructure.Month==10)|(RTC_DateTimeStructure.Month==12))
- {
- if(RTC_DateTimeStructure.Date > 31)
- return RTC_OVERFLOW;
- }
- else if((RTC_DateTimeStructure.Month==4)|(RTC_DateTimeStructure.Month==6)|(RTC_DateTimeStructure.Month==9)|(RTC_DateTimeStructure.Month==11))
- {
- if(RTC_DateTimeStructure.Date > 30)
- return RTC_OVERFLOW;
- }
- else if(RTC_DateTimeStructure.Month==2)
- { /* 如果是闰年 */
- if(RTC_DateTimeStructure.Year%4 == 0)
- {
- if(RTC_DateTimeStructure.Date > 29)
- return RTC_OVERFLOW;
- }
- else if(RTC_DateTimeStructure.Date > 28)
- return RTC_OVERFLOW;
- }
- //--------------------------- 计算天数 ----------------------------
- //闰年数
- num_leapyear = RTC_DateTimeStructure.Year/4 + 1;
- //计秒(年)
- conut_year = RTC_DateTimeStructure.Year*SEC_YEAR + num_leapyear*SEC_DAY;
- switch(RTC_DateTimeStructure.Month)
- {
- case 1:/* 一月 */
- conut_month_day = (RTC_DateTimeStructure.Date-1)*SEC_DAY;
- if(RTC_DateTimeStructure.Year%4 == 0) //假如是闰年,需要减去一天的计数
- conut_month_day -= SEC_DAY;
- break;
- case 2:/* 二月 */
- conut_month_day = (31 + RTC_DateTimeStructure.Date - 1)*SEC_DAY;
- if(RTC_DateTimeStructure.Year%4 == 0) //假如是闰年,需要减去一天的计数
- conut_month_day -= SEC_DAY;
- break;
- case 3:/* 三月 */
- conut_month_day = (59 + RTC_DateTimeStructure.Date - 1)*SEC_DAY;
- break;
- case 4:/* 四月 */
- conut_month_day = (90 + RTC_DateTimeStructure.Date - 1)*SEC_DAY;
- break;
- case 5:/* 五月 */
- conut_month_day = (120 + RTC_DateTimeStructure.Date - 1)*SEC_DAY;
- break;
- case 6:/* 六月 */
- conut_month_day = (151 + RTC_DateTimeStructure.Date - 1)*SEC_DAY;
- break;
- case 7:/* 七月 */
- conut_month_day = (181 + RTC_DateTimeStructure.Date - 1)*SEC_DAY;
- break;
- case 8:/* 八月 */
- conut_month_day = (212 + RTC_DateTimeStructure.Date - 1)*SEC_DAY;
- break;
- case 9:/* 九月 */
- conut_month_day = (243 + RTC_DateTimeStructure.Date - 1)*SEC_DAY;
- break;
- case 10:/* 十月 */
- conut_month_day = (273 + RTC_DateTimeStructure.Date - 1)*SEC_DAY;
- break;
- case 11:/* 十一月 */
- conut_month_day = (304 + RTC_DateTimeStructure.Date - 1)*SEC_DAY;
- break;
- case 12:/* 十二月 */
- conut_month_day = (334 + RTC_DateTimeStructure.Date - 1)*SEC_DAY;
- break;
- }
- RTC_WaitForLastTask();
- //设置计数值(更新RTC)
- RTC_SetCounter(conut_year + conut_month_day + RTC_DateTimeStructure.Hour*3600 + RTC_DateTimeStructure.Minute*60 + RTC_DateTimeStructure.Second);
- //等待TRC操作完成
- RTC_WaitForLastTask();
- return RTC_OK;
- }
- /************************************************
- 函数名称 : RTC_GetDateTime
- 功 能 : 读取RTC时间(含日历、星期)
- 参 数 : RTC_DateTimeStructure --- RTC日期时间结构体
- 返 回 值 : 无
- 作 者 : sun
- *************************************************/
- void RTC_GetDateTime(RTC_DateTimeTypeDef *RTC_DateTimeStructure)
- {
- uint32_t num_day; //计数的天数
- uint32_t num_daytmp; //该年的天数
- uint32_t num_leapyear; //闰年数
- uint32_t count_value = RTC_GetCounter(); //读取RTC计数值
- num_day = count_value/SEC_DAY; //从0开始计算天数
- num_leapyear = num_day/(365*4+1) + 1; //闰年数
- if(num_day%(365*4+1) == 0) //闰年的1月1日
- RTC_DateTimeStructure->Year = (uint8_t)((num_day - num_leapyear + 1)/365);
- else
- RTC_DateTimeStructure->Year = (num_day - num_leapyear)/365;
- if(RTC_DateTimeStructure->Year%4 == 0)
- {
- /* 闰年一年内的天数 */
- num_daytmp = num_day - RTC_DateTimeStructure->Year*365 - (num_leapyear-1);
- if(num_daytmp < 31) /* 一月 */
- {
- RTC_DateTimeStructure->Month = 1;
- RTC_DateTimeStructure->Date = num_daytmp%31 + 1;
- }
- else if(num_daytmp < 60)/* 二月 */
- {
- RTC_DateTimeStructure->Month = 2;
- RTC_DateTimeStructure->Date = (num_daytmp - 31)%29 + 1;
- }
- else if(num_daytmp < 91)/* 三月 */
- {
- RTC_DateTimeStructure->Month = 3;
- RTC_DateTimeStructure->Date = (num_daytmp - 60)%31 + 1;
- }
- else if(num_daytmp < 121)/* 四月 */
- {
- RTC_DateTimeStructure->Month = 4;
- RTC_DateTimeStructure->Date = (num_daytmp - 91)%30 + 1;
- }
- else if(num_daytmp < 152)/* 五月 */
- {
- RTC_DateTimeStructure->Month = 5;
- RTC_DateTimeStructure->Date = (num_daytmp - 121)%31 + 1;
- }
- else if(num_daytmp < 182)/* 六月 */
- {
- RTC_DateTimeStructure->Month = 6;
- RTC_DateTimeStructure->Date = (num_daytmp - 152)%30 + 1;
- }
- else if(num_daytmp < 213)/* 七月 */
- {
- RTC_DateTimeStructure->Month = 7;
- RTC_DateTimeStructure->Date = (num_daytmp - 182)%31 + 1;
- }
- else if(num_daytmp < 244)/* 八月 */
- {
- RTC_DateTimeStructure->Month = 8;
- RTC_DateTimeStructure->Date = (num_daytmp - 213)%31 + 1;
- }
- else if(num_daytmp < 274)/* 九月 */
- {
- RTC_DateTimeStructure->Month = 9;
- RTC_DateTimeStructure->Date = (num_daytmp - 244)%30 + 1;
- }
- else if(num_daytmp < 305)/* 十月 */
- {
- RTC_DateTimeStructure->Month = 10;
- RTC_DateTimeStructure->Date = (num_daytmp - 274)%31 + 1;
- }
- else if(num_daytmp < 335)/* 十一月 */
- {
- RTC_DateTimeStructure->Month = 11;
- RTC_DateTimeStructure->Date = (num_daytmp - 305)%30 + 1;
- }
- else if(num_daytmp < 366)/* 十二月 */
- {
- RTC_DateTimeStructure->Month = 12;
- RTC_DateTimeStructure->Date = (num_daytmp - 335)%31 + 1;
- }
- }
- else
- {
- /* 平年一年内的天数 */
- num_daytmp = num_day - RTC_DateTimeStructure->Year*365 - num_leapyear ;
- if(num_daytmp < 31)
- {
- RTC_DateTimeStructure->Month = 1;
- RTC_DateTimeStructure->Date = num_daytmp%31 + 1;
- }
- else if(num_daytmp < 59)
- {
- RTC_DateTimeStructure->Month = 2;
- RTC_DateTimeStructure->Date = (num_daytmp - 31)%28 + 1;
- }
- else if(num_daytmp < 90)
- {
- RTC_DateTimeStructure->Month = 3;
- RTC_DateTimeStructure->Date = (num_daytmp - 59)%31 + 1;
- }
- else if(num_daytmp < 120)
- {
- RTC_DateTimeStructure->Month = 4;
- RTC_DateTimeStructure->Date = (num_daytmp - 90)%30 + 1;
- }
- else if(num_daytmp < 151)
- {
- RTC_DateTimeStructure->Month = 5;
- RTC_DateTimeStructure->Date = (num_daytmp - 120)%31 + 1;
- }
- else if(num_daytmp < 181)
- {
- RTC_DateTimeStructure->Month = 6;
- RTC_DateTimeStructure->Date = (num_daytmp - 151)%30 + 1;
- }
- else if(num_daytmp < 212)
- {
- RTC_DateTimeStructure->Month = 7;
- RTC_DateTimeStructure->Date = (num_daytmp - 181)%31 + 1;
- }
- else if(num_daytmp < 243)
- {
- RTC_DateTimeStructure->Month = 8;
- RTC_DateTimeStructure->Date = (num_daytmp - 212)%31 + 1;
- }
- else if(num_daytmp < 273)
- {
- RTC_DateTimeStructure->Month = 9;
- RTC_DateTimeStructure->Date = (num_daytmp - 243)%30 + 1;
- }
- else if(num_daytmp < 304)
- {
- RTC_DateTimeStructure->Month = 10;
- RTC_DateTimeStructure->Date = (num_daytmp - 273)%31 + 1;
- }
- else if(num_daytmp < 334)
- {
- RTC_DateTimeStructure->Month = 11;
- RTC_DateTimeStructure->Date = (num_daytmp - 304)%30 + 1;
- }
- else if(num_daytmp < 365)
- {
- RTC_DateTimeStructure->Month = 12;
- RTC_DateTimeStructure->Date = (num_daytmp - 334)%31 + 1;
- }
- }
- /* 星期 */
- RTC_DateTimeStructure->Week = (num_day + 5)%7 + 1;
- /* 时 */
- RTC_DateTimeStructure->Hour = (count_value / 3600) % 24;
- /* 分 */
- RTC_DateTimeStructure->Minute = (count_value % 3600) / 60;
- /* 秒 */
- RTC_DateTimeStructure->Second = count_value % 60;
- }
- /************************************************
- 函数名称 : RTC_Initializes
- 功 能 : RTC初始化
- 参 数 : 无
- 返 回 值 : 无
- 作 者 : sun
- *************************************************/
- void RTC_SetAlarmTime_S(uint32_t Time )
- {
- uint32_t TimeNow = 0;
- RTC_ITConfig(RTC_IT_ALR, DISABLE); //使能闹钟中断
- RTC_WaitForLastTask(); //等待操作完成
- TimeNow = RTC_GetCounter();
- TimeNow = TimeNow + Time -1;
- RTC_SetAlarm(TimeNow); //闹钟时间
- RTC_WaitForLastTask(); //等待操作完成
- RTC_ITConfig(RTC_IT_ALR, ENABLE); //使能闹钟中断
- RTC_WaitForLastTask(); //等待操作完成
- }
- /**** Copyright (C)2016 sun. All Rights Reserved **** END OF FILE ****/
|