KEIL-MDK的时间戳之time.h 结合gd32f1的RTC应用

KEIL-MDK的时间戳之time.h 的应用

1 时间戳介绍

现在物联网产品的在进行通讯的时候,需要加入时间戳的这个信息参数,方便服务器和产品之间交换时间信息。

时间戳是计算机系统中用来表示日期和时间的一种方式,通常是一个数字或者一串字符,表示从某个特定时间点(通常是“纪元”或“起始时间”)开始经过的秒数或者毫秒数。时间戳通常是以协调世界时(UTC)为基准的,但也可以根据需要使用其他时区。

时间戳的优点是它提供了一种统一的方式来表示时间,无论用户所在的时区如何,都可以通过时间戳来精确地表示一个特定的时间点。这在计算机系统中进行时间计算、排序和存储时非常有用。

时间戳通常用于记录事件发生的时间,例如在日志文件中记录系统活动的时间、在数据库中存储数据的创建或修改时间等。它也经常用于计算时间间隔,例如计算两个事件之间经过的时间,或者用于定时任务的调度。

在很多编程语言和操作系统中,时间戳通常是以自某个特定日期开始的秒数来表示,这个特定日期被称为“纪元”(epoch)。UNIX 系统通常使用1970年1月1日作为纪元,而Windows系统则使用1601年1月1日。

KEIL的time文件采用UNIX 系统通常使用1970年1月1日作为纪元。

2 RTC模块介绍

GD32F1系列是基于ARM Cortex-M3内核的通用微控制器系列,由中国的光电半导体(GigaDevice)公司开发。该系列包括了具有丰富外设和功能的微控制器,其中也包括了RTC(Real-Time Clock,实时时钟)模块。

RTC模块是用来提供精确的时间信息的硬件设备,在嵌入式系统中通常用于实现实时时钟、日历功能和时间戳等应用。以下是关于GD32F1系列的RTC模块的一般介绍。

这里以gd32f1的RTC为例。 gd32f1的集成了一个RTC的模组,可以非常方便自动记录时间。

2.1 电路设计

为了达到比较精确的时间记录,为RTC增加了一个32.768kHz的晶振。 这样比较保存时间。
在这里插入图片描述
在这里插入图片描述

2.2 驱动代码开发

开发RTC(Real-Time Clock,实时时钟)驱动代码的配置思路如下:

选择合适的时钟源:

RTC通常需要一个稳定的时钟源来提供时间基准。这可以是外部晶振或者内部RC振荡器。在配置RTC之前,需要确定使用哪种时钟源,并相应地配置系统时钟。
初始化RTC模块:

首先,需要初始化RTC模块,包括启用RTC时钟、选择时钟源、配置分频系数等。这通常涉及设置RTC相关的寄存器,具体操作可参考MCU的技术手册。
设置时间:

在RTC初始化后,需要设置当前时间。这可以通过设置RTC的年、月、日、时、分、秒等寄存器来完成。一般情况下,需要提供一个函数接口,允许用户设置初始时间。
配置闹钟功能(可选):

如果需要使用RTC的闹钟功能,需要配置相应的闹钟寄存器。这包括设置闹钟触发时间、选择触发模式(例如每秒、每分钟、每小时等)、启用闹钟中断等。
处理RTC中断:

如果RTC模块支持中断功能,需要编写中断服务程序(ISR)来处理RTC中断。这可能涉及到处理时间更新中断、闹钟触发中断等。在中断服务程序中,通常需要清除相应的中断标志位。
备份寄存器的使用(可选):

一些MCU的RTC模块提供了备份寄存器,用于在系统掉电时保存特定的数据。如果需要使用备份寄存器,需要相应地初始化和配置备份寄存器。
测试与调试:

完成RTC驱动代码后,需要进行测试和调试。可以使用仿真器或者实际硬件进行测试,并检查RTC功能是否按预期工作。
优化与稳定性提升:

在测试过程中,可以对RTC驱动代码进行优化,提高代码的稳定性和性能。例如,考虑使用更有效率的算法或者减少对寄存器的访问次数来优化代码。
通过以上步骤,可以完成对RTC模块的驱动代码配置,实现所需的实时时钟功能,并确保代码的可靠性和稳定性。

void rtc_configuration(void)
{/* enable PMU and BKPI clocks */rcu_periph_clock_enable(RCU_BKPI);rcu_periph_clock_enable(RCU_PMU);/* allow access to BKP domain */pmu_backup_write_enable();/* reset backup domain */bkp_deinit();/* enable LXTAL */rcu_osci_on(RCU_LXTAL);/* wait till LXTAL is ready */rcu_osci_stab_wait(RCU_LXTAL);/* select RCU_LXTAL as RTC clock source */rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);/* enable RTC Clock */rcu_periph_clock_enable(RCU_RTC);/* wait for RTC registers synchronization */rtc_register_sync_wait();/* wait until last write operation on RTC registers has finished */rtc_lwoff_wait();//    /* enable the RTC second interrupt*/
//    rtc_interrupt_enable(RTC_INT_SECOND);//    /* wait until last write operation on RTC registers has finished */
//    rtc_lwoff_wait();/* set RTC prescaler: set RTC period to 1s */rtc_prescaler_set(32767);/* wait until last write operation on RTC registers has finished */rtc_lwoff_wait();
}

3 字符串转化成为时间戳

将字符串转换为时间戳的过程通常需要以下步骤,具体实现方式取决于所用编程语言和库:

解析字符串:首先,需要解析输入的字符串,提取其中的年、月、日、时、分、秒等时间信息。这可能需要使用字符串处理函数或正则表达式来提取有效的时间信息。

转换为结构化时间:将提取出的时间信息转换为结构化时间,即包含年、月、日、时、分、秒等字段的时间数据结构。不同编程语言和库提供了不同的函数或类来表示结构化时间。

转换为时间戳:最后,将结构化时间转换为时间戳,即从某个特定时间点(通常是纪元时间,如1970年1月1日)开始的秒数或毫秒数。通常可以使用编程语言提供的时间转换函数来实现这一步骤。

具体实现步骤

3.1 字符串转化成为年、月、日、时、分、秒等时间信息

// 时间字符串转化成为时间   "19/05/29,02:05:29+32"  "07/10/25,11:33:44+08"
int DateString_to_TM(Bat_Struct *p_bat)
{if(rt_strncmp(p_bat->rtcstr,"\0",2)==0)   // 判断输入不为空{return 1;   // 输入错误}else{
//		struct tm myTime = {0}; char arr[32];strcpy(arr,p_bat->rtcstr);  // 复制数据rt_kprintf("arr is %s\r\n",arr);const char * sep = "/,:+";  // 分割符号char *str = NULL;	uint32_t n=1;int val;for( str=strtok(arr, sep);str!=NULL;str=strtok(NULL,sep)){switch(n){case 1:  {val = atoi(str);if(val !=0){p_bat->date.tm_year=val+2000; // 获取年n++;break;}else{return 2;  // 解析错误}}case 2:  {val = atoi(str);				p_bat->date.tm_mon=val; // 获取月n++;break;}case 3:  {val = atoi(str);				p_bat->date.tm_mday=val; // 获取日n++;break;}case 4:  {val = atoi(str);				p_bat->date.tm_hour=val; // 获取hour					   n++;break;}case 5:  {val = atoi(str);				p_bat->date.tm_min=val; // 获取minn++;break;}case 6:  {val = atoi(str);				p_bat->date.tm_sec=val; // 获取minn++;break;}default: break;			}			}if(n<6){return 2;  // 解析错误}		else{return 0;   // 成功}}	
}

3.2 利用mktime变成时间戳,同时考虑时区问题。

其中tm_diff 用来调整时区,北京时区是东八区

uint32_t time_regulate(int syear,int smon,int sday,int hour,int min,int sec)
{time_t time_t_Set_Time;     //定义time_t类型的设置时间结构体struct tm tm_Set_Time;      //定义tm结构的设置时间结构体tm_Set_Time.tm_year = (uint32_t)(syear-1900); //从1900年开始算起tm_Set_Time.tm_mon  = (uint32_t)(smon-1);     //月tm_Set_Time.tm_mday = (uint32_t)sday;         //日tm_Set_Time.tm_hour = (uint32_t)hour;         //时tm_Set_Time.tm_min  = (uint32_t)min;          //分tm_Set_Time.tm_sec  = (uint32_t)sec;          //秒tm_Set_Time.tm_isdst=0;struct tm diff;diff.tm_year = (uint32_t)(1970-1900); //从1900年开始算起diff.tm_mon  = 0;     //月diff.tm_mday = 1;         //日diff.tm_hour = 8;         //时区diff.tm_min  = 0;          //分diff.tm_sec  = 0;          //秒diff.tm_isdst=0;time_t_Set_Time=mktime(&tm_Set_Time)-mktime(&diff);     // 插入                 return time_t_Set_Time;   // 存储时间戳}

3.3 写入寄存器

把时间戳的值写入到寄存器中,可以让RTC电路自动进行累加。

 rtc_lwoff_wait();/* change the current time */rtc_counter_set(time_regulate(data->tm_year,data->tm_mon,data->tm_mday,data->tm_hour,data->tm_min,data->tm_sec));/* wait until last write operation on RTC registers has finished */rtc_lwoff_wait();

3.4 读取时间戳

sysBat.timestamp=rtc_counter_get();   // 获取时间戳

4 把时间戳变成字符串

// 定义时间戳time_t timestamp = 1644202496; // 2024-02-07 12:34:56// 使用localtime函数将时间戳转换为tm结构体struct tm *timeinfo;timeinfo = localtime(&timestamp);// 使用strftime函数将tm结构体格式化为字符串char buffer[80];strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", timeinfo);// 输出格式化后的字符串printf("Formatted date and time: %s\n", buffer);

5 总结

RTC的实际使用结合时间戳比较应用价值,很多参考案把f1当作只能记录一天时间的读秒器,失去这个RTC应用意义。希望这篇文章帮助读者更好应用RTC的这个模组。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2778977.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【DDD】学习笔记-统一语言与领域分析模型

无论你采用什么样的软件开发过程&#xff0c;对于一个复杂的软件系统&#xff0c;都必然需要通过分析阶段对问题域展开分析&#xff0c;如此才能有的放矢地针对该软件系统的需求寻找设计上的解决方案。在领域驱动设计中&#xff0c;分析阶段完全围绕着“领域”为中心展开&#…

从信息隐藏到功能隐藏

本文主要记录复旦大学张新鹏教授于2022年12月在第三届CSIG中国媒体取证与安全大会上的汇报

微信小程序 民宿预订租赁系统uniApp

通过山青水磨APP办理租房相关业务&#xff0c;线上解决预定、退订的业务&#xff0c;旅客在使用时更加灵活&#xff0c;实现了快速找房&#xff0c;在线沟通、便捷租赁等操作&#xff0c;除此以外&#xff0c;还能帮助旅客获取周边资讯、当地特色活动服务&#xff0c;提升旅客的…

1-3 mininet中使用python API直接拓扑定义以及启动方式对比

作为SDN网络中搭建拓扑非常重要的仿真平台&#xff0c;我们可以使用mininet默认的库内拓扑文件&#xff0c;也可以使用python语言进行自定义拓扑。使用python进行拓扑定义时&#xff0c;不同的定义方式将导致其启动的方式由所不同。 一、采用最原始的命令启动方式&#xff1a; …

Python 视频转场特效处理笔记

本文参考Python-OpenCV 实现美图秀秀视频剪辑效果【特效】_opencv 多张图片 视频 特效-CSDN博客 最近研究了点python处理视频相关的东西&#xff0c;本文展示特效包括&#xff0c;竖向开幕/横向开幕&#xff0c;渐隐/渐显&#xff0c;推近/拉远&#xff0c;方形开幕&#xff0…

yolo层数连接

head [-1,6]连接的是第六层 [-1,4连接的是第四层

在虚拟机上完成Centos安装

Linux学习和使用 前言如何安装Centos初始化操作 使用VMware备份操作系统快照克隆 内容总结参考链接 本人介绍:2023年全国大学生数学建模竞赛国家二等奖,2022年蓝桥杯省二等奖,这里是一个和你一起不断努力,不断前进的程序猿一枚 前言 简单介绍一下本片文章将会讲到的内容:本章节…

大模型训练所需的硬件配置

1. 引入 训练一个大模型&#xff0c;到底需要投入多少块GPU&#xff0c;需要多少数据&#xff0c;训练多长时间能达到一个不错的效果&#xff1f; 本文引用靠谱的数据&#xff0c;来回答这些问题。 2. 全流程训练 大模型的训练&#xff0c;简单来说&#xff0c;分为Pretrain…

Peter算法小课堂—单调队列

祝大家新年快乐&#xff01; 今天这一次有点简单。 单调队列有两个要点&#xff0c;一个是单调&#xff0c;另一个就是我们的队列。 听到队列&#xff0c;我相信大家一定会想到它的好朋友BFS吧。但是……今天……可……没……那么……简单哦。 西佳佳偶像天团1 题目描述 …

第74讲Breadcrumb 面包屑实现

Breadcrumb 面包屑实现 为了实现二级路由&#xff0c;我们搞成搞个子路由&#xff0c;对于二级菜单 const routes [{path: /,name: 首页,component: () > import(../views/layout),redirect:/home,children:[{path: /home,name: 首页,component: () > import(../views…

vtkActor 设置特定图层 显示及置顶显示

问题&#xff0c;有时我们需要显示某个 Actor 在相机最前面&#xff0c;可以遮盖后面的物体;显示在顶层有点不准确&#xff1b;因为这个还相机位置也有关系&#xff1b; 这里讲三种情况&#xff1a; 1. 设置 Mapper 顶层&#xff0c;尝试了一下&#xff0c;可以用于某些场景&…

对话模型Demo解读(使用代码解读原理)

文章目录 前言一、数据加工二、模型搭建三、模型训练1、构建模型2、优化器与损失函数定义3、模型训练 四、模型推理五、所有Demo源码 前言 对话模型是一种人工智能技术&#xff0c;旨在使计算机能够像人类一样进行对话和交流。这种模型通常基于深度学习和自然语言处理技术&…

七、热身仪式(Warm-Up Rituals)

5.Warm Up Rituals 五、热身仪式 A warm up ritual is your per flight checklist you go through before you start focusing for a big session.It may be checking that you have water, that you don’t need to use the bathroom, that your phone is turned off or you’…

基于微信小程序的校园故障维修管理系统的研究与实现

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

Sodinokibi(REvil)勒索病毒黑客组织攻击姿势全解

前言 2021年6月 11日&#xff0c;国外媒体 threatpost 发布文章宣称美国能源部 (DOE) 的分包商同时也是美国国家核安全局 (NNSA) 核武器开发合作商的 Sol Oriens 公司遭受到网络攻击&#xff0c;并且 Sol Oriens 公司人员已证实该公司于上月发现被勒索病毒攻击&#xff0c;而国…

Java图形化界面编程——组件绘图原理 笔记

2.8 绘图 ​ 很多程序如各种小游戏都需要在窗口中绘制各种图形&#xff0c;除此之外&#xff0c;即使在开发JavaEE项目时&#xff0c; 有 时候也必须"动态"地向客户 端生成各种图形、图表&#xff0c;比如 图形验证码、统计图等&#xff0c;这都需要利用AWT的绘图功…

深入理解Netty及核心组件使用—下

目录 ChannelHandler ChannelHandler 接口 ChannelInboundHandler 接口 ChannelHandler 的适配器 Handler 的共享和并发安全性 资源管理和 SimpleChannelInboundHandler Bootstrap ChannelInitializer ChannelOption ChannelHandler ChannelHandler 接口 从开发人员的…

重构利器:如何用 Immer 优雅地管理应用状态

1. immer immer 是一个 JavaScript 库,用于处理不可变数据的状态更新。不可变数据意味着一旦创建,数据结构就不能被修改。在编写复杂的应用程序时,不可变性可以带来一系列好处,比如更容易追踪数据的改变、更容易实现撤销/重做功能以及更简单的状态管理。 然而,处理不可变…

更新win11后无法上网

问题描述 系统提示可以更新win11了&#xff0c;然后我就想着更新一下试试。等了好久终于下载完了准备更新&#xff0c;结果提示更新失败&#xff0c;再次更新时下载到一半就停了&#xff0c;然后就发现连不上网了&#xff08;真服了&#xff0c;win11没更新成功&#xff0c;还…

MATLAB环境下一维时间序列信号的同步压缩小波包变换

时频分析相较于目前的时域、频域信号处理方法在分析时变信号方面&#xff0c;其主要优势在于可以同时提供时域和频域等多域信号信息&#xff0c;并清晰的刻画了频率随时间的变化规律&#xff0c;已被广泛用于医学工程、地震、雷达、生物及机械等领域。 线性时频分析方法是将信…