当前位置: 首页 > news >正文

24:RTC实时时钟

RTC实时时钟

  • 1、时间戳
  • 2、BKP备份寄存器
    • 2.1:简介
    • 2.2:基本结构
  • 3、RTC时钟
  • 4、读写备份寄存器BKP
  • 5、RTC实时时钟

1、时间戳

在这里插入图片描述

#include <stdio.h>
#include <time.h>time_t ourtime;				// time_t = int64_t;
struct tm day;
struct tm day1;
struct tm day2;int main(void)
{//t = time(NULL);//获取伦敦的时间戳的秒数,time(&ourtime);printf("伦敦的时间戳:%d\n",ourtime);long long int d = ourtime + 28800;printf("本地的时间戳:%d\n",d);day = *gmtime(&ourtime);//转换为伦敦的年月日时分秒printf("伦敦时间:%d-%d-%d %d:%d:%d。\n",day.tm_year+1900,day.tm_mon+1,day.tm_mday,day.tm_hour,day.tm_min,day.tm_sec);day1 = *gmtime(&d);//转换为本地的年月日时分秒printf("本地时间:%d-%d-%d %d:%d:%d。\n",day1.tm_year+1900,day1.tm_mon+1,day1.tm_mday,day1.tm_hour,day1.tm_min,day1.tm_sec);day2 = *localtime(&ourtime);//转换为当地的年月日时分秒printf("本地时间:%d-%d-%d %d:%d:%d。\n",day2.tm_year+1900,day2.tm_mon+1,day2.tm_mday,day2.tm_hour,day2.tm_min,day2.tm_sec);ourtime = mktime(&day2);//将本地的日期转换为伦敦的时间戳printf("伦敦的时间戳:%d\n",ourtime);char t[50];strftime(t,50,"%Y-%m-%d %H:%M:%S",&day1);//打印自定义的时间格式printf("本地时间:%s\n",t);return 0;
}

伦敦的时间戳:1725763707
本地的时间戳:1725792507
伦敦时间:2024-9-8 2:48:27。
本地时间:2024-9-8 10:48:27。
本地时间:2024-9-8 10:48:27。
伦敦的时间戳:1725763707
本地时间:2024-09-08 10:48:27

2、BKP备份寄存器

2.1:简介

1、备份寄存器,用于存储数据,当VDD电源被切断时,这个备份寄存器由VBAT维持供电。如果VBAT电源也被切断,那么里面的数据就会被清除。当系统在待机模式下被唤醒,或系统复位或电源复位时,也不会被复位
2、TAMPER引脚产生的侵入事件将所有备份寄存器内容清除

3、用户数据存储容量:
20字节r(中容量和小容量)/84字节(大容量和互联型)

2.2:基本结构

在这里插入图片描述

由上图所示:一个数据寄存器DR只能存储2个字节,而中容量和小容量只能存储20个字节,所以BKP中的数据寄存器DR只有10个。除了由数据寄存器,还有RTC的控制寄存器和状态寄存器和RTC时钟校准寄存器。

3、RTC时钟

RTC是一个独立的定时器,本质就是一个计时器。RTC和时钟配置系统处于后备区域,VDD(2.0~3.6V)断电后可借助VBAT (1.8~3.6V)供电继续走时。但是如果系统复位或电源复位时,秒计数器里面会从初始值开始计数
1、32位的可编程计数器,可对应Unix时间戳的秒计数器
2、20位的可编程预分频器,可适配不同频率的输入时钟
3、可选择三种RTC时钟源:
HSE时钟除以128(通常为8MHz/128)
LSE振荡器时钟(通常为32.768KHz)
LSI振荡器时钟(40KHz)

在这里插入图片描述

时钟来源:
在这里插入图片描述
如上图所示:RTC的时钟来源一般是LSE32.768KHz,而20位RTC预分频器设置为2^15,则正好为1Hz。而且只有这一路的时钟由备用电池VBAT供电。

在这里插入图片描述

在这里插入图片描述

注意事项:
在这里插入图片描述

4、读写备份寄存器BKP

在这里插入图片描述标准库的编程接口:
在这里插入图片描述

/*BKP(备份寄存器)数据的写入与读取测试
*/#include "stm32f10x.h"                 
#include "OLED.h"uint16_t Data;int main(void)
{OLED_Init();//1、开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能PWRRCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);//使能BKP//2、使能对BKP的访问PWR_BackupAccessCmd(ENABLE);//使能对BKP和RTC的访问//3、写入数据BKP_WriteBackupRegister(BKP_DR1,0x1234);//写入数据寄存器DR1//4、读取数据Data = BKP_ReadBackupRegister(BKP_DR1);//读取数据寄存器DR1的数据OLED_ShowHexNum(1,1,Data,4);while(1){}
}

5、RTC实时时钟

标准库的编程接口:
在这里插入图片描述
RTC.c文件的代码如下:

#include "stm32f10x.h"                  // Device header
#include <time.h>uint16_t MyRTC_Time[] = {2024,9,10,21,10,55};//设置时间:年月日时分秒void MyRTC_SetTime(void);//设置时间的函数void MyRTC_Init(void)
{//1、开启PWR和BKP的时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);//2、使能BKP和RTC的访问PWR_BackupAccessCmd(ENABLE);if(BKP_ReadBackupRegister(BKP_DR1) != 0x1111)//按下复位按钮,BKP中DR1不清除,则不用重装计数器里面的时间戳{///3、配置时钟源RCC_LSEConfig(RCC_LSE_ON);//打开LSE//4、等待LSE启动完成while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);//5、选择RTC时钟源RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//选择LSE为时钟源RCC_RTCCLKCmd(ENABLE);//6、等待同步和操作完成RTC_WaitForSynchro();//等待同步RTC_WaitForLastTask();//等待操作完成//7、配置预分频器RTC_SetPrescaler(32768 - 1);//设置分频系数为32768RTC_WaitForLastTask();//等待操作完成MyRTC_SetTime();BKP_WriteBackupRegister(BKP_DR1,0x1111);}else{RTC_WaitForSynchro();//等待同步RTC_WaitForLastTask();//等待操作完成}
}void MyRTC_SetTime(void)//设置时间的函数
{time_t ourtime;struct tm day;day.tm_year = MyRTC_Time[0]-1900;day.tm_mon = MyRTC_Time[1]-1;day.tm_mday = MyRTC_Time[2];day.tm_hour = MyRTC_Time[3];day.tm_min = MyRTC_Time[4];day.tm_sec = MyRTC_Time[5];ourtime = mktime(&day);//将日期转换为时间戳秒RTC_SetCounter(ourtime);RTC_WaitForLastTask();//等待操作完成
}void MyRTC_ReadTime(void)
{time_t ourtime;struct tm day;ourtime = RTC_GetCounter();//获取RTC计数器的值day = *localtime(&ourtime);//将时间戳转换为本地的年月日时分秒MyRTC_Time[0] = day.tm_year + 1900;//将转换的数据保存在数组中MyRTC_Time[1] = day.tm_mon + 1;MyRTC_Time[2] = day.tm_mday;MyRTC_Time[3] = day.tm_hour;MyRTC_Time[4] = day.tm_min;MyRTC_Time[5] = day.tm_sec;
}

主程序的代码如下:

/*RTC实时时钟的使用
*/#include "stm32f10x.h"                 
#include "OLED.h"
#include "MyRTC.h"int main(void)
{OLED_Init();MyRTC_Init();OLED_ShowString(1,1,"Data:xxxx-xx-xx");OLED_ShowString(2,1,"Time:xx:xx:xx");OLED_ShowString(3,1,"CNT:");while(1){MyRTC_ReadTime();//显示日期OLED_ShowNum(1,6,MyRTC_Time[0],4);OLED_ShowNum(1,11,MyRTC_Time[1],2);OLED_ShowNum(1,14,MyRTC_Time[2],2);//显示时间OLED_ShowNum(2,6,MyRTC_Time[3],2);OLED_ShowNum(2,9,MyRTC_Time[4],2);OLED_ShowNum(2,12,MyRTC_Time[5],2);//显示秒时间戳OLED_ShowNum(3,5,RTC_GetCounter(),10);}
}

在这里插入图片描述


http://www.mrgr.cn/news/30859.html

相关文章:

  • 【学术会议:中国杭州,机器学习和计算机应用面临的新的挑战问题和研究方向】第五届机器学习与计算机应用国际学术会议(ICMLCA 2024)
  • 第十九节:学习WebFlux与前端响应式-非阻塞-流式通讯(自学Spring boot 3.x的第四天)
  • 平价头戴式蓝牙耳机有哪些?四款公认平价性能超强品牌机型推荐
  • 第六天旅游线路预览——从景区门口到天山天池
  • JavaScript可视化
  • 【Unity踩坑】UI Image的fillAmount不起作用
  • 创新的护盾:知识产权、商标与软件著作权的全方位解读
  • 【QGIS】(六)对图层添加属性并赋值行号(可作为导入数据的主键使用)
  • 大厂常问的MySQL事务隔离到底怎么回答
  • LabVIEW闪退
  • AutoX.js向后端传输二进制数据
  • js 深入理解类-class
  • Python数据处理入门教程!
  • 低侧单向电流、单电源检测电路
  • Redis系列---Redission分布式锁
  • 深度学习激活函数
  • 力扣560 和为k的子数组 Java版本
  • CCRC-CDO首席数据官:未成年人首次上网年龄持续降低
  • vmware官网下载
  • 企业如何使用数据分析管理系统