关于RTC秒中断的使用,断电可以继续跑,获取实时时间

您所在的位置:网站首页 pcr断电后可以继续跑吗 关于RTC秒中断的使用,断电可以继续跑,获取实时时间

关于RTC秒中断的使用,断电可以继续跑,获取实时时间

2024-07-01 22:58| 来源: 网络整理| 查看: 265

RTC其实就是一种计数器,只要纽扣电池存在,RTC就能持续计时,需要给它设置一个初始时间(为了准确需要联网实现,但只使用RTC的话,可以自己创建一个数组来赋初值)

用的是localtime函数,以指针的形式获取到数据的

在主函数中调用设置时间函数(放在循环外,不然每次上电都会重新设置时间,获取一次以后就屏蔽掉,RTC会保存数据的,就可以查看了)

注意:这行代码加上去RTC会一直从0开始,就变成了秒表计数的感觉(千万不能加)

int main(){ RTC_SetTime(); __WFI();//闹钟中断的睡眠模式 while (1) { Sensor_SerialSreen_show(); rt_thread_delay(50); //延时50个tick } }

代码如下

rtc.c

#include "rtc.h" #include "usart.h" #include "stdio.h" #include "string.h" #include "time.h" #include "public.h" #include "led.h" struct tm *d = NULL; uint32_t a = 0; time_t time_cnt; //定义秒计数器数据类型 // struct tm time_date; //定义日期时间数据类型 uint32_t alarm_time; void RTC_IRQHandler(void) { // RTC_SetTime(); //秒中断 if(RTC_GetITStatus(RTC_IT_SEC)==SET) { RTC_ClearITPendingBit(RTC_IT_SEC); a = RTC_GetCounter(); d = localtime((time_t *)&a); /* Clear Interrupt pending bit */ RTC_ClearITPendingBit(RTC_FLAG_SEC); // printf("%d/%d/%d %02d:%02d:%02d\n", 1900 + p->tm_year, 1+ p->tm_mon, p->tm_mday,p->tm_hour, p->tm_min, p->tm_sec); // printf("%d/%d/%d %d/%d/%d %d\r\n",\ // d->tm_year+1900,d->tm_mon+1,d->tm_mday,\ // d->tm_hour,d->tm_min,d->tm_sec,d->tm_wday); } //闹钟中断,修改中,暂时没写完· if(RTC_GetITStatus(RTC_IT_ALR)==SET) { RTC_ClearITPendingBit(RTC_IT_ALR);//清闹钟中断 alarm_time=RTC_GetCounter()+1*6; alarm_time = alarm_time - alarm_time%60;//设置时精确到分,将秒去除 RTC_SerAlarmSec(alarm_time);//每来一次闹钟,闹钟时间向后推alarm_time LED2(0); LED3(0); // RTC_ClearITPendingBit(RTC_FLAG_ALR); } } void RTC_SerAlarmSec(uint32_t s) { //设置时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟 PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问 RTC_SetAlarm(s); RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成 } void RTC_Config(void) { /* NVIC configuration 中断配置*/ NVIC_Configuration(); //● 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟 /* Enable PWR and BKP clocks */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //● 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。 /* Allow access to BKP Domain */ PWR_BackupAccessCmd(ENABLE); //检测RTC是否已经进行过配置 读取BKP_DR寄存器里面的数据 if (BKP_ReadBackupRegister(BKP_DR1) != 0xA6A6) { /* Backup data register value is not correct or not yet programmed (when the first time the program is executed) */ // printf("\r\n\n RTC not yet configured...."); /* RTC Configuration */ RTC_Configuration(); printf("\r\n RTC configured...."); BKP_WriteBackupRegister(BKP_DR1, 0xA6A6); } else { /* Check if the Power On Reset flag is set */ if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET) { // printf("\r\n\n Power On Reset occurred...."); } /* Check if the Pin Reset flag is set */ else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET) { // printf("\r\n\n External Reset occurred...."); } printf("\r\n No need to configure RTC...."); /* Wait for RTC registers synchronization */ RTC_WaitForSynchro(); /* Enable the RTC Second */ RTC_ITConfig(RTC_IT_SEC, ENABLE); RTC_ITConfig(RTC_IT_ALR, ENABLE); /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); // get_time(); } /* Clear reset flags */ RCC_ClearFlag(); // RTC_SetCounter(0); // RTC_SetTime(); /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); } /** * @brief Configures the nested vectored interrupt controller. * @param None * @retval None */ void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure = {0}; /* Enable the RTC Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /** * @brief Configures the RTC. * @param None * @retval None */ void RTC_Configuration(void) { /* Reset Backup Domain */ BKP_DeInit(); /* Enable LSE 打开LSE*/ RCC_LSEConfig(RCC_LSE_ON); // RCC_LSICmd(ENABLE); /* Wait till LSE is ready 等待LSE准备完毕*/ while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {} /* Select LSE as RTC Clock Source 选择RTC时钟源 */ RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); /* Enable RTC Clock 使能RTC时钟 */ RCC_RTCCLKCmd(ENABLE); /* Wait for RTC registers synchronization */ RTC_WaitForSynchro(); /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); /* Enable the RTC Second 开启秒中断*/ RTC_ITConfig(RTC_IT_SEC, ENABLE); RTC_ITConfig(RTC_IT_ALR, ENABLE); /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); /* Set RTC prescaler: set RTC period to 1sec 分频*/ RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */ /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); } uint16_t MyRTC_Time[] = {2023, 11, 14, 17, 16, 00}; void RTC_SetTime(void) { d->tm_year = MyRTC_Time[0] - 1900; //将数组的时间赋值给日期时间结构体 d->tm_mon = MyRTC_Time[1] - 1; d->tm_mday = MyRTC_Time[2]; d->tm_hour = MyRTC_Time[3]; d->tm_min = MyRTC_Time[4]; d->tm_sec = MyRTC_Time[5]; time_cnt = mktime(d); //调用mktime函数,将日期时间转换为秒计数器格式 RTC_SetCounter(time_cnt); //将秒计数器写入到RTC的CNT中 RTC_WaitForLastTask(); }

rtc.h

#ifndef _RTC_H_ #define _RTC_H_ #include "stm32f10x.h" extern struct tm *d; //extern struct tm time_date; //定义日期时间数据类型 void NVIC_Configuration(void); void RTC_Configuration(void); void RTC_Config(void); void RTC_SetTime(void); //void RTC_GetTime(void); //void RTC_SerAlarmSec(uint32_t s); #endif



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3