电子系统中,时钟是一个关键的要素,尤其在手持设备中,时钟系统的设计与系统的性能和功耗有直接关系。PXA255提供了丰富的时钟系统的控制能力,能有效地实现性能和功耗的平衡。
2.1 实时时钟RTC
在介绍时钟机制之前,先要说明一下PXA255上的时钟系统。PXA255上的时钟系统主要包含以下5个模块:
n32.768kHz振荡器;
n3.6864MHz振荡器;
n可编程频率核心锁相环PLL;
n95.85MHz固定频率外设锁相环PLL;
n147.46MHz固定频率锁相环PLL。
其中32.768kHz和3.6864MHz晶振将与本书讲解的模块有密切联系。
如图2-1所示的32.768kHz晶振可以用来驱动RTC、PWM等模块。但是这个晶振在硬件复位后是被屏蔽的,系统使用3.6864MHz晶振作为时钟源。因此需要软件来设置寄存器,使这个晶振工作。
图2‑1 PXA255时钟系统
3.6864MHz晶振是系统的主要时钟源,可以用来驱动大部分的模块。在没有32.768kHz晶振的情况下,可以将其分频使用。
一个实时时钟是系统在关闭时也能追踪、记录时间的时钟。它经常以集成电路芯片的形式嵌入在系统中。实时时钟可以用于许多种类的计算机,尤其在嵌入式系统中。
一般情况下,实时时钟是依靠备用电池供电的,并不和外部电源直接相连。因此在断电后,仍然能工作,而相比之下,其他依靠外部电源供电的时钟在系统断电后就无法工作了。希望读者不要把一个计算机的实时时钟与其CPU时钟相混淆。
2.1.1 实时时钟的运行原理
PXA255一共提供了以下几个实时时钟控制/状态寄存器:
nRTC精确调整寄存器(RTTR);
nRTC闹钟寄存器(RTAR);
nRTC计数寄存器(RCNR);
nRTC状态寄存器(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。
可以通过编程来指定产生赫兹时钟的除法的参数,这同时也提供给开发人员修正时钟误差的机会,关于修正误差,我们将在后续的章节中讨论。
2.1.2 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所示。
图2-2 RTTR
表2-1 RTTR定义
位 号 | 名 称 | 描 述 |
<31> | LCK | 调整值的锁存位 |
<30:26> | - | 保留 |
<25:16> | DEL | 调整用的删除计数 |
<15:0> | CK_DIV | 时钟除数 |
2.1.3 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闹钟触发值 |
2.1.4 RTC Counter Register(RCNR)
RCNR是一个读/写寄存器,如图2-4所示。理论可以在任何时候对这个寄存器进行操作,但是Intel公司建议开发人员不要随意地在系统运行时随便改动这个值。
RCNR的定义如图2-4与表2-3所示。
图2-4 RCNR
表2-3 RCNR定义
位 号 | 名 称 | 描 述 |
<31:0> | RCV | RTC计数值 |
2.1.5 RTC Status Register(RTSR)
RTSR在硬件复位后默认值为0。ALE和HZE位为中断控制位,它们都可以触发中断。AL和HZ位为状态位,它们的值分别和ALE与HZE位相对应。向AL和HZ中写1,可以把ALE和HZE清零。
RTSR的定义如图2-5与表2-4所示。
同样,在这个寄存器中也有很多保留位,这些位应当被清零,任何读操作都将被忽略。如果系统处于睡眠状态,那么只有AL的事件会被得到响应,而HZ的事件则被忽略。
图2‑5 RTSR
表2-4 RTSR定义
位 号 | 名 称 | 描 述 |
<31:4> | - | 保留 |
<3> | HZE | HZ中断使能 |
续表
位 号 | 名 称 | 描 述 |
<2> | ALE | RTC闹钟中断使能 |
<1> | HZ | HZ上升沿监测 |
<0> | AL | RTC闹钟监测 |
2.1.6 时间的修正
由于晶振的自身误差和分频时产生的误差,使得长时间后时钟的误差急剧加大,因此有必要在运行一段时间后进行修正。
通过RTC Trim Register提供给开发者一个时钟修正的途径。在理想的情况下,这种修正方式可以使32kHz晶振在一个月内的误差控制在±5s之内。
1.修正过程
赫兹时钟的输出频率是晶振分频的结果,但是晶振自身也有误差,再加上板上各种电容的负面影响,时钟会产生误差。因此需要在特定的时钟周期内进行小规模的修正。RTC精确修正寄存器允许对时钟进行误差在1ppm内的修正操作。这样的话,对于1Hz频率的赫兹时钟,一个月的误差也就是5s左右。
当PXA255的nRESET引脚产生高电平时,RTTR就会被回复为0x0000_7FFF,如果是32kHz的晶振,正好产生1Hz的输出。而当RTTR中的分频位(RTTR[15:0])都为0时,赫兹时钟将一直输出高电平,这样也就失去了时钟的意义。对于其他数值来说,最终的赫兹时钟输出应当为32kHz除以RTTR中的分频值再加1。
2.晶振频率的修正
在决定向RTTR中写入值之前,必须先使用一定时间精确度的基准来衡量晶振频率多用复路器上的频率(一般为32kHz),如使用频率计数器。PXA255上RTC的脉冲可以通过复用引脚的GPIO[12]或者GPIO[72]向外输出,然后将实际有效的频率用一个整数来除,并且在特定周期内,丢弃一定量的脉冲,即每隔一段时间使脉冲无效,以补偿前面的误差。
3.RTTR值的计算
在测定晶振的实际频率后,还要确定需要的赫兹时钟的频率。将后者除以前者,这样能得到一个正数的商和小数部分。将整数部分减1后的值存入RTTR的时钟除数计数位中。这个值将和由晶振多路复用引脚驱动的计数器的值进行比较,如果它们相等,计数器就会复位。
小数部分是为了用来判定在特定周期内舍弃驱动整数计数器的时钟中的部分赫兹时钟时钟周期,从而对赫兹时钟进行修正。修正周期大约是赫兹时钟周期的210-1倍。如果赫兹时钟的频率被设置成1Hz的话,那么修正操作大约每17分钟才会进行一次。
至于要舍弃多少个时钟周期,这是由RTTR[25:16]这10个位来决定的,因此最多能舍弃210-1个时钟周期。总之,每隔210-1个赫兹时钟周期,整数计数器都将停下来一段时间,这段时间内的时钟周期将被舍弃。如果将这10个位的值设置成零的话,那么修正将失去功能效果,而RTC也将由原始的32kHz clock驱动。
下面是赫兹时钟的频率值和32kHz clock频率值的计算公式如下:
nf1=赫兹时钟频率
nf32k=RTC内部时钟–晶振输出
nRTTR[DEL]=RTTR(25:16)
nRTTR[CK_DIV]=RTTR(15:0)
2.1.7 时间计算举例
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时钟控制器为操作系统提供了一些有用的资源。
2.2.1 OS时钟匹配寄存器0~3(OSMRx)
OS时钟匹配寄存器0~3为32位可读/写寄存器。它们在3.6864MHz时钟的每个上升沿后和OSCR寄存器进行比较。如果这4个寄存器中有任何一个与OSCR寄存器的值相符合,而且此时相应的中断使能位没有被关闭的话,则OSSR中相应的状态位被置位。在适当的时候,这些状态位将通知中断控制器产生一次CPU中断。OSMR3寄存器同样可以被用作看门狗记时器。
图2-6显示了OSMRx的位结构。这4个寄存器都有相同的位结构,只是它们的地址有所不同。OSMRx的定义如表2-5所示。
图2-6 OSMRx
表2-5 OSMRx定义
位 号 | 名 称 | 描 述 |
<31:0> | OSMV | OS定时器匹配值 |
2.2.2 OS时钟中断使能寄存器(OIER)
OS时钟中断使能寄存器中包含了4个位来控制4个匹配寄存器,当它们与OSCR寄存器值相同时,会决定是否将OSSR中的状态位置位。
OIER的定义如图2-7与表2-6所示。
图2-7 OIER
表2-6 OIER定义
位 号 | 名 称 | 描 述 |
<31:4> | - | 保留 |
<3> | E3 | 中断使能通道3 |
续表
位 号 | 名 称 | 描 述 |
<2> | E2 | 中断使能通道2 |
<1> | E1 | 中断使能通道1 |
<0> | E0 | 中断使能通道0 |
2.2.3 OS时钟看门狗使能寄存器(OWER)
OWER寄存器中包含了一个位0,它控制这看门狗的功能。这个位可以写入,但是要复位就需要使用复位操作,例如硬件复位、看门狗复位与GPIO复位等。
OWER的定义如图2-8与表2-7所示。
图2-8 OWER
表2-7 OWER定义
位 号 | 名 称 | 描 述 |
<31:1> | - | 保留 |
<0> | WME | 看门狗匹配使能 |
2.2.4 OS时钟计数寄存器(OSCR)
OSCR寄存器在3.6864MHz时钟的上升沿递增。这是一个可读/写的寄存器。PXA的手册上建议程序员利用MMU将这个寄存器保护起来。在向这个寄存器写入值后,在寄存器真正被更新前会有一个延迟。
OSCR的定义如图2-9与表2-8所示。
表2-8 OSCR的定义
位 号 | 名 称 | 描 述 |
<31:0> | OSCV | OS时间计数器的当前值 |
图2-9 OSCR
2.2.5 OS时钟状态寄存器(OSSR)
OSSR寄存器包含了状态位,用来标记4个匹配寄存器中任何一个和OSCR匹配的结果。在3.6864MHz时钟上升沿时,如果发生匹配,并且OIER中相应的中断使能位被打开,则状态位被置位。
OSSR的定义如图2-10与表2-9所示。
图2-10 OSSR
表2-9 OSSR定义
位 号 | 名 称 | 描 述 |
<31:4> | - | 保留 |
<3> | M3 | 匹配状态通道3 |
<2> | M2 | 匹配状态通道2 |
<1> | M1 | 匹配状态通道1 |
<0> | M0 | 匹配状态通道0 |
2.3 PWM输出
脉宽调制(Pulse Width Modulation,PWM)控制电路,通常称为PWM控制电路,是利用半导体功率晶体管或晶闸管等开关器件的导通和关断,把直流电压变成电压脉冲列,控制电压脉冲的宽度或周期以达到变压目的,或者控制电压脉冲宽度和脉冲列的周期以达到变压变频目的的一种变换电路。
在PXA255中,主要使用PWM来调节PWM信号的宽度。在kaola开发板中,主要使用PWM信号来为LCD提供亮度或对比度的控制。
J15、LCD和触摸屏接口如图2-11所示。
图2‑11 LCD和触摸屏接口
图中SA_PWM_0为LCD PWM控制信号,用于LCD的背光或者对比度调节。
如果无法提供背光控制信号PWM信号,可以在出厂的时候设置合适亮度,或者客户在LCD_PWM接3V左右的固定电压。
2.3.1 PWM的运行原理
PXA255提供了两个PWM:PWM0和PWM1,它们之间并没有任何依赖或者影响关系。每个PWM也有自己的寄存器组,它们向外部引脚提供了可调节宽度的PWM信号。
每个PWM包含了:
n两个PWM通道;
n通过6bit的时钟分频器和10bit的周期计数器来加强对周期的控制;
n10bit的脉冲控制。
PWM的框图如图2-12所示。
PWM单元使用3.6864MHz的晶振提供的频率。每个PWM单元使用到以下3个寄存器:
n脉宽控制寄存器(PWM_CTRL);
n占空比控制寄存器(PWM_DUTY);
n周期控制寄存器(PWM_PERVAL)。
通过向这3个寄存器中填写相应的值,使PWM运行并且输出特定的PWM信号。这些寄存器中包含了PWM单元的计数器和电源管理模式的信息。每个寄存器中都有一些位定义了PWM_OUTn波形的输出特性。PWM_CTRLn[PRESCALE]定义了PWM单元的时钟分频值。注意,实际上使用的分频值是实际写入值加1。这个被分频的时钟用来驱动10位的计数器。
图2‑12 PWM框图
在PXA255的每个PWM单元中,各有两个比较器。它们都以10位的计数器为基准。第一个比较器将计数器的值和PWM_DUTYn[DCYCLE]的值进行比较,当它们相等时,PWM_OUT信号被设置为高。第二个计数器将计数器的值和PWM_PERVALn[PV]-1相比较。如果它们相等的话,PWM_OUT信号被清零。在这两个比较器中,PWM_PERVALn[PV]和PWM_DUTYn[DCYCLE]都是10位的宽度。
2.3.2 PWM控制寄存器(PWM_CTRLn)
PWM_CTRLn寄存器包含以下两个域,如图2-13所示。定义如表2-10所示。
图2‑13 PWM_CTRLn
nRESCALE域:PRESCALE域包含了6位的分频率值。它将晶振的频率除以(这个域的值-1),然后就得到了PWM单元的频率。
nPWM_SD域:PWMn可以在两种方式下被关闭,一种是立即关闭,另一种是完成当前周期后关闭,而这个域的值决定了使用哪种方式关闭PWM单元。如果是使用完成当前任务周期的模式,那么将在计数器完成当前计数后关闭PWM单元。如果是选择立即关闭PWM单元,则计数器中未完成的计数被终止。
表2-10 PWM_CTRLn定义
位 号 | 名 称 | 描 述 |
<31:7> | - | 保留 |
<6> | PMW_SD | PWMn关闭方法: |
<5:0> | PRESCALE | PWMn预分频除数,用于设定PWM模块的频率 |
2.3.3 PWM占空比寄存器(PWM_DUTYn)
PWM_DUTY由FDCYCLE和DCYCLE两个域组成,如图2-14所示。定义如表2-11所示。
FDCYCLE位决定了PWM_OUTn是否有效。如果FDCYCLE被设置为0,而且DCYCLE也为高电平,则PWM_OUTn的输出是循环的,PWM_OUTn将在DCYCLE指定的时间内维持高电平。如果它们都为低电平,则PWM_OUTn始终为低电平且不被任何信号触发。
图2‑14 PWM_DUTYn
表2-11 PWM_DUTYn定义
位 号 | 名 称 | 描 述 |
<31:11> | - | 保留 |
<10> | FDCYCLE | PWMn占空比选择设置 |
<9:0> | DCYCLE | PWMn占空比数值设置 |
2.3.4 PWM Period Control Register(PWM_PERVALn) (如图2-15和表2-12)
PWM_PERVALn寄存器包含了一个10位的域,称为PV域。这个域按照PSCLK_PWMn决定了PWM_OUTn波形的长度。如果这个域被清零,也就是说波形的长度为0,则PWM_OUTn始终为低,因此也不起任何作用。对于其他非0值,PWMn的输出频率将是PSCLK_OUTn除以PV的值的结果。
当10位的计数器的值和(PV+1)相等时,计数器被复位,并且PWM_CTRLn、PWM_PERVALn和PWM_DUTYn将被保存到这3个寄存器的内部映射中。
如果将这个域清零,则输出将3维持在高电平。但是如果FDCYCLE=0x0且DCYCLE=0x0,则输出将保持低电平而无视PV的值。
图2-15 PWM_PERVALn
表2-12 PWM_PERVALn定义
位 号 | 名 称 | 描 述 |
<31:10> | - | 保留 |
<9:0> | PV | PWMn周期控制 |
2.3.5 PWM输出举例
如果有以下设置:
PWM_PERVAL[PV] = 0xA
PWM_DUTY[FDCYCLE] = 0x0
PWM_DUTY[DCYCLE] = 0x6
PWM_CTRL[PRESCALE] = 0x0
则输出的波形将如图2-16所示。
图2‑16 PWM输出