怎样在软件中给时间写进电脑软硬件学习rtc

Linux驱动分析之RTC详解_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Linux驱动分析之RTC详解
来源:blog.csdn.net/lmm670&
作者:lmm670
这里我们针对三星的S3C24XX系列进行RTC驱动框架的分析,关于RTC(实时时钟)的功能和硬件原理我就不在这里啰嗦了,相信大家都十分清楚,不清楚的可以google或者百度一下,我想通过RTC驱动和大家探讨一下linux驱动的一般框架,为大家在linux驱动的学习路上起到一个抛砖引玉的作用。那有哥们就要问了,为什么选择RTC驱动呢?就是因为它简单明了,大家都容易明白的东西才是好东西,好啦,废话不多说,开始进入正题:
Linux常见的驱动在driver目录下都有一个文件夹,当然我们的RTC也不例外,我们进入kernel主目录下的drivers/rtc,发现下面包含了许多开发平台的RTC驱动,我们这里是以S3C24xx为主,所以我们要寻找的是“rtc-s3c.c”这个美人儿,她是我们要分析的核心;其他几个相关联的文件分别是:alarm.c, alarm-dev.c,class.c, hctosys.c, interface.c, rtc-dev.c.这几个文件就是我们这部戏的主角儿。
看戏大家都喜欢去研究人物之间的关系,A喜欢B,B喜欢C,C又喜欢D…….这里我们也来先理顺一下这几个主角之间微妙的关系:
首先,当然是我们主角中的战斗机rtc-s3c.c,她是最顶层的直接和硬件打交道的驱动文件,每个平台,高通,marvell,三星都有自己的这部分,一般被命名为类似的”rtc-msm.c,rtc-pxa.c,rtc-s3c.c”;就像每个国家每个部落,总有一批底层工作者,在默默的为上层的骄奢淫逸,荣华富贵贡献着自己的血汗;
rtc-s3c.c上面的是interface.c,顾名思义就知道是接口文件,它主要是对rtc-s3c.c进行封装,给上层提供统一的接口,屏蔽底层差异化的东东。
Interface.c再往上就到了rtc-dev.c.,rtc-dev.c最终生成了/dev/rtc,上层的应用程序就是通过操作此文件来进行RTC的相关的设置系统时间,设置闹钟,等等。
所有整个人物关系图如下:
上层应用层序
interface.c
好像三个文件就已经把整个RTC从底层到上层所有的东东都讲完了,那么还剩下几个文件干嘛呢?
Alarm.c和alarm-dev.c:这两个文件用来干什么呢?这里先留个悬念,后面和大家慢慢说明
class.c:提供了RTC子系统一些的公共函数,让各个RTC驱动注册集成到我们的linux内核中,她实际上是一个粘合剂。
hctosys.c:系统起来之后,会调用到这个文件中的rtc_hctosys()函数,主要功能是系统起来的时候,去读RTC硬件中的时间,然后更新我们的系统时间。
好啦,到这里,相信我们已经对整个rtc驱动各个层都比较清楚了,小时候我语文老师叫我们写作文的时候就喜欢玩“总分”结构,先“总”对整个过程有个大概把握,再“分”起来就容易多了,感觉一切都逃出不我们的“五指山”。
后面的几个小节,开始我们的“分”,从细节去分析理解每个文件。
相关资讯 & & &
& (07/23/:38)
& (05/23/:33)
& (10/09/:05)
& (07/21/:14)
& (01/04/:27)
& (06/23/:19)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款
匿名 发表于 写得详细!非常好!1786人阅读
之前使用开发板时发现每次开机后,系统的时间都恢复到初始状态1969年,因为QT界面要显示采集数据的时间,没办法只能自己去解决这个问题,这两天总算把问题搞定了。一、先说一下时钟的概念,时钟包括硬件时钟和系统时钟,系统时钟就是linux系统显示的时间,用命令date可以显示当前系统时间;硬件时钟就是硬件自身的时间了。它们两者没有关系的,但是可以通过命令设置系统时钟和硬件设置,让它们同步。在linux系统设置系统时钟用命令date,格式为:date .10,表示系统时间设置为日20时50分10秒。硬件时钟RTC时间是通过hwclock命令来设置的,比如说硬件时间要设置为日20时50分10秒,则应该先用date .10,然后用命令:hwclock -w,这样RTC时间就跟系统时间一致了。二、确保RTC在开发板断电后能继续工作。原来的gec2410开发板的底层板电路有问题,RTC无法工作,导致开机时RTC的时间也回到了1969年(用hwclock命令查看硬件时间),后来发现3.3v的电池通过两个电阻跟RTC的VDDRTC(为RTC提供电压的引脚)相连后电压不要1v,而RTC工作电压为1.8v左右,前天去了广嵌,朱工把D8电阻短路掉,D9电阻换成一个发光二级管(压降为1.5v左右),这样开发板断电后就可以用3.3v的电池供电了。三、让系统时间和RTC时间同步。因为每次开机后系统的时间都是系统原来的时间,比如说日1时1分1秒,为了让系统时间和RTC时间同步,可以在文件系统中etc/init.d/rcS添加如下命令:/sbin/hwclock -s,这样每次开机时系统就会读取RTC的时间,系统时间就与RTC时间同步了。(hwclock有时候可能会在/bin目录下面,具体要看busybox编译后放在/bin还是/sbin目录下)
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:35531次
排名:千里之外
原创:28篇
转载:21篇
(4)(5)(2)(3)(2)(8)(8)(17)2792人阅读
linux kernel(111)
电子系统中,时钟是一个关键的要素,尤其在手持设备中,时钟系统的设计与系统的性能和功耗有直接关系。提供了丰富的时钟系统的控制能力,能有效地实现性能和功耗的平衡。
实时时钟RTC
在介绍时钟机制之前,先要说明一下上的时钟系统。上的时钟系统主要包含以下个模块:
n可编程频率核心锁相环;
n固定频率外设锁相环;
n固定频率锁相环。
其中和晶振将与本书讲解的模块有密切联系。
如图所示的晶振可以用来驱动、等模块。但是这个晶振在硬件复位后是被屏蔽的,系统使用晶振作为时钟源。因此需要软件来设置寄存器,使这个晶振工作。
图时钟系统
晶振是系统的主要时钟源,可以用来驱动大部分的模块。在没有晶振的情况下,可以将其分频使用。
一个实时时钟是系统在关闭时也能追踪、记录时间的时钟。它经常以集成电路芯片的形式嵌入在系统中。实时时钟可以用于许多种类的计算机,尤其在嵌入式系统中。
一般情况下,实时时钟是依靠备用电池供电的,并不和外部电源直接相连。因此在断电后,仍然能工作,而相比之下,其他依靠外部电源供电的时钟在系统断电后就无法工作了。希望读者不要把一个计算机的实时时钟与其时钟相混淆。
2.1.1 实时时钟的运行原理
一共提供了以下几个实时时钟控制状态寄存器:
n精确调整寄存器();
n闹钟寄存器();
n计数寄存器();
n状态寄存器()。
为时钟提供了修正的功能;为闹钟寄存器,存放了引发中断的时间限制数;为计数计数器;为状态寄存器,可以用来触发中断。
在硬件复位或者看门狗复位后,计数恢复为,然后在每赫兹时钟的每个下降沿递增。由于赫兹产生的脉冲的高电平区只能维持周期的宽度,而的递增操作发生在赫兹时钟产生上升沿后的周期的时间点上,因此看起来就像是在赫兹时钟下降沿递增的。这个寄存器是读写寄存器,当要把特定的计数值写入这个寄存器时,直接操作即可。计数器不受系统的睡眠或者是空闲状态改变的影响。
除了计数器以外,还提供了闹钟寄存器,可以向中写入特定的值,每当计数器递增后就会和进行比较,如果值相等,则触发中断(如果中断没有被屏蔽的话)。
赫兹时钟是由两个时钟源中任何一个的频率进行特定运算后得到的频率。在的系统中,要求使用的晶振和的晶振。系统中可以同时使用这两个时钟源或者其中一个,如果是使用晶振的话,应当对其进行分频到。
可以通过编程来指定产生赫兹时钟的除法的参数,这同时也提供给开发人员修正时钟误差的机会,关于修正误差,我们将在后续的章节中讨论。
2.1.2 RTC精确调整寄存器(RTTR)
通过设置寄存器,可以调整赫兹时钟的频率。这个寄存器在复位后的值为,如果晶振为非常精确的的话,那么正好将产生的输出。如果设置成其他值,也同样会使赫兹时钟产生其他的频率。如果使用的晶振不是的话,也可以通过这个寄存器的值的改变来弥补。在后面的章节中我们将介绍如何计算赫兹时钟的频率。
向中的一次写入操作将会使自增。在中,有一部分被保留的位,这些位应当被设置成,任何对它们的读操作都将被忽略。只能通过硬件的重启来复位,不像可以通过软件方式来复位。的第位为功能,如果被置位的话,那么本寄存器就变成只读的了,这样可以更好地保护数据。第位只能通过硬件复位来清除。的定义如图与表所示。
表2-1 RTTR定义
调整值的锁存位
值允许被改变
值不允许被改变
调整用的删除计数
这个值代表了时钟被删除的数目
这个值代表了时钟周期数,加等于赫兹时钟周期
2.1.3 RTC闹钟寄存器(RTAR)
闹钟寄存器是一个位的寄存器。处理器可以进行读写操作。
在赫兹时钟的每个上升沿,本寄存器的值都将和的值进行比较,如果它们相等,并且被置位,则被设置成,引发中断。
寄存器在复位后,值为。
的定义如图与表所示。
表2-2 RTAR定义
闹钟触发值
这个值将会和计数器的值比较
2.1.4 RTC Counter Register(RCNR)
是一个读写寄存器,如图所示。理论可以在任何时候对这个寄存器进行操作,但是公司建议开发人员不要随意地在系统运行时随便改动这个值。
的定义如图与表所示。
表2-3 RCNR定义
计数值
当前计数器的值
2.1.5 RTC Status Register(RTSR)
在硬件复位后默认值为。和位为中断控制位,它们都可以触发中断。和位为状态位,它们的值分别和与位相对应。向和中写,可以把和清零。
的定义如图与表所示。
同样,在这个寄存器中也有很多保留位,这些位应当被清零,任何读操作都将被忽略。如果系统处于睡眠状态,那么只有的事件会被得到响应,而的事件则被忽略。
表2-4 RTSR定义
闹钟中断使能
闹钟中断禁止
闹钟中断使能
上升沿监测
没有监测到上升沿
监测到上升沿并且位被置为
没有监测到闹钟
监测到闹钟并且置位
2.1.6 时间的修正
由于晶振的自身误差和分频时产生的误差,使得长时间后时钟的误差急剧加大,因此有必要在运行一段时间后进行修正。
通过提供给开发者一个时钟修正的途径。在理想的情况下,这种修正方式可以使晶振在一个月内的误差控制在±之内。
1.修正过程
赫兹时钟的输出频率是晶振分频的结果,但是晶振自身也有误差,再加上板上各种电容的负面影响,时钟会产生误差。因此需要在特定的时钟周期内进行小规模的修正。精确修正寄存器允许对时钟进行误差在内的修正操作。这样的话,对于频率的赫兹时钟,一个月的误差也就是左右。
当的引脚产生高电平时,就会被回复为,如果是的晶振,正好产生的输出。而当中的分频位()都为时,赫兹时钟将一直输出高电平,这样也就失去了时钟的意义。对于其他数值来说,最终的赫兹时钟输出应当为除以中的分频值再加。
2.晶振频率的修正
在决定向中写入值之前,必须先使用一定时间精确度的基准来衡量晶振频率多用复路器上的频率(一般为),如使用频率计数器。上的脉冲可以通过复用引脚的或者向外输出,然后将实际有效的频率用一个整数来除,并且在特定周期内,丢弃一定量的脉冲,即每隔一段时间使脉冲无效,以补偿前面的误差。
3.RTTR值的计算
在测定晶振的实际频率后,还要确定需要的赫兹时钟的频率。将后者除以前者,这样能得到一个正数的商和小数部分。将整数部分减后的值存入的时钟除数计数位中。这个值将和由晶振多路复用引脚驱动的计数器的值进行比较,如果它们相等,计数器就会复位。
小数部分是为了用来判定在特定周期内舍弃驱动整数计数器的时钟中的部分赫兹时钟时钟周期,从而对赫兹时钟进行修正。修正周期大约是赫兹时钟周期的-倍。如果赫兹时钟的频率被设置成的话,那么修正操作大约每分钟才会进行一次。
至于要舍弃多少个时钟周期,这是由这个位来决定的,因此最多能舍弃-个时钟周期。总之,每隔-个赫兹时钟周期,整数计数器都将停下来一段时间,这段时间内的时钟周期将被舍弃。如果将这个位的值设置成零的话,那么修正将失去功能效果,而也将由原始的驱动。
下面是赫兹时钟的频率值和频率值的计算公式如下:
n赫兹时钟频率
n内部时钟晶振输出
2.1.7 时间计算举例
在这个例子中赫兹时钟的频率被设定为。晶振的输出频率测定为周期秒(),这与系统要求的相比整整多出了个周期,并且这里做除法之后没有小数部分。因此只需要整数的修正而不需要使用小数修正。中应当被写入或者是,而被设置成。
这个例子中的情况更加常见,它将产生小数部分。晶振的输出频率测定为周期秒(),赫兹时钟的频率被设定为,除法的结果是。在中填入或者是。
由于实际的频率比整数计数器快个周期,赫兹时钟的频率比实际要快,因此要设法让它慢下来。这样每秒中要平均舍弃个周期。由于修正周期为-,也就是,因此在内要删除个周期(?)。因此在相应的位置上填写或者。但是可以看到,要完全消除误差也是不可能的。
时钟控制器
提供了一个位的时间计数器,其计数频率来自于时钟。时钟控制器为操作系统提供了一些有用的资源。
2.2.1 OS时钟匹配寄存器0~3(OSMRx)
时钟匹配寄存器~为位可读写寄存器。它们在时钟的每个上升沿后和寄存器进行比较。如果这个寄存器中有任何一个与寄存器的值相符合,而且此时相应的中断使能位没有被关闭的话,则中相应的状态位被置位。在适当的时候,这些状态位将通知中断控制器产生一次中断。寄存器同样可以被用作看门狗记时器。
图显示了的位结构。这个寄存器都有相同的位结构,只是它们的地址有所不同。的定义如表所示。
表2-5 OSMRx定义
定时器匹配值
这个值和定时计数器的值比较
2.2.2 OS时钟中断使能寄存器(OIER)
时钟中断使能寄存器中包含了个位来控制个匹配寄存器,当它们与寄存器值相同时,会决定是否将中的状态位置位。
的定义如图与表所示。
表2-6 OIER定义
中断使能通道和定时器匹配时不会置位和定时器匹配时会置位
中断使能通道和定时器匹配时不会置位和定时器匹配时会置位
中断使能通道和定时器匹配时不会置位和定时器匹配时会置位
中断使能通道和定时器匹配时不会置位和定时器匹配时会置位
2.2.3 OS时钟看门狗使能寄存器(OWER)
寄存器中包含了一个位,它控制这看门狗的功能。这个位可以写入,但是要复位就需要使用复位操作,例如硬件复位、看门狗复位与复位等。
的定义如图与表所示。
表2-7 OWER定义
看门狗匹配使能
匹配将不会引发复位
匹配将会引发复位
2.2.4 OS时钟计数寄存器(OSCR)
寄存器在时钟的上升沿递增。这是一个可读写的寄存器。的手册上建议程序员利用将这个寄存器保护起来。在向这个寄存器写入值后,在寄存器真正被更新前会有一个延迟。
的定义如图与表所示。
表2-8 OSCR的定义
时间计数器的当前值
2.2.5 OS时钟状态寄存器(OSSR)
寄存器包含了状态位,用来标记个匹配寄存器中任何一个和匹配的结果。在时钟上升沿时,如果发生匹配,并且中相应的中断使能位被打开,则状态位被置位。
的定义如图与表所示。
表2-9 OSSR定义
匹配状态通道如果被置位
自上次清零后,还没有和定时器匹配
和定时器匹配
匹配状态通道如果被置位
自上次清零后,还没有和定时器匹配
和定时器匹配
匹配状态通道如果被置位
自上次清零后,还没有和定时器匹配
和定时器匹配
匹配状态通道如果被置位
自上次清零后,还没有和定时器匹配
和定时器匹配
脉宽调制(,)控制电路,通常称为控制电路,是利用半导体功率晶体管或晶闸管等开关器件的导通和关断,把直流电压变成电压脉冲列,控制电压脉冲的宽度或周期以达到变压目的,或者控制电压脉冲宽度和脉冲列的周期以达到变压变频目的的一种变换电路。
在中,主要使用来调节信号的宽度。在开发板中,主要使用信号来为提供亮度或对比度的控制。
、和触摸屏接口如图所示。
图和触摸屏接口
图中为控制信号,用于的背光或者对比度调节。
如果无法提供背光控制信号信号,可以在出厂的时候设置合适亮度,或者客户在接左右的固定电压。
2.3.1 PWM的运行原理
提供了两个:和,它们之间并没有任何依赖或者影响关系。每个也有自己的寄存器组,它们向外部引脚提供了可调节宽度的信号。
每个包含了:
n两个通道;
n通过的时钟分频器和的周期计数器来加强对周期的控制;
n的脉冲控制。
的框图如图所示。
单元使用的晶振提供的频率。每个单元使用到以下个寄存器:
n脉宽控制寄存器();
n占空比控制寄存器();
n周期控制寄存器()。
通过向这个寄存器中填写相应的值,使运行并且输出特定的信号。这些寄存器中包含了单元的计数器和电源管理模式的信息。每个寄存器中都有一些位定义了波形的输出特性。定义了单元的时钟分频值。注意,实际上使用的分频值是实际写入值加。这个被分频的时钟用来驱动位的计数器。
在的每个单元中,各有两个比较器。它们都以位的计数器为基准。第一个比较器将计数器的值和的值进行比较,当它们相等时,信号被设置为高。第二个计数器将计数器的值和相比较。如果它们相等的话,信号被清零。在这两个比较器中,和都是位的宽度。
2.3.2 PWM控制寄存器(PWM_CTRLn)
寄存器包含以下两个域,如图所示。定义如表所示。
n域:域包含了位的分频率值。它将晶振的频率除以(这个域的值-),然后就得到了单元的频率。
n域:可以在两种方式下被关闭,一种是立即关闭,另一种是完成当前周期后关闭,而这个域的值决定了使用哪种方式关闭单元。如果是使用完成当前任务周期的模式,那么将在计数器完成当前计数后关闭单元。如果是选择立即关闭单元,则计数器中未完成的计数被终止。
表2-10 PWM_CTRLn定义
关闭方法:
当中的时钟使能位清零时,逐步削弱直至关闭
当中的时钟使能位清零时,立即关闭
预分频除数,用于设定模块的频率
2.3.3 PWM占空比寄存器(PWM_DUTYn)
由和两个域组成,如图所示。定义如表所示。
位决定了是否有效。如果被设置为,而且也为高电平,则的输出是循环的,将在指定的时间内维持高电平。如果它们都为低电平,则始终为低电平且不被任何信号触发。
表2-11 PWM_DUTYn定义
占空比选择设置
输出占空比由设定
输出恒定为高电平
占空比数值设置
也就是一个周期内为高电平的的时钟个数
2.3.4 PWM Period Control Register(PWM_PERVALn)
(如图2-15和表2-12)
寄存器包含了一个位的域,称为域。这个域按照决定了波形的长度。如果这个域被清零,也就是说波形的长度为,则始终为低,因此也不起任何作用。对于其他非值,的输出频率将是除以的值的结果。
当位的计数器的值和()相等时,计数器被复位,并且、和将被保存到这个寄存器的内部映射中。
如果将这个域清零,则输出将维持在高电平。但是如果且,则输出将保持低电平而无视的值。
表2-12 PWM_PERVALn定义
构成一个周期的周期数目
注意:如果,将被置为高,并不翻转,除非和都为,此时输出恒定为低电平,不受的影响
2.3.5 PWM输出举例
如果有以下设置:
PWM_PERVAL[PV] = 0xA
PWM_DUTY[FDCYCLE] = 0x0
PWM_DUTY[DCYCLE] = 0x6
PWM_CTRL[PRESCALE] = 0x0
则输出的波形将如图所示。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:286846次
积分:3335
积分:3335
排名:第7527名
原创:18篇
转载:257篇
评论:19条
(10)(2)(4)(5)(7)(3)(1)(8)(3)(5)(13)(5)(17)(10)(16)(8)(10)(3)(3)(2)(4)(3)(26)(7)(5)(5)(10)(16)(8)(14)(1)(8)(7)(1)(5)(21)STM32学习笔记(17)-RTC实践
&&&&&& BKP还没有搞完,怎么又换到了RTC上了,因为RTC和BKP有些联系,想不关联还不行呢。
以下是数据手册上有关RTC的介绍:
******介绍开始
15.1&&&& RTC 简介&
&&&&&& 实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
&&&&&& RTC模块和时钟配置系统(RCC_BDCR寄存器)是在后备区域,即在系统复位或从待机模式唤醒后RTC的设置和时间维持不变。
&&&&&& 系统复位后,禁止访问后备寄存器和RTC,防止对后备区域(BKP)的意外写操作。执行以下操作使能对后备寄存器和RTC的访问:
●& 设置寄存器RCC_APB1ENR的PWREN和BKPEN位来使能电源和后备接口时钟
●& 设置寄存器PWR_CR的DBP位使能对后备寄存器和RTC的访问。
******介绍结束
&&&&&& 下面就以库中所带的实例来玩这个RTC,正好也要解决TAMPER引脚的问题。
&&&&&& 这次要用到的例子是这个:
&&&&&& 有关配置没有什么可多说的,把上一个例子:BKP-&Backup_Data中修改过的:
stm32_eval.c
stm3210e_eval.h
stm32_eval.h
三个文件复制过来,建立工程,一路顺风,非常顺利地编译、链接好,然后进入调试,结果,出问题了,见下面:
&&&&&& 进入调试界面即停在了反汇编界面。一旦执行程序,立即就停下来。这个BKPT指令是个什么东西呢?查了一下指令表,原来是个断点指令,那为什么会停止在这里呢?万能的网啊,一搜就出来了,感谢前人的努力,感谢伟大的网...。
&&&&&结论是:& 凡是用到printf的都会出现这样的问题。&
&&&&&& 解决方法:
打开Options for Target项,把那个Use MicroLIB前面打上勾,重新编译链接即可。
&&&&&&出现问题的原因,网上的相关解释是:这是Printf库函数的问题,需要使用MicroLIB这个库来替代默认的库。原因是默认printf并非使用串口,所以要改掉。
&&&&&& 在main.c中有这样一段函数:
& * @brief& Retargets the C library printf function to the USART.
& * @param& None
& * @retval None
PUTCHAR_PROTOTYPE
& /* Place your implementation of fputc here */
& /* e.g. write a character to the USART */
& USART_SendData(EVAL_COM1, (uint8_t) ch);
&& /* Loop until the end of transmission */
& while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)
&&&&&& 根据这段函数的说明,就是做这个事情的。
&&&&& 但是还有一些疑问:
&&&&& (1)这个例子的readme.txt中并没有说明要用MicroLIB这个库的事情。
&&&&&& (2)如果不用硬件,而是用软件仿真,也是不需要使用MicroLIB库的。
&&&&&& 因此,有关MicroLIB的问题还不是特别明确,还需要进一步研究。是否是这段程序还用到了scanf的原因?
例子的运行
&&&&&& 如果是第一次运行,那么会出现如下画面:
即其中有提示RTC没有初始化,要求进行设置的提示,根据提示分别送入小时,分钟,秒的数值,即完成设置工作,程序不断地将当前时间通过串口送出。
如果在VBAT端接入后备电池,那么断电后再上电显示的信息如下:
其中提示RTC已初始化,不需要再进行初始化,直接将时间不断地从串口送出。
& * @brief& Configures the RTC.
& * @param& None
& * @retval None
void RTC_Configuration(void)
& /* 开启PWR和BKP模块的时钟 */
& RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
&& /* 允许对BKP进行存取操作*/
& PWR_BackupAccessCmd(ENABLE);
&& /* 初始化BKP区域*/
& BKP_DeInit();
&& /* LSE允许,这里LSE是指外部接的32768HZ 晶振的一个振荡器,它使用PC14和PC15两条引脚。有关这部分的一些细节描述如下:
当备份区域由V DD (内部模拟开关连到V DD )供电时,下述功能可用:
●& PC14和PC15可以用于GPIO或LSE引脚
●& PC13可以作为通用I/O口、TAMPER引脚、RTC校准时钟、RTC闹钟或秒输出
当后备区域由VBAT供电时(VDD消失后模拟开关连到VBAT),可以使用下述功能:
●& PC14和PC15只能用于LSE引脚
●& PC13可以作为TAMPER引脚、RTC闹钟或秒输出
& RCC_LSEConfig(RCC_LSE_ON);
& /* 等待LSE振荡器就绪 */
& while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
&& /* 选择LSE作为RTC的时钟源
&&&&&& 说明:RTC时钟源可以是以下三种之一:
─&&& HSE 时钟除以 128
─&&& LSE 振荡器时钟
─&&& LSI振荡器时钟
其中LSI是一个内部的低频RC振荡器。关于RTC的这三个时钟各有何特点,见下面的说明。
& RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
&& /* RTC时钟允许*/
& RCC_RTCCLKCmd(ENABLE);
&& /* 等待RTC寄存器同步
理由如下:
15.3.3& 读 RTC 寄存器&
RTC核完全独立于RTC APB1接口。
软件通过APB1接口访问RTC的预分频值、计数器值和闹钟值。但是,相关的可读寄存器只在与RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。RTC标志也是如此的。
这意味着,如果APB1接口刚刚被开启之后,在第一次的内部寄存器更新之前,从APB1上读出RTC寄存器的第一个值可能被破坏了(通常读到0)。下述几种情况下能够发生这种情形:
●& 发生系统复位或电源复位
●& 系统刚从待机模式唤醒(参见4.3节)。
●& 系统刚从停机模式唤醒(参见4.3节)。
所有以上情况中,APB1接口被禁止时(复位、无时钟或断电)RTC核仍保持运行状态。 因此,若在读取RTC寄存器曾经被禁止的RTC& APB1接口,软件首先须等待RTC_CRL寄存器中
的RSF位(寄存器同步标志)被硬件置1。
void RTC_WaitForSynchro(void)
& /* Clear RSF flag */
& RTC-&CRL &= (uint16_t)~RTC_FLAG_RSF;
& /* Loop until RSF flag is set */
& while ((RTC-&CRL & RTC_FLAG_RSF) == (uint16_t)RESET)
& RTC_WaitForSynchro();
&& /* 等待最后写操作完成*/
& RTC_WaitForLastTask();
&& /* 允许秒中断,相应代码如下:
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState)
& /* Check the parameters */
& assert_param(IS_RTC_IT(RTC_IT));&
& assert_param(IS_FUNCTIONAL_STATE(NewState));
&&& if (NewState != DISABLE)
&& &RTC-&CRH |= RTC_IT;
&&& RTC-&CRH &= (uint16_t)~RTC_IT;
而调用这段程序的代码中的第一个参数是:
#define RTC_IT_SEC&&&&&&&&&& ((uint16_t)0x0001)& /*!& Second interrupt */
可见它是对RTC-&CRH的最低位进行操作,CRH相关内容见下面的图。
& RTC_ITConfig(RTC_IT_SEC, ENABLE);
&& /* 等待最后的写操作完成*/
& RTC_WaitForLastTask();
&& /* 设置RTC预分频器: set RTC period to 1sec */
& RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
&& /* 等待最后的写操作完成*/
& RTC_WaitForLastTask();
&&& 下面的图是有关RTC时钟选择的问题,其中说明了各种时钟的工作特性:
&&&&&& 下面的图是有关RTC_CRH寄存器的描述,放在这里是为了说明SECIE标志位。
关注微信公众号

我要回帖

更多关于 iphone硬件检测软件 的文章

 

随机推荐