应用笔记 2740

如何访问DS1318的时钟寄存器


摘要 : 该应用笔记描述了如何适当访问DS1318历时计数器的时钟寄存器。实时时钟(RTC)的读、写操作和时钟寄存器的内部更新不同步,需要做出正确判断,确保数据的准确性。

引脚配置

概述

DS1318并行接口历时计数器(ETC)是一款44位计数器,提供分辨率244µs的历时。ETC具有6个寄存器,其中4个寄存器表示为32位秒计数,其余两个寄存器使用12位记录亚秒级计数(表1)。DS1318能够用于时间和日期记录。ETC寄存器里的零值必须定义为某个确定的“零计时起点”。比如,在Unix系统中,零计时起点为1970年1月1日午夜零时,则32位秒寄存器可表示1970年1月1日午夜零时至2038年1月19日03:14:07之间的任何时间。转换程序通常完成将32位计数值转换成标准的时间和日期格式。请参考网站china.maximintegrated.com/AN517上的应用笔记517:DS1371/DS1372/DS1374 32-Bit Binary Counter Time Conversion。DS1318还可用于两个事件之间的计 时。

表1. 地址分配表
Address Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Function Range
00H SS3 SS2 SS1 SS0 0 0 0 SQWS Subseconds0 00-F0h
01H SS11 SS10 SS9 SS8 SS7 SS6 SS5 SS4 Subseconds1 00-FFh
02H S7 S6 S5 S4 S3 S2 S1 S0 Seconds0 00-FFh
03H S15 S14 S13 S12 S11 S10 S9 S8 Seconds1 00-FFh
04H S23 S22 S21 S20 S19 S18 S17 S16 Seconds2 00-FFh
05H S31 S30 S29 S28 S27 S26 S25 S24 Seconds3 00-FFh
06H ALM 7 ALM 6 ALM 5 ALM 4 ALM 3 ALM 2 ALM 1 ALM 0 Alarm0 00-FFh
07H ALM 15 ALM 14 ALM 13 ALM 12 ALM 11 ALM 10 ALM9 ALM 8 Alarm1 00-FFh
08H ALM 23 ALM 22 ALM 21 ALM 20 ALM 19 ALM 18 ALM 17 ALM 16 Alarm2 00-FFh
09H ALM 31 ALM 30 ALM 29 ALM 28 ALM 27 ALM 26 ALM 25 ALM 24 Alarm3 00-FFh
0AH TE ECOSC CCFG1 CCFG0 EPOL SQWE PIE AIE ControlA 00-FFh
0BH PRS3 PRS2 PRS1 PRS0 SRS3 SRS2 SRS1 SRS0 ControlB 00-FFh
0CH OSF UIP 0 0 0 0 PF ALMF Status --

在任何应用中,ETC运行时通常需要读取ETC寄存器值。DS1318提供一组“用户寄存器”,允许在内部计数器运 行的同时访问寄存器数据。每244µs内部寄存器更新一次用户寄存器。尽管计数器带有缓冲,但由于读操作和计数 更新是异步工作的,仍有可能读取或写入错误的数据。

例子1

在读取ETC寄存器时,数据可能在更新。比如,如果寄存器中的数据是0x55555555.FFF,在读亚秒和秒寄存器之 间时,数据可能更新,读取的值可能为0x55555556.FFF,而不是0x55555556.000。

例子2

当访问某个寄存器时,数据正从内部计数器传输到用户寄存器。在这种情况下,数据更新和读操作可能仅相差几个 纳秒。虽然出现的概率很低,但当它真的发生时,则读取的数据是无效的。

例子3

执行写操作,同时内部计数器和用户寄存器之间正在传输数据。由于内部数据总线在传输过程中被占用,对DS1318内部任何寄存器的写操作都破坏数据(数据冲突)。在这种情况下,如果发生的时间差仅几个纳秒时,则用户寄存器中 的数据无效,直至244µs之后的再次更新为止。

例子4

当写计数器时,如果对所有计数器的写操作时间超过244µs,则更新操作将发生,必然增加先前写入寄存器中的数 据。

有几种办法可避免上述错误。DS1318包含两个控制位,用于避免在更新过程中进行读或者写操作。以下段落讨论这 些方法。

更新操作可能发生在读计数寄存器时。一种验证所读数据是否正确的方法是:以LSB到MSB的顺序读取对应的寄 存器,并存储结果,然后再次读取这些寄存器。如果发生了更新操作,则第一次读取数据和第二次读取数据不同。 如果数据不同,需要再次读取这些寄存器,直到前后数据匹配为止。如果使用了亚秒级寄存器,则每244µs发生一 次更新操作。如果仅使用了秒寄存器,则更新操作每秒一次(图1)。

图1. 在两次更新操作之间读取时钟寄存器
图1. 在两次更新操作之间读取时钟寄存器

当读计数器时,通过判断更新进行中(UIP)标志位,以避免出错。UIP每244µs置位一次,如果更新操作在61µs之内发生,则其值为1。当读计数寄存器时,应该判断UIP位。如果其值为1,应该延时读操作,直到UIP为0。如果UIP为0,则可以读取寄存器。应该在60µs之内读寄存器,以避免下一次更新操作(图2)。如果读寄存器程序的执行时间大于60µs (例如,程序被另一个程序中断,且执行时间大于60µs),则必须注意应当确保数据是否有效。

图2. 采用UIP位读取时钟寄存器
图2. 采用UIP位读取时钟寄存器

另一种读寄存器的方法是使用UIP位和传输使能位(TE)。当TE位被设置为0时,将停止内部计数器和用户寄存器之间的数据传输,由于上次数据更新可能会被写TE位操作破坏,因此在改写TE位时,应当判断UIP位,避免发生更新操作。一旦TE被设置为0,数据还可以从寄存器中读出。由于更新被禁止,因而不必在意UIP位是否被设置,或者要花多长时间读取寄存器数据。这个例程可代替前面的例程,在那些应用中可能需要花费60µs以上的时间读取所有寄存器。

一旦数据被读出,应当设置TE位为1。允许数据更新。注意:为发生一次计时更新,传输使能应至少保持244µs。由于这个要求,因此采用这个方法不可能读到后续变化的亚秒0寄存器数据(图3)。

图3. 使用UIP和TE位读时钟寄存器
图3. 使用UIP和TE位读时钟寄存器

周期中断与时钟寄存器的更新保持同步。如果PF标志用作中断输出,则在数据更新后马上读取时钟寄存器。如果准备读取亚秒寄存器,则在244µs内不会遇到计时更新。如果仅使用秒寄存器,则下次更新将在1秒后发生。该程序可使用在时间和日期周期性更新的应用中,例如要求显示时间和日期。使用PF标志位驱动控制器的中断输入,允许系统在时间未发生变化时,执行其他的功能。

图4. 使用周期中断标志位读时钟寄存器
图4. 使用周期中断标志位读时钟寄存器

图5. 使用TE和UIP位写时钟寄存器
图5. 使用TE和UIP位写时钟寄存器

当往计数寄存器写数据时,可使用TE。当TE被写入1时,所有写入用户寄存器中的数据将传输到内部计数器。如果所有寄存器被写,则无需特别担心数据冲突。如果仅改写部分寄存器,相对于其余的寄存器,将可能产生读寄存器和获取有效数据的问题。在这种情况下,应当判断UIP位,以避免冲突。