《Windows CE嵌入式开发入门——基于Xscale架构》第2章 系统时钟

电子系统中,时钟是一个关键的要素,尤其在手持设备中,时钟系统的设计与系统的性能和功耗有直接关系。PXA255提供了丰富的时钟系统的控制能力,能有效地实现性能和功耗的平衡。

2.1 实时时钟RTC

在介绍时钟机制之前,先要说明一下PXA255上的时钟系统。PXA255上的时钟系统主要包含以下5个模块:

n 32.768kHz振荡器;

n 3.6864MHz振荡器;

n 可编程频率核心锁相环PLL

n 95.85MHz固定频率外设锁相环PLL

n 147.46MHz固定频率锁相环PLL

其中32.768kHz3.6864MHz晶振将与本书讲解的模块有密切联系。

如图2-1所示的32.768kHz晶振可以用来驱动RTCPWM等模块。但是这个晶振在硬件复位后是被屏蔽的,系统使用3.6864MHz晶振作为时钟源。因此需要软件来设置寄存器,使这个晶振工作。

<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype>《Windows CE嵌入式开发入门——基于Xscale架构》第2章 系统时钟

2‑1 PXA255时钟系统

3.6864MHz晶振是系统的主要时钟源,可以用来驱动大部分的模块。在没有32.768kHz晶振的情况下,可以将其分频使用。

一个实时时钟是系统在关闭时也能追踪、记录时间的时钟。它经常以集成电路芯片的形式嵌入在系统中。实时时钟可以用于许多种类的计算机,尤其在嵌入式系统中。

一般情况下,实时时钟是依靠备用电池供电的,并不和外部电源直接相连。因此在断电后,仍然能工作,而相比之下,其他依靠外部电源供电的时钟在系统断电后就无法工作了。希望读者不要把一个计算机的实时时钟与其CPU时钟相混淆。

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on"><span lang="EN-US">2.1.1</span></chsdate> 实时时钟的运行原理

PXA255一共提供了以下几个实时时钟控制/状态寄存器:

n RTC精确调整寄存器(RTTR);

n RTC闹钟寄存器(RTAR);

n RTC计数寄存器(RCNR);

n RTC状态寄存器(RTSR)。

RTTR为时钟提供了修正的功能;RTAR为闹钟寄存器,存放了引发中断的时间限制数;RCNR为计数计数器;RTSR为状态寄存器,可以用来触发中断。

在硬件复位或者看门狗复位后,RCNR计数恢复为0,然后在每赫兹时钟的每个下降沿递增1。由于1赫兹产生的脉冲的高电平区只能维持32kHz周期的宽度,而RCNR的递增操作发生在赫兹时钟产生上升沿后的32kHz周期的时间点上,因此看起来就像是在赫兹时钟下降沿递增的。这个寄存器是读/写寄存器,当要把特定的计数值写入这个寄存器时,直接操作即可。RTSR计数器不受系统的睡眠或者是空闲状态改变的影响。

除了计数器以外,PXA255还提供了闹钟寄存器RTAR,可以向RTAR中写入特定的值,每当RCNR计数器递增后就会和RTAR进行比较,如果值相等,则触发中断RTSR[AL](如果中断没有被屏蔽的话)。

赫兹时钟是由两个时钟源中任何一个的频率进行特定运算后得到的频率。在PX255的系统中,要求使用3.6864MHz的晶振和32.768kHz的晶振。系统中可以同时使用这两个时钟源或者其中一个,如果是使用3.6864MHz晶振的话,应当对其进行分频到32.914kHz

可以通过编程来指定产生赫兹时钟的除法的参数,这同时也提供给开发人员修正时钟误差的机会,关于修正误差,我们将在后续的章节中讨论。

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on"><span lang="EN-US">2.1.2</span></chsdate> RTC精确调整寄存器(RTTR

通过设置RTTR寄存器,可以调整赫兹时钟的频率。这个寄存器在复位后的值为0x0000_7FFF,如果晶振为非常精确的32.768kHz的话,那么正好将产生1Hz的输出。如果设置成其他值,也同样会使赫兹时钟产生其他的频率。如果使用的晶振不是32.768kHz的话,也可以通过这个寄存器的值的改变来弥补。在后面的章节中我们将介绍如何计算赫兹时钟的频率。

RTTC中的一次写入操作将会使RCNR自增。在RTTR中,有一部分被保留的位,这些位应当被设置成0,任何对它们的读操作都将被忽略。RTTR只能通过硬件的重启来复位,不像RCNR可以通过软件方式来复位。RTTR的第32位为Lock功能,如果被置位的话,那么本寄存器就变成只读的了,这样可以更好地保护数据。第32位只能通过硬件复位来清除。RTTR的定义如图2-2与表2-1所示。

《Windows CE嵌入式开发入门——基于Xscale架构》第2章 系统时钟

2-2 RTTR

2-1 RTTR定义

<31>

LCK

调整值的锁存位
0-RTTR
值允许被改变
1-RTTR
值不允许被改变

<30:26>

-

保留

<25:16>

<state w:st="on"><place w:st="on"><span lang="EN-US"><font face="Times New Roman">DEL</font></span></place></state>

调整用的删除计数
这个值代表了32MHz时钟被删除的数目

<15:0>

CK_DIV

时钟除数
这个值代表了32MHz时钟周期数,加1等于赫兹时钟周期

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on"><span lang="EN-US">2.1.3</span></chsdate> RTC闹钟寄存器(RTAR

RTAR闹钟寄存器是一个32位的寄存器。处理器可以进行读/写操作。

在赫兹时钟的每个上升沿,本寄存器的值都将和RCNR的值进行比较,如果它们相等,并且RTSR[ALE]被置位,则RTSR[AL]被设置成1,引发中断。

RTAR寄存器在复位后,值为0x0

RTAR的定义如图2-3与表2-2所示。

2‑3 RTAR

2-2 RTAR定义

<31:0>

RTMV

RTC闹钟触发值
这个值将会和RTC计数器的值比较

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on"><span lang="EN-US">2.1.4</span></chsdate> RTC Counter RegisterRCNR

RCNR是一个读/写寄存器,如图2-4所示。理论可以在任何时候对这个寄存器进行操作,但是Intel公司建议开发人员不要随意地在系统运行时随便改动这个值。

RCNR的定义如图2-4与表2-3所示。

2-4 RCNR

2-3 RCNR定义

<31:0>

RCV

RTC计数值
当前RTC计数器的值

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on"><span lang="EN-US">2.1.5</span></chsdate> RTC Status RegisterRTSR

RTSR在硬件复位后默认值为0ALEHZE位为中断控制位,它们都可以触发中断。ALHZ位为状态位,它们的值分别和ALEHZE位相对应。向ALHZ中写1,可以把ALEHZE清零。

RTSR的定义如图2-5与表2-4所示。

同样,在这个寄存器中也有很多保留位,这些位应当被清零,任何读操作都将被忽略。如果系统处于睡眠状态,那么只有AL的事件会被得到响应,而HZ的事件则被忽略。

2‑5 RTSR

2-4 RTSR定义

<31:4>

-

保留

<3>

HZE

HZ中断使能
0-HZ
中断禁止
1-HZ
中断使能

续表

<2>

ALE

RTC闹钟中断使能
0-RTC
闹钟中断禁止
1-RTC
闹钟中断使能

<1>

HZ

HZ上升沿监测
0-
没有监测到上升沿
1-
监测到上升沿并且HZE位被置为1

<0>

<state w:st="on"><place w:st="on"><span lang="EN-US"><font face="Times New Roman">AL</font></span></place></state>

RTC闹钟监测
0-
没有监测到RTC闹钟
1-
监测到RTC闹钟并且置位ALE

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on"><span lang="EN-US">2.1.6</span></chsdate> 时间的修正

由于晶振的自身误差和分频时产生的误差,使得长时间后时钟的误差急剧加大,因此有必要在运行一段时间后进行修正。

通过RTC Trim Register提供给开发者一个时钟修正的途径。在理想的情况下,这种修正方式可以使32kHz晶振在一个月内的误差控制在±5s之内。

1.修正过程

赫兹时钟的输出频率是晶振分频的结果,但是晶振自身也有误差,再加上板上各种电容的负面影响,时钟会产生误差。因此需要在特定的时钟周期内进行小规模的修正。RTC精确修正寄存器允许对时钟进行误差在1ppm内的修正操作。这样的话,对于1Hz频率的赫兹时钟,一个月的误差也就是5s左右。

PXA255nRESET引脚产生高电平时,RTTR就会被回复为0x0000_7FFF,如果是32kHz的晶振,正好产生1Hz的输出。而当RTTR中的分频位(RTTR[15:0])都为0时,赫兹时钟将一直输出高电平,这样也就失去了时钟的意义。对于其他数值来说,最终的赫兹时钟输出应当为32kHz除以RTTR中的分频值再加1

2.晶振频率的修正

在决定向RTTR中写入值之前,必须先使用一定时间精确度的基准来衡量晶振频率多用复路器上的频率(一般为32kHz),如使用频率计数器。PXA255RTC的脉冲可以通过复用引脚的GPIO[12]或者GPIO[72]向外输出,然后将实际有效的频率用一个整数来除,并且在特定周期内,丢弃一定量的脉冲,即每隔一段时间使脉冲无效,以补偿前面的误差。

3RTTR值的计算

在测定晶振的实际频率后,还要确定需要的赫兹时钟的频率。将后者除以前者,这样能得到一个正数的商和小数部分。将整数部分减1后的值存入RTTR的时钟除数计数位中。这个值将和由晶振多路复用引脚驱动的计数器的值进行比较,如果它们相等,计数器就会复位。

小数部分是为了用来判定在特定周期内舍弃驱动整数计数器的时钟中的部分赫兹时钟时钟周期,从而对赫兹时钟进行修正。修正周期大约是赫兹时钟周期的210-1倍。如果赫兹时钟的频率被设置成1Hz的话,那么修正操作大约每17分钟才会进行一次。

至于要舍弃多少个时钟周期,这是由RTTR[25:16]10个位来决定的,因此最多能舍弃210-1个时钟周期。总之,每隔210-1个赫兹时钟周期,整数计数器都将停下来一段时间,这段时间内的时钟周期将被舍弃。如果将这10个位的值设置成零的话,那么修正将失去功能效果,而RTC也将由原始的32kHz clock驱动。

下面是赫兹时钟的频率值和32kHz clock频率值的计算公式如下:

<shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe"><stroke joinstyle="miter"></stroke><path gradientshapeok="t" o:connecttype="rect"></path></shapetype><shape id="_x0000_s1027" style="margin-top: 18.6pt; z-index: 2; left: 0px; margin-left: 192.25pt; width: 11pt; position: absolute; height: 16pt; text-align: left; mso-wrap-edited: f" filled="f" stroked="f" wrapcoords="0 0 21600 0 21600 21600 0 21600 0 0" type="#_x0000_t202"><textbox inset="0,0,0,0"></textbox></shape><shape id="_x0000_s1026" style="margin-top: 2.9pt; z-index: 1; left: 0px; margin-left: 160.5pt; width: 11pt; position: absolute; height: 16pt; text-align: left; mso-wrap-edited: f" filled="f" stroked="f" wrapcoords="0 0 21600 0 21600 21600 0 21600 0 0" type="#_x0000_t202"><textbox inset="0,0,0,0"></textbox></shape>

n f1=赫兹时钟频率


n
f32k=RTC内部时钟晶振输出

n RTTR[DEL]=RTTR25:16

n RTTR[CK_DIV]=RTTR15:0­

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on"><span lang="EN-US">2.1.7</span></chsdate> 时间计算举例

1.举例一

在这个例子中赫兹时钟的频率被设定为1Hz。晶振的输出频率测定为36 045.000周期/秒(Hz),这与系统要求的32.768kHz相比整整多出了3277个周期,并且这里做除法之后没有小数部分。因此只需要整数的修正而不需要使用小数修正。RTTR[15:0]中应当被写入36045-1或者是0x0000_8CCC,而RTTR[25:16]被设置成0

2.举例二

这个例子中的情况更加常见,它将产生小数部分。晶振的输出频率测定为32 768.92周期/秒(Hz),赫兹时钟的频率被设定为1Hz,除法的结果是32 768.92。在RTTR[15:0]中填入32768-1或者是0x0000_7FFF

由于实际的频率比整数计数器快0.92个周期,赫兹时钟的频率比实际要快,因此要设法让它慢下来。这样每秒中要平均舍弃0.92个周期。由于修正周期为210-1s,也就是1023s,因此在1023s内要删除941.16个周期(0.92´1023=941.16)。因此在相应的位置上填写0x3AD或者941。但是可以看到,要完全消除误差也是不可能的。

2.2 OS时钟控制器

PXA255提供了一个32位的时间计数器,其计数频率来自于3.6864MHz时钟。OS时钟控制器为操作系统提供了一些有用的资源。

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on"><span lang="EN-US">2.2.1</span></chsdate> OS时钟匹配寄存器03OSMRx

OS时钟匹配寄存器0332位可读/写寄存器。它们在3.6864MHz时钟的每个上升沿后和OSCR寄存器进行比较。如果这4个寄存器中有任何一个与OSCR寄存器的值相符合,而且此时相应的中断使能位没有被关闭的话,则OSSR中相应的状态位被置位。在适当的时候,这些状态位将通知中断控制器产生一次CPU中断。OSMR3寄存器同样可以被用作看门狗记时器。

2-6显示了OSMRx的位结构。这4个寄存器都有相同的位结构,只是它们的地址有所不同。OSMRx的定义如表2-5所示。

《Windows CE嵌入式开发入门——基于Xscale架构》第2章 系统时钟

2-6 OSMRx

2-5 OSMRx定义

<31:0>

border-right: gray 1pt solid; padding-right: 5.4pt; border-top: #e0dfe3; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #e0dfe3; width: 54pt; padding-top: 0cm; b
分享到:
评论
yesjavame
  • 浏览: 154533 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

你可能感兴趣的:(编程,windows,F#,OS,嵌入式)