实时时钟是单片机系统面临的重要课题,理论上讲,每个单片机应用系统都应具有实时时钟系统,如同PC机及手机上的RTC。我看了一些应用系统例程,无非是两种办法:一是用单片机自己的TIMER,再者是用DS1302时钟芯片。 实时时钟的计时精度最终取决于晶振的准确性及稳定度,PC及手机的计时精度是非常不错的,由于其生产规模庞大,估计其晶振的性价比极高,以器件渠道而言,单片机系统难以比附,在这种情况下,如何提高单片机系统的计时精度呢?或者说,从理论上讲,我们最终能够做到多少精度? 常见单片机用晶振的指标大约是准确度50~150PPM,稳定性也是这样,根根有关理论,晶振的秒稳定度应比其准确度至少高一数量级,这样综合考虑下来,则其合成准确度十分恐怖,再考虑温漂,廉价晶振无非是个节拍器罢了,对于计时而言,可以说一无是处。 那么实测结果又怎样呢? TIMER的计时准确度取决以下几个方面:晶振的稳定度、谐振电容的匹配性及温漂、软件处理的合理性。 软件处理实际上是一个重装初值的问题,我采取如下办法: TR0=0; TL0=TL0+V_TL0; TH0=TH0+V_TH0; TR0=1; 以上的办法我理解为动态修正,与救火车老师讲的原理殊无二致。根据在KEIL中的模拟:在置位TR0的情况下,观察进入TIMER中断时TL0的值,多次观察的结果,其值并不一致,这是因为TIMER每次响应中断的时间并不相同所致。所以动态修正是必要的。 上几条语句反汇编的结果如下: CLR TR0(0x88.4) MOV A,#IP(0xB8) ADD A,TL0(0x8A) MOV TL0(0x8A),A MOV A,#0x3C ADD A,TH0(0x8C) MOV TH0(0x8C),A SETB TR0(0x88.4)
根据以前在论坛中咨询的结果,以上指令共需八个机器周期,由于执行SETB TR0时TL0已开始计数,所以在理论初值上一共补偿7个。 谐振电容按资料上讲应尽量匹配,且宜选用温飘低的正牌厂家的产品,由于渠道所限,所用的电容应该疑似正牌罢! 我没有采用从晶振的XTAL2处直测频率的办法,这是出于不影响其正常振荡的考虑,采取测中断周期这种间接的办法,通过不断调整V_TL0,得到精确的100ms中断周期,再通过V_TL0反推晶振真实频率,考虑量化误差的影响,晶振频率准确度约为30ppm。 稳定性如何呢?在温度、电源负载恒定的情况下,可以忽略不计。 在实验室(未刻意恒温)中启动计时24小时,未见明显误差。在打开实验室窗户的情况下再计时24小时,由于当日气温下降了约10度,其计时误差为10秒。(采取用收音机收地方台的办法授时)。 10秒是个致命的误差。接下来几天继续观察,偏快偏慢不等,看来用廉价晶振时,单片机的TIMER并不适合做系统的实时时钟。 DS1302又如何呢?我没有首选DS1302是基于如下考虑:3元芯片+2元晶振+1元电池+3根口线,其软件效率如何呢?由于是串行读写,有这读写的功夫,TIMER也已完成了计时,况且用TIMER可直接从内部RAM中取数,用DS1302得通过串行办法从外部RAM中取数,那个速度要慢很多。再则二者的计时精度都是依赖晶振,无非一个是用硬件计时一个是用软件计时,二者并无本质的差别。还有,TIMER在晶振稳定性优于其准确度的情况下,可以用软件修正的办法提高计时精度,而DS1302在晶振不准时只能无可奈何! 惟一的好处是DS1302用的晶振号称钟振,听说电脑主板、石英钟、表都用的是这个,渠道或者畅通一点罢,至于DS1302对晶振负载电容6PF的要求,询问商家,茫无所知,渠道仍属不畅,但总要试一下。 对DS1302的试验结果是日误差20秒,这个当然与器件本身无关,问题在晶振,网上有资料说,可以串或并一个几PF电容调整晶振的负载电容,通过用频率计测试,得到精确的32.768kHz的晶振频率,我对此方法存疑,因为我在监测晶振频率的过程中,一个小时内,计时误差达到数分钟,亦即测试工作直接影响到了晶振振荡频率,纵然你依此调出了准确的频率,但取下频率计的测试线后,其振荡频率并不是你调校好了的结果。再者,即便通过串并联电容得到了较好的准确度,也只是摸石头过河的个案成功,并无理论上的指导意义,继续试验的价值不大。 总结困难,问题在器件上——晶振、电容、负载电容。虽说国货当自强,但困难在眼前,用SEIKO、EPSON的器件罢,据说“贼贵”,用内部集成晶振及电池的计时芯片吧,“成本就上去了”,我想,用常规的国产器件,加上一些软硬方法,做一个单片机的实时时钟模块,达到PC机及手机RTC的精度,应该是有办法的,想就此求教各位老师!
|