源:RTC-高效率实现TimerTicker编解码

  嵌入式系统中时间是很重要的,在以往的系统中设计者常常使用一种叫RTC的专用芯片来维持时间,这种芯片种类很多接口形式也很多,如常用的DS1302、PCF8563、DS12887等等,虽然用起来方便,但额外增加一个器件和一种驱动程序,这同时也增加了系统的不安全因素,并且很多时候嵌入式工程师常发现这些时钟芯片的走时精度值得怀疑,且难于修改。

  现在的MCU或MPU,一般都带有RTC功能,这对嵌入式工程师来说是个好消息,不用再为此扩展一枚芯片了,但通常RTC寄存器中提供的是一个32位的时间刻度值,并没有专用芯片那样分解成时分秒日月年之类的,此处,我将讨论它们的互换算法,其实也很简单。

  一般可以设定RTC寄存器每秒加1,这样寄存器中的值使终代表了当前累计的秒数,还好这种RTC结构都是可以由后备电池来维护运行的,不致于断电就没有了。这个32位寄存器值被称为TimerTicker,时间刻度,很是形象。

  首先考虑记录时间,32位的整型量每秒加一,其共能记录的时间为,2的32次方秒,即约136.19年,这对于一个产品来说运行时间相当足够了,试想一个产品能运行超过136年是多么恐怖的数字啊。

  

  如何把任意时刻转换成为刻度呢?也就是编码。

  先看下面的时间结构:

typedef struct
{
uint8 Year;       //年
uint8 Month;       //月
uint8 Day;  //日
uint8 Hour; //时
uint8 Minute; //分
uint8 Second; //秒
}DateTime;

  上面定义的结构实现了最常用的时间结构,对于具体应用,可以添加星期等。其年份可以用年纷的后两位实现,这样可以实现任何世纪,呵呵,理论上。

  下面的方法将把此结构编码成为时间刻度:

//Author: 愿陪你一生 QQ380052073
//Note: 本方法时间起点从2000-1-1 0:0:0开始,向后编码150年
uint32 RTC_EncodeTime(DateTime * DT)
{
uint8 T,K;
uint32 T32,TimeData=;
for(T=,K=;T<DT->Year;T++){ //累加年份
K=T&0x03;
TimeData+=K?:;
}
for(T=;T<DT->Month;T++){
if(T!=){ //统计平月
T32=((T+(T>>))&0x01)?:;
}else T32=K?:; //统计闰月
TimeData+=T32;
}
T32=DT->Day-;TimeData+=T32*; //统计天
T32=DT->Hour;TimeData+=T32*; //统计时
T32=DT->Minute;TimeData+=T32*; //统计分
TimeData+=DT->Second; //统计秒
return TimeData;
}

  以上方法实现任意时刻编码,其算法思路是先累加年份,从起点年份开始向后计算,每过四年要计算一次闰年,其它为平年,这里运用位运算方法实现了闰年和平年的判断,接下来就计算一年中的月数,这里要对2月份分闰年和平年来讨论,上面的方法中供用了闰平年判断的标志,不用再次判断。最后是时分秒的累加过程,这部分最简单了,全部化为秒即可。

  

  同样的思路,可以实现从任意刻度解码到当前时间,即逆变换过程,如下面的方法:

//Author: 愿陪你一生 QQ380052073
//Note: 本方法时间起点从2000-1-1 0:0:0开始,向后解码150年
void RTC_DecodeTime(uint32 TimeData,DateTime * DT)
{
uint8 T,K;
uint32 T16,K16;
K16=TimeData%; //分离时/分/秒
T16=TimeData/; //分离年/月/日
DT->Second=K16%; //计算秒
K16/=;DT->Minute=K16%; //计算分
K16/=;DT->Hour=K16%; //计算时
for(K16=,T=;T<;T++){ //按天累计年份
K16=(T&0x03)?:; //统计闰年
if(T16<K16){K16-=;break;} //计算当年二月份天数
else T16-=K16; //减掉年份
}
DT->Year=T; //计算得到相对年份
for(T=;T<;T++){
K=(T==)?K16:(((T+(T>>))&0x01)+); //统计当月天数
if(T16>=K)T16-=K; //减掉当前月
else break;
}
DT->Month=T; //计算得到当年中的月份
DT->Day=T16+; //计算得到当年中的天
}

  上面的算法实现了解码,正好采用相反的方向,先分离出时分秒和年月日,因为闰平年中一天种有24个小时,一小时总是3600秒,而从一月有多少天这里开始出现分岐,所以分离出两部分。秒分时的解码从前部分中得到,依次求余即可,而年月日的分离则需要考虎闰平年和是否2月等。同样先从起点时刻向上累加天数,中间需要区分闰平年,之后即可把年份提取出来,随后再分开月和天,月分的闰年标记同样从年份分离中得到。

  以上只是时间刻度编解码的一种方法,经过测试,其效率还是比较高的,运行速度和程序占用空间都满意,适合MCU使用。在分解后的时间结构中,还可以实现类似农历的算法。

RTC-高效率实现TimerTicker编解码的更多相关文章

  1. 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放 license收费等 ...

  2. 集显也能硬件编码:Intel SDK && 各种音视频编解码学习详解

    http://blog.sina.com.cn/s/blog_4155bb1d0100soq9.html INTEL MEDIA SDK是INTEL推出的基于其内建显示核心的编解码技术,我们在播放高清 ...

  3. 我的Android进阶之旅------>Android中编解码学习笔记

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

  4. 【miscellaneous】各种音视频编解码学习详解

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

  5. 【FFMPEG】各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    目录(?)[-] 编解码学习笔记二codec类型 编解码学习笔记三Mpeg系列Mpeg 1和Mpeg 2 编解码学习笔记四Mpeg系列Mpeg 4 编解码学习笔记五Mpeg系列AAC音频 编解码学习笔 ...

  6. 【知识点】H264, H265硬件编解码基础及码流分析

    前言 音视频开发需要你懂得音视频中一些基本概念,针对编解码而言,我们必须提前懂得编解码器的一些特性,码流的结构,码流中一些重要信息如sps,pps,vps,start code以及基本的工作原理,而大 ...

  7. iOS8系统H264视频硬件编解码说明

    公司项目原因,接触了一下视频流H264的编解码知识,之前项目使用的是FFMpeg多媒体库,利用CPU做视频的编码和解码,俗称为软编软解.该方法比较通用,但是占用CPU资源,编解码效率不高.一般系统都会 ...

  8. IOS和Android支持的音频编解码

    1.IOS编码 参考文档地址:https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/Multimedi ...

  9. java编解码技术,netty nio

    对于java提供的对象输入输出流ObjectInputStream与ObjectOutputStream,可以直接把java对象作为可存储 的字节数组写入文件,也可以传输到网络上去.对与java开放人 ...

随机推荐

  1. [PHP] 安装和配置

    Apachehttpd-2.2.19-win64mysql5.6Phphttp://www.php.net/downloads.php 5.4Phpeclipsehttp://www.phpeclip ...

  2. OLEDB和ODBC的区别

    ODBC(开放数据库互连):是Microsoft引进的一种早期数据库接口技术.它实际上是ADO的前身.早期的数据库连接是非常困难的. 每个数据库的格式都不一样,开发者得对他们所开发的每种数据库的底层A ...

  3. CSS样式与选择器

    CSS构造块的样式: 1.  h1{color:red;background-color:yellow} 其中:h1是选择器,花括号内是声明部分.多个声明之间用分号隔开. 2.为样式规则添加注释:/* ...

  4. apache:添加cgi模式

    最终期望:通过配置apache的cgi能够使得apache能通过cgi方式连接go程序(因为我们的后端程序是用go语言写的). 实验1: 期望:通过配置cgi使得应用程序能够跑起来. go代码: pa ...

  5. CAFFE中训练与使用阶段网络设计的不同

    神经网络中,我们通过最小化神经网络来训练网络,所以在训练时最后一层是损失函数层(LOSS), 在测试时我们通过准确率来评价该网络的优劣,因此最后一层是准确率层(ACCURACY). 但是当我们真正要使 ...

  6. MyEclipse运行到断点也跳过的问题

    如果是B/S开发也就是javaWeb开发的话,Tomcat 的启动模式要设置成Debug模式 还有下面是没运行时断点的样子: 运行的时候,断点会变成对钩,表示执行到它所在代码的时候会停下来:

  7. to_date()与to_char()

    1.以时间(Date类型)为查询条件时,可以用to_date函数实现: select t.* from D101 t where t.d101_40 = to_date('2013/9/12', 'y ...

  8. NDK编译应用程序

    Android源码目录下的build/envsetup.sh文件,描述编译的命令 - m:       Makes from the top of the tree. - mm:      Build ...

  9. THE ROAD TO PROGRAM

    <The C Programming Language> <The Practice of Programming><The Art of Computer Progra ...

  10. GCD应用场景

    1.计算文件大小放在子线程中中计算,计算完了,回到主线程更新UI