【原创】MC9S08MG64实时时钟的校准和补偿
0赞MC9S08MG64是飞思卡尔开云棋牌官网在线客服针对国网单相电表推出的一款半SoC芯片,它集成了片上液晶驱动器和实时时钟模块,以及多种通讯接口。用于智能电表设计时,配合外部电能计量芯片,即可完成性价比良好的单相电表设计。此单片机内部集成的实时时钟模块(iRTC) 具有时间保持和日历功能。对由晶体本身的频偏及温度漂移引起的误差,可以利用实时时钟本身的补偿功能进行修正。本文讨论如何对实时时钟进行校准和补偿,以达到国网要求的标准(误差小于5ppm)。
晶体的特性
1.1 负载电容的影响
一般说来晶体的振荡频率是很稳定的,但我们也知道晶体的振荡频率受负载电容和温度变化的影响。如下图所示的例子为一个负载电容为12.5pF的晶体,当负载电容变化时其振荡频率偏差的随动特性
振荡电路匹配电容的离散性和温度漂移,电路板的分布电容都会对振荡频率造成影响。对于MC9S08MG64,使用32.768kHz晶体时其振荡器可以有两种配置。当使用低功耗模式(RANG = 0, HGO = 0)时,负载电容、反馈电阻、和串行电阻已经集成在单片机内部了,外面只需加晶体即可。这种配置的功耗比较低,且可以抵消上述误差因素的影响。当使用高增益模式(RANG = 0,HGO = 1)时,外部要加负载电容、反馈和串行电阻。这种配置的抗干扰能力比较强,但外部元器件对振荡频率的精确性存在影响。对于负载电容引起的频率漂移,我们可以通过选用温漂系数小的电容(如COG电容)来减小其影响。
1.2 温漂
上图是音叉型的晶体振荡频率随温度变化的曲线,它可以用抛物线方程描述为:
Fdev = B (T - TQ)2+ K
其中:
由以上分析可见,对于一个晶体振荡电路,影响其振荡频率误差的因素有:
- 负载电容
- 晶体在转折温度点的频率偏差K
- 温漂Fdev
因此,要使iRTC精确计时,必须消除以上因素带来的误差。负载电容可以通过振荡电路元器件的选择来保证。而后两项则必须通过软件的办法来校准和补偿。
2 实时时钟的补偿原理
实时时钟使用外部的32768Hz 振荡时钟经由32768分频产生秒脉冲。寄存器IRTC_COMPEN用来对补偿进行配置;这包括补偿的时间间隔(compensation interval) 和补偿值(compensation value) 。补偿电路根据配置在固定的时间间隔内(compensation interval)增加或减少振荡周期。
补偿间隔和补偿值寄存器
补偿间隔(compensation interval)是无符号整数,取值范围是1-255 秒;补偿值(compensation value)的取值范围是-128 to 127。增加或减少一个振荡周期将会产生±30.5ppm(1/32768)的频率偏移,所以此补偿电路具有0.119ppm(interval = 255,value = 1)到3906ppm(interval = 1, value = -128)的补偿能力。如果补偿间隔(compensation interval)或补偿值(compensation value)之一设置为0将禁止补偿功能。
实时时钟模块在补偿周期的第一秒进行补偿。根据补偿寄存器设置对第一秒钟增加或减少相应的振荡周期(compensation value),其它的秒脉冲输出保持不变。从而导致秒脉冲之间的时长不同,但从长时间来看时间精度因得到补偿而大为提高。
MG64的实时时钟模块(iRTC)可以配置为在引脚RTCCLKOUT输出补偿后的秒脉冲。图2-1说明了引脚RTCCLKOUT 输出秒脉冲的情况。秒脉冲的高电平时长为一个时钟振荡周期(1/32768 秒)。
在没有启动补偿的情况下,每个秒脉冲的周期都是T(包含32768个时钟振荡)。如果启动补偿并设置补偿间隔为M,补偿值为V,那么在每个补偿周期(M秒内),第一个秒脉冲周期会增加或减少V个时钟振荡,变为32768 ±V个时钟振荡。第一个秒脉冲的长度与其它秒脉冲长度不同。
在图2-1中,补偿间隔为M,补偿值为V。
T= 32768 个振荡周期
Tcomp+/- =(32768 ± |V|)个振荡周期
由补偿值决定,第一秒钟(Tcomp)被减少或增加|V| 个振荡周期。其它的秒脉冲时长仍然是32768 个振荡周期。
补偿间隔和补偿值的选择可以根据晶体的误差和需要的补偿精度来决定。
表1中的例子说明如何根据补偿误差最小化来选择补偿间隔和补偿值。
表2列出了当晶体的误差为-2ppm ,不同补偿间隔的补偿值及补偿后的误差。根据公式2为不同的补偿间隔计算补偿值;根据公式3可以计算出各补偿间隔和补偿值组合补偿之后的误差。最佳补偿间隔(61)和补偿值(-4)是根据补偿后误差最小而选取的。
公式1用来计算引入误差后的晶体振荡周期,它可以由晶体的误差定义CrystalError = Δf/f推导得出。晶体误差一般用ppm表示,注意量纲的换算。
在表1中对不同的晶体误差列出了对应的补偿值和补偿后的误差。补偿间隔限制在127之内。在补偿之后,如果测量的时间大于补偿间隔,测得误差大为减小。
表1 晶体误差对应的补偿值(补偿间隔< 128)
晶体误差(频率:ppm)
补偿间隔
补偿值
补偿后误差(ppm)
0
0
0
0
-1
61
-2
0.035095215
-2
61
-4
0.07006836
-3
61
-6
0.104919435
-4
61
-8
0.139648441
-5
116
-19
-0.16891478
-6
117
-23
-0.099914526
-7
109
-25
-0.065887414
-8
103
-27
-0.031982369
-9
78
-23
-0.102020207
-10
58
-19
-0.171813907
-11
86
-31
0.034515495
-12
89
-35
0.102417146
-13
54
-23
-0.104827762
-14
109
-50
-0.142455756
-15
59
-29
-0.003509322
-16
103
-54
-0.077148016
-17
70
-39
0.165314065
-18
39
-23
-0.108337175
-19
53
-33
0.060943967
-20
29
-19
-0.177612073
-21
93
-64
0.083985236
-22
43
-31
0.024109345
-23
69
-52
-0.122435684
-24
103
-81
-0.135496623
-25
83
-68
0.143433914
-26
27
-23
-0.113952162
-27
26
-23
-0.114654029
-28
97
-89
-0.01159455
-29
20
-19
-0.182830323
-30
59
-58
-0.033567743
表2 不同补偿间隔对应的补偿值(晶体误差=-2 ppm)
补偿间隔
补偿间隔内总误差
补偿值
取整后的补偿值
补偿后误差(ppm)
1
-2
-0.065536131
0
-2
2
-4
-0.131072262
0
-4
3
-6
-0.196608393
0
-6
4
-8
-0.262144524
0
-8
5
-10
-0.327680655
0
-10
6
-12
-0.393216786
0
-12
7
-14
-0.458752918
0
-14
8
-16
-0.524289049
-1
14.51751709
9
-18
-0.58982518
-1
12.51751709
10
-20
-0.655361311
-1
10.51751709
11
-22
-0.720897442
-1
8.51751709
12
-24
-0.786433573
-1
6.51751709
13
-26
-0.851969704
-1
4.51751709
14
-28
-0.917505835
-1
2.51751709
15
-30
-0.983041966
-1
0.51751709
16
-32
-1.048578097
-1
-1.48248291
17
-34
-1.114114228
-1
-3.48248291
18
-36
-1.179650359
-1
-5.48248291
19
-38
-1.24518649
-1
-7.48248291
20
-40
-1.310722621
-1
-9.48248291
21
-42
-1.376258753
-1
-11.48248291
22
-44
-1.441794884
-1
-13.48248291
23
-46
-1.507331015
-2
15.03503418
24
-48
-1.572867146
-2
13.03503418
25
-50
-1.638403277
-2
11.03503418
26
-52
-1.703939408
-2
9.03503418
27
-54
-1.769475539
-2
7.03503418
28
-56
-1.83501167
-2
5.03503418
29
-58
-1.900547801
-2
3.03503418
30
-60
-1.966083932
-2
1.03503418
31
-62
-2.031620063
-2
-0.96496582
32
-64
-2.097156194
-2
-2.96496582
33
-66
-2.162692325
-2
-4.96496582
34
-68
-2.228228456
-2
-6.96496582
35
-70
-2.293764588
-2
-8.96496582
36
-72
-2.359300719
-2
-10.96496582
37
-74
-2.42483685
-2
-12.96496582
38
-76
-2.490372981
-2
-14.96496582
39
-78
-2.555909112
-3
13.55255127
40
-80
-2.621445243
-3
11.55255127
41
-82
-2.686981374
-3
9.55255127
42
-84
-2.752517505
-3
7.55255127
43
-86
-2.818053636
-3
5.55255127
44
-88
-2.883589767
-3
3.55255127
45
-90
-2.949125898
-3
1.55255127
46
-92
-3.014662029
-3
-0.44744873
47
-94
-3.08019816
-3
-2.44744873
48
-96
-3.145734291
-3
-4.44744873
49
-98
-3.211270423
-3
-6.44744873
50
-100
-3.276806554
-3
-8.44744873
51
-102
-3.342342685
-3
-10.44744873
52
-104
-3.407878816
-3
-12.44744873
53
-106
-3.473414947
-3
-14.44744873
54
-108
-3.538951078
-4
14.07006836
55
-110
-3.604487209
-4
12.07006836
56
-112
-3.67002334
-4
10.07006836
57
-114
-3.735559471
-4
8.07006836
58
-116
-3.801095602
-4
6.07006836
59
-118
-3.866631733
-4
4.07006836
60
-120
-3.932167864
-4
2.07006836
61
-122
-3.997703995
-4
0.07006836
62
-124
-4.063240126
-4
-1.92993164
63
-126
-4.128776258
-4
-3.92993164
64
-128
-4.194312389
-4
-5.92993164
…
…
…
…
…
在实际的应用中,我们可以根据需要的补偿精度来选择补偿间隔和补偿值。最大补偿间隔可以根据实际情况确定。例如如果每分钟都要高精度输出,那么补偿间隔可以设置为60。
下图为根据上述方法选取一些温度点做补偿的实验结果。Fdev为补偿之前的频率偏差, Fcalib为补偿之后的频率偏差。从实验数据可见,使用正确的补偿间隔和补偿值,MC9S08MG64的iRTC的精度完全可以控制在2ppm以内。
3 实时时钟的温度补偿
上面讨论了在一个固定的温度下如何做时钟的补偿及其原理,现在我们讨论在温度变化的情况下如何做时钟的自动补偿。如前所述,晶体的频率偏差可以用抛物线方程来描述,如果我们确定出抛物线,那么就可以通过温度(温度的测量可以用集成温度传感器或NTC电阻来完成)来确定出频率偏差从而对其进行补偿。比较常用的一种方法就是测出一些点然后用最小二乘法拟合。简要描述如下:
由一些已知点拟合抛物线方程:
已知点:(X1,Y1), (X2,Y2), (X3,Y3) … (Xn,Yn).
确定抛物线方程y=ax2+ bx + c 的系数。
最小二乘法:
至少需要三个点来确定此抛物线。
晶振典型温漂曲线形式如下:
y = a(x-t)2+ k = ax2- 2atx + at2+ k
对于同一个型号的晶体,假定抛物线二次系数不变,可由公式(2)(3)求得b c,然后得出t, k。从而实现两点校正。由于抛物线越远离顶点变化率越大,所以在抛物线的两端进行校正可以得到更好的补偿精度。
t = -b/2a
k = c - b2/4a
如果晶体的一致性比较好,系数a和t偏差不大,可以只对系数k进行标定。即单点校正。
4 使用FTM 模块产生秒脉冲
在一些应用中,实时时钟输出的秒脉冲需要用光耦隔离。过窄的时钟脉冲难以通过低速光耦。在这一节中,将讨论一种使用FTM 模块来校正实时时钟iRTC输出的秒脉冲的方法。校正后的秒脉冲将具有:
- 更高的精度(每个秒脉冲)
- 50% 的占空比
4.1 以RTCCLKOUT做时钟源产生秒脉冲
在上述讨论的实时时钟(iRTC)的校准方法中,RTCCLKOUT时钟在长的时间内精度得到了保证。在图2-1中可以看到,由于补偿间隔是M(M>1)秒,补偿间隔内的第一秒长度和其它秒长度是不一样的,因为第一秒包含了补偿时间。如果我们能把此补偿时间平均分配到补偿间隔内的每一秒钟,使每一秒的长度相等(每一秒都得到补偿),那么我们将得到均匀的高精度秒脉冲输出。
单片机中的程序计算补偿间隔内每一秒的补偿时间并对每一秒进行补偿。如果补偿间隔是M,补偿值是N,那么每一秒钟的补偿值就是N/(32768 ×M)秒。N/(32768×M)可能是一个很小的值,因此我们需要一个高精度的时钟来得到高分辨率(精度)。
在此方案中我们使用总线时钟(bus clock),该总线时钟由外部的32768Hz 晶体(XOSC1)组成的振荡器产生参考频率,然后经由片内倍频电路锁频环(FLL)倍频获得。锁频环(FLL) 和实时时钟(iRTC)共用同一外部振荡源。锁频环(FLL)的倍频系数设置为512,所以总线频率最大为16.78MHz(512×32768)。每一秒的补偿时间为(512×N)/M 总线时钟周期,它消除掉了温度和晶体老化的影响。
从图2-1(补偿后的实时时钟秒脉冲输出)中我们可以看出,当前补偿周期的最后一个时钟沿就是下一个补偿周期的第一个时钟沿。用第一个时钟沿做对齐,实时时钟的补偿精度得到继承(上升沿和下降沿都可以用来做对齐;由软件来设定)。
MC9S08GW64 的FTM模块的每个通道可以单独工作在输入捕捉或者输出比较模式。我们可以使用一个FTM模块的两个通道,其中的一个通道来捕捉iRTC输出的窄脉冲,另一个通道输出50%占空比的秒脉冲。
当 FTM模块的通道1捕捉IRTCCLKOUT的上升沿(或下降沿)时使用总线时钟,在FTMCH1中断触发后保存FTM计数器的捕获值到FTMCH1V。在FTMCH1中断程序中,FTMCH0被设置为输出比较模式,输出比较值设置为FTMCH1V加一个偏移Ф。Ф为一个常量加每一个脉冲周期的调整值。表3列出了IRTCCLKOUT和FTM输出边沿的上升时刻,以及两者的脉冲宽度。
表3 IRTCCLKOUT 和FTM 输出时序
TAVG= V ÷ M(晶体振荡周期)
= 512 × V ÷ M(总线时钟周期)
从表3可以看出,RTCCLKOUT先右移了σ。每一个秒脉冲用平均的补偿值进行补偿。
图4-1和图4-2对这种补偿方法做了详细地说明。图4-1演示了加入一些振荡周期的情形。
在图4-1中:
图4-2 说明了减少一些振荡周期的情形。
图4-2:
偏移量 σ(延迟)有两个作用:
- 对实时时钟iRTC 输出进行移相;每个秒脉冲的补偿都基于这个值
- 有足够的时间处理FTMCH1中断
每一个秒脉冲的补偿时间都被加上σ,在例程中σ 被设置为0x8000,在总线时钟为32768 ×512Hz时这相当于1.9ms。σ值的大小取决于补偿间隔(compensation period)和补偿值(compensation value)。
0 < σ - (M-1)(512 × V/M) < 0xFFFF
-128 < V < 127
一般来讲,当温度变化时晶体的误差总是负的,所以σ 可以设置为一个比较小的值,比如0x2000,0x1000,补偿的范围得以增大。
FTMCH0设置为输出比较模式(匹配时设置输出为高),当FTM 计数器的值和FTMCH0V 寄存器的值匹配时FTMCH0引脚被置高,FTMCH0中断被触发。FTM 设置为128分频,0.5秒后FTMCH0输出变低。当输出变低时FTM的分频比设置为1。
4.2 硬件配置和例程
MCU的串口SCI0用来和PC通讯,在PC端可以使用超级终端。IIC用来读取集成温度传感器LM75B的数值。ADC模块读取NTC和电阻的分压。RTCCLKOUT (Pin20) 连接至FTMCH1 (pin 38)。1Hz秒脉冲FTMCH0 pin (Pin37)通过光耦隔离后输出,可以在校表台上测量。例程是用CodeWarrior 6.3 IDE开发的。
电路板上电后会进入自动补偿模式,根据环境温度的变化对实时时钟进行补偿。在超级终端中按任意键退出自动补偿模式,然后输入命令help可以显示所有可用的命令:
comp 显示当前的补偿间隔和补偿值,并输入新值。
temp 显示温度。
date 显示日期并输入新日期。
time 显示时间并输入新时间。
auto 重新进入自动补偿模式。
在FTMCH1的中断服务程序中,做FTMCH0输出比较时间的调整。如果当前补偿周期结束,它会检查有没有新的补偿间隔和补偿值。如果有则把新值载入补偿寄存器,并重新计算补偿调整值。
在补偿周期结束前,IRTC_STATUS 寄存器中的C_DON (IRTC_STATUS_L_C_DON) 会被置位。它被用来对齐补偿周期。
实时时钟iRTC的补偿机制可以在长时间内(>补偿间隔)输出高精度的秒脉冲,FTM则用来保证在补偿间隔之内每个秒脉冲周期相等。
说明
当开发GW64工程时,推荐在iRTC的初始化中禁止掉iRTC中断,或者定义iRTC中断服务程序。因为即使当下载一个新程序时,iRTC模块仍然保留着上一次的配置(iRTC可以由VBAT供电,MCU掉电时,iRTC的配置仍然保留)。在初始化时必须禁止掉iRTC中断,或者定义其中断服务程序。否则可能发生不可预期的错误。
5 补偿流程
使用上述软件,我们可以不用关心补偿算法的细节,按照下面的简单步骤来完成晶体振荡电路在全温度范围内的自动补偿:
(1) 把补偿间隔和补偿值设置为0(Interval = 0, Value = 0),在全工作温度范围内调整温度并记录频率偏差值。测量点越多越好。
(2) 利用测量点拟合抛物线(a(x - t)2+ k),得出抛物线参数a, t, k。
(3) 把参数写入程序中。
对于同一批次的晶体,如果晶体的一致性比较好,可以用上面的步骤确定出参数a,和t。在批量生产时,在任意一个温度点测量晶体的误差,即可反推出k。其他温度点的误差即可通过抛物线公式计算得出,根据误差查表得到需要的补偿间隔和补偿值。把补偿间隔和补偿值写入补偿寄存器即可得到精确的秒脉冲输出。参数a, t和k 都要保存在非易失性存储器中以防掉电丢失。
6 总结
本文介绍了实时时钟iRTC的补偿机制和如何输出均匀秒脉冲的问题,探讨了如何在全温度范围内对iRTC进行补偿。iRTC可以在长时间内保持高精度,FTM模块用来输出每个周期都很均匀的秒脉冲。在全温度范围内的补偿精度依赖于晶体的一致性,建议采用高精度,一致性好的晶体。温度测量器件基于成本考虑建议采用NTC电阻,根据测量值用查找表来确定温度,NTC电阻应尽量靠近晶体。MG64有一个内部温度传感器,通过标定也可以达到比较高的测温精度,使用它可以进一步降低系统的硬件成本。内部温度传感器的标定方法请参考应用手册AN3031(Temperature Sensor for the HCS08 Microcontroller Family)。