摘要: 器件DS87C530和DS5250高速微控制器与实时时钟(RTC)是理想的应用,如数据记录。本应用笔记检查了连接到DS1620数字温度计和恒温器的温度测量技术。时间测量和报警设置也进行了讨论。示例代码包含在本应用程序说明中。
DS87C530和DS5250结合了实时时钟(RTC)和闹钟,允许用户执行真实世界的定时操作,如时间戳事件,在特定时间执行任务,或执行很长的定时延迟。虽然软件定时循环或内部计时器可用于此类测量,但它们依赖于晶体,对于长时间测量效率低下,并且与电源管理模式的使用不兼容。RTC的集成意味着只需要32.768kHz晶体。无负载电容器需要与RTC晶体。RTC由专用的特殊功能寄存器(SFRs)控制。
RTC由次秒、秒、分、小时、星期和两个总日计数寄存器组成。此外,还有一个用于亚秒、秒、分和小时寄存器的报警寄存器。亚秒寄存器提供1/256秒的分辨率和1秒的最大翻转计数。RTC使用的寄存器和控制位如表1所示。复位后指定为不变的位和寄存器在无电池复位后可能是不确定的。请查阅完整的位或寄存器描述以了解完整的细节。
位名称 | 位置 | 函数 | 范围 | 重置 | 读/写访问 |
ERTCI | EIE.5 | RTC中断使能 | 0 | 不受限制的 | |
PRTCI | EIP.5 | RTC中断优先级 | 0 | 不受限制的 | |
RTASS.7-0 | 区域贸易协定 | RTC报警分秒 | 0-FFh | 不变 | 不受限制的 |
RTAS.5-0 | 区域贸易协定 | RTC报警秒 | 0-3Bh | 不变 | 不受限制的 |
RTAM.5-0 | RTAM | RTC报警分钟 | 0-3Bh | 不变 | 不受限制的 |
RTAH.4-0 | RTAH | RTC报警时间 | 0-17H | 不变 | 不受限制的 |
RTCSS.7-0 | RTCSS | RTC次秒级 | 0-FFh | 不变 | 只读:仅当RTCRE=1时。 不能写。 RTCWE 1<0时清除 |
RTCS.5-0 | 清债信托公司 | RTC第二 | 0-3Bh | 不变 | 只读:仅当RTCRE=1时。 Write:仅当RTCWE=1时。 1ms读/写窗口 |
RTCM.5-0 | RTCM | RTC分钟 | 0-3Bh | 不变 | |
RTCH.4-0 | RTCH.4-0 | RTC小时 | 0-17h | 不变 | |
DOW2-0 | RTCH.7-5 | RTC星期几 | 0-7h | 不变 | |
RTCD1.7-0 RTCD0.7-0 | RTCD1 (MSB) RTCD0 (LSB) | RTC的一天 | 0-FFFFh | 不变 | |
SRCE | RTCC.7 | RTC次秒级 比较支持 | 不变 | 不受限制的 | |
南加州爱迪生公司 | RTCC.6 | RTC二次比较 启用 | 不变 | 不受限制的 | |
多国评价 | RTCC.5 | RTC分钟比较 启用 | 不变 | 不受限制的 | |
HCE | RTCC.4 | RTC小时比较 启用 | 不变 | 不受限制的 | |
RTCRE | RTCC.3 | RTC读使能 | 0 | 不受限制的 | |
RTCWE | RTCC.2 | RTC写使能 | 0 | 读:无限制 写:定时访问 | |
RTCIF | RTCC.1 | RTC中断标志 | 0 | 不受限制的 | |
RTCE | RTCC.0 | RTC启用 | 不变 | 读:无限制 写:定时访问 | |
E4K | TRIM.7 | 外部4096Hz RTC 信号使 | 0 | ||
X12 / / 6 \ | TRIM.6 | RTC水晶 电容选择 | 不变 | ||
TRM2-0 | TRIM.5 TRIM.3 TRIM.1 | RTC修整位2-0 | 不变 | 读:无限制 写:定时访问 | |
/0 - trm2 \ | TRIM.4 TRIM.2 TRIM.0 | 反向修整钻头 2 - 0 | 不变 | 读:无限制 写:定时访问 一定是的倒数 TRM2-0 |
请注意,TRM2及其逆在DS5250上不存在。用户软件和内部时钟都直接写入和读取RTC时间寄存器(RTCSS, RTCS, RTCM, RTCH, RTCD0, RTCD1)。寄存器锁定机制防止了用户软件和内部定时器同时访问同一寄存器的可能性。在软件读或写操作期间,内部计时器对RTC时间寄存器的更新被暂时挂起,最长可达1ms。如果在1ms窗口中出现亚秒计时器,则一旦RTCWE或RTCRE位被清除,它将立即被处理。为了防止意外写入RTC时间寄存器的可能性,应该在计划的修改完成后立即清除RTCWE位。作为一种保护措施,如果软件中没有清除RTCWE位,设备会在1ms后自动清除RTCWE位。为了允许处理任何待处理的计时器节拍,软件必须在RTCWE或RTCRE位的任何连续修改之间等待四个机器周期。
该方案不会影响RTC的准确性,因为在读或写窗口期间可能出现的任何亚秒计时器只会暂时延迟,而不会丢弃。只有对单个亚秒计时器滴答的识别被延迟,随后的滴答将与时钟同步。关于RTC操作的唯一可能的含义是,如果在时间寄存器读取操作期间发生会导致警报中断的计时器滴答。在这种情况下,警报将延迟零点几毫秒,直到RTCRE位被清除。如上所述,下一个亚秒计时器将在适当的时间发生,因此长期时钟精度不会受到影响。
观察4台机器周期设置和1ms窗口时间是至关重要的。在4个机器周期之前从时间寄存器读取的任何操作都可能返回一个无效的时间。在4个机器周期之前写入时间寄存器将被忽略。类似地,在1ms窗口之外的任何RTC时间寄存器操作都会导致无效的读操作或忽略写操作。因此,在修改任何RTC寄存器之前,应该全局禁用中断。
RTC晶体放大器的操作由RTC使能位RTCE (RTCC.0)控制。该位只能由定时访问过程访问,不受任何操作复位的影响。然而,在无电池复位后,RTCE位的状态是未定义的,应该初始化。清除RTC使能位将停止晶体放大器和时钟的操作,但所有寄存器值(包括时钟被禁用的时间)将被保留。这可能是为了在存储期间保持备用能源的寿命所需要的。当重新启动RTC晶体振荡器时,无论是从无电池复位状态还是通过设置RTC使能位,都必须遵守晶体启动时间。没有直接的方法来检测RTC晶体振荡器何时稳定,系统软件必须允许在重新启动RTC时有足够的稳定时间。晶体启动时间由晶体制造商指定,但通常在1秒左右。
在电池电量耗尽或第一次连接电池时,有必要初始化RTC。虽然没有状态位来指示无电池复位,但有几种方法可以检测实时时钟何时失去电源/时间。最好的方法是监视板载内存中的保留位置。由于片上SRAM内容与RTC由相同的能量源保存,因此先前加载的存储器位置的意外变化可能表明电池电量的损失。
从RTC获取当前时间是通过以下程序完成的:
通过清除EA位(IE.7)禁用所有中断
设置RTCRE位(rtc .3)
等待4个机器周期
在RTCRE设置后1毫秒内读取相应的寄存器
清除RTCRE位(RTCC.3)
通过设置EA位(IE.7)使能中断
通过写入时钟寄存器来设置时间。秒、分、时、星期几和日计数可以通过写入各自的寄存器来设置。这是不可能设置实时时钟亚秒寄存器(RTCS;FBh)。当RTCWE位被清除时,通过软件或1ms写窗口的自动超时,该寄存器自动重置为00h。忘记RTC时间寄存器的过程如下:
通过清除EA位(IE.7)禁用所有中断
执行定时访问过程
设置RTCWE位(rtc2)
等待4个机器周期
在RTCWE设置后1毫秒内写入相应的寄存器
执行定时访问过程
清除RTCWE位(rtc2)
通过设置EA位(IE.7)使能中断
RTC告警功能用于当RTC值与选定的告警寄存器值匹配时产生中断。一个告警可以由以下一个或多个告警寄存器的匹配触发:亚秒(RTASS;F2h),秒(RTAS;F3h),分钟(RTAM;F4h)和Hour (RTAM;F5h)。请注意,没有与RTC日或星期寄存器相关联的警报寄存器。如果需要在特定日期发出警报,则可以每天发出一次警报,用户软件可以将当前日期与日寄存器进行比较。设置告警寄存器时,不需要设置RTC写使能位。
可以将警报设置为在与任何或所有警报寄存器匹配时发生。闹钟可以在一天中唯一的时间发生,或者可以每亚秒、秒、分或小时设置一个重复的闹钟。通过设置或清除相应的比较使能位(RTCC.7-4)来选择要比较的具体告警寄存器。任何被清除的比较位将导致该寄存器在评估报警条件时被视为“不关心”。清除所有的比较使能位将禁用RTC引起中断的能力,并将立即清除RTC中断标志(RTCC.1)。与某些中断不同,RTC标志不会通过退出RTC中断服务程序来清除,必须在软件中完成。
设置RTC告警寄存器导致RTC中断的一般步骤如下:
清除RTC中断使能位(ie5)
清除所有RTC告警比较使能位(ANL RTCC, #0Fh)
写一个或多个RTC告警寄存器
设置所需的RTC告警比较使能位
设置RTC中断使能位(ie5)
通过将所有报警寄存器设置为所需值并启用所有比较位,可以在24小时内将警报设置为单个时间中断。例如,如果希望在上午11:45:00发出警报,将使用以下配置:
告警亚秒(RTASS) | 00次秒级 | = 00 h |
报警秒数(RTAS) | 00秒 | = 00 h |
报警分钟(RTAM) | 45分钟 | = 2 dh |
闹钟时间(RTAH) | 11个小时 | = 0黑洞 |
时钟控制(RTCC) | 次秒级比较 | = F1h |
第二个比较 | ||
分钟的比较 | ||
小时比较 |
通过禁用与一个或多个告警寄存器相关联的比较使能位来启用循环告警。通常,使用下一个较低的时间增量设置循环警报。例如,如果需要每小时发出一次警报,就会对RTAM寄存器进行比较,因为RTCM寄存器每小时只匹配RTAM寄存器一次。例如,如果希望在半小时内每小时发出一次警报,则将使用以下配置:
告警亚秒(RTASS) | 00次秒级 | = 00 h |
报警秒数(RTAS) | 00秒 | = 00 h |
报警分钟(RTAM) | 30分钟 | = 1嗯 |
闹钟时间(RTAH) | 11个小时 | = 00 h |
时钟控制(RTCC) | 次秒级比较 | = E1h |
第二个比较 | ||
分钟的比较 | ||
RTC启用 |
在上面的示例中,对亚秒、秒和分寄存器进行编程,并设置相应的比较使能位,即使只需要在分寄存器上匹配。这是因为在评估警报时,“不关心”总是被视为匹配。如果在上面的例子中SSCE和SCE位被清除为0(不关心),那么在RTAM寄存器匹配的每一分钟的每一秒内都会发生匹配(和中断)。这将导致15,360次中断,这很可能不是期望的效果。一般来说,当指定重复报警时,应使能最大时间增量以下的所有比较位,并将相应的报警寄存器加载为00h或已知值。
当时钟滚动以匹配警报条件时,警报可以同步发生,如果警报寄存器设置为与当前时间匹配的值,则可以异步发生。请注意,每亚秒刻度只能发生一次警报。这意味着,如果在当前亚秒内已经发生同步告警,则软件不能在同一亚秒内引起异步告警。
虽然这是一个相对次要的问题,但如果软件希望使用警报的异步功能,它可能会产生影响。例如,假设当告警寄存器匹配当前时间01:00:00:00(1小时,0分钟,0秒,0子秒)时发生RTC中断。RTC中断相对较短,占用的时间远少于一亚秒(<4ms),执行返回到主程序。一旦退出RTC中断程序,就会立即发生一个事件,需要软件通过将警报设置为匹配00分、00秒、00子秒,从而在小时上发出警报。正常情况下,将此告警条件设置为01:00:00:00,将立即导致RTC中断;但因为我们已经在这亚秒内发出了警报,所以情况不会被识别。警报将被忽略,因为它将不会被评估,直到下一个亚秒滴答,当时间将被更改为01:00:00:01。设计人员应该防止在同一次秒内使用同步异步警报的可能性。
由于警报条件可以异步发生,因此必须小心,在写入警报寄存器时不要意外启用匹配。例如:当前时间为0B:00:00:00,当前告警条件为00:00:00:00。假设软件将告警设置为0B:01:00:00。如果小时、秒、分和次秒比较使能,并且第一条指令为MOV RTCH, #0B0H,则会立即发出警报,而不是在预定的时间发出警报。避免这种情况的最佳方法是在更改RTC警报寄存器之前禁用所有比较启用项。
有许多简单的技巧可以用来简化与RTC操作相关的软件。4个机器周期的延迟可以使用CJNE a, a,$指令来执行。与使用4个nop相比,这是一条指令,并且缩短了1个字节。
RTC允许软件动态改变报警寄存器,以实现宽范围的间隔。通常软件会想要以半增量的时间有规律地中断(每30秒,每30分钟,等等)。这可以使用XRL指令轻松完成。例如,如果RTAM寄存器设置为00h,则指令XRL RTAM, #1Eh将把内容更改为1Eh。再次执行该指令将使其变回00h。将此指令放在RTC中断例程的开始处,将导致每次调用中断时都可以轻松快速地修改相应的报警寄存器。
下面的程序演示了使用DS87C530操作远程数据记录站的通用方案。在这个例子中,DS87C530从停止模式唤醒每30分钟从设备DS1620数字温度计和恒温器读取温度。DS1620通过串口0寻址,使用串行模式0。当中断被调用时,DS87C530将使用环形振荡器从停止执行快速恢复并向恒温器发出信号以开始温度转换。然后,它将重置RTC警报,使其在1秒内再次发生。这将允许时间转换和晶体预热期完成,之后设备将自动切换回晶体作为时钟源。DS87C530将读取温度并将其连同小时和分钟一起传输回连接到串行端口1的主机系统。然后,它将返回到停止模式,等待下一个警报。图1显示了DS87C530和DS1620接口的部分原理图。如果DS1620要与微控制器隔很远的距离,则可能需要在时钟和数据线上进行滤波以降低噪声。
图1所示、DS1620接口示例
这个程序演示了如何使用RTC定期为外部设备提供服务。设备在停止模式下停止,直到被RTC中断唤醒;每半小时一次。然后,它从DS1620数字恒温器读取温度,并发送带有时间戳的数据,通过串口1到主机,寄存器等于tableSP equ 81h;堆栈点interpcon equ 87h;电源控制RegisterTCON equ 88h;定时器控制RegisterTMOD equ 89h;定时器模式RegisterTH1 equ 8Dh;定时器1 MSBCKCON equ 8Eh;时钟控制RegisterP1 equ 90h;端口1EXIF equ 91h;外部中断标志RegisterSCON0 equ 98h;串口0控制RegisterSBUF0 equ 99h;串口0数据缓冲p3 equ 0B0h;端口3SCON1 equ 0C0h;串口1控制RegisterSBUF1 equ 0C1h;串口1数据缓冲ta定时访问RegisterWDCON equ 0D8h;看门狗控制RegisterACC equ 0E0h;AccumulatorRTASS equ 0F2h;实时告警子秒RegisterRTAS equ 0F3h;实时告警秒RegisterRTCC equ 0F9h;实时时钟控制rtcm equ 0FCh;实时时钟分钟registerrttch equ 099hREN0 equ 09ChEA equ 0AFhTI1 equ 0C1hERTCI equ 0EdhDS1620_RST equ 090h绑定到DS87C530 P1.0。WR_CONFIG equ 0Ch;DS1620写配置命令。RD_TEMP equ 0AAh;DS1620读取温度命令。START_CONV equ 0EEh DS1620启动转换命令。重置向量。LJMP STARTcseg at 6Bh;实时时钟中断向量。LJMP RTC_INT;cseg at 100H;启动:MOV SP, #40h;MOV EXIF, #0Ah;使环振荡器从停止模式重新启动。MOV P3, #03h;Set P3.1 &P3.0高到使用串口0。MOV SCON0, #20h;设置串口模式0,4 t。MOV P1, #0Ch;Set P1.2 &P1.3 high:使用串口1;Clear P1.0:复位DS1620。MOV SCON1, #40h;设置串口模式1。baudMOV TH1, #0FDh;在11.0592 mhz。MOV TCON, #40h;启动定时器;配置DS1620SETB DS1620_RST;拆除DS1620复位为启动操作。发送命令到地址配置字节。CALL OUT_1620MOV A, #03h;1次模式。CALL OUT_1620CLR DS1620_RST;Assert DS1620 to end operation.;设置RTCMOV RTAM, #00h;报警将响起mov RTAS, #00h;下一小时启动温度remov RTASS, #00h;转换。设置闹钟,这样我们一开始就会有一个闹钟。使能RTC中断。全局中断使能。MAIN: ORL PCON, #02h;设置停止位进入停止模式。主程序循环结束。程序将返回;RTC中断完成后 .;***************************************************************************; RTC_INT——这从DS1620 ISR读取临时和输出数据;串口1。例程开始转换,等待1;二是允许转换完成并使晶体稳定;转换完成后,设备将读取温度;并将小时,分钟和温度发送给主机。RTAM;注册将被修改在30分钟后再报警 .;*************************************************************************** RTC_INT: MOV RTCC, # 081 h;明确RTCI国旗和第二比较启用;在1秒内产生另一个警报。PUSH ACC;保存累加器。SETB DS1620_RST;拆下DS1620复位,开始工作。启动第一次温度转换。调用OUT_1620CLR DS1620_RST;断言DS1620结束操作。打开RTC读进程,并延迟4 machineCJNE A, ACC, $;使时间寄存器稳定的周期。MOV R7, RTCM;节省分钟和小时,可以传输MOV R6, RTCH;只要水晶稳定下来。ANL RTCC, #0F7h;重新启用时间寄存器更新。WAIT: MOV A, RTCC;等待RTC中断标志设置,JNB ACC.1, WAIT;表示转换完成。的;一秒钟的延迟就足够了;水晶要稳定,所以现在就换。把闹钟调到半小时后响。清除RTCI标志,并设置比较位;所以下一个警报将在30分钟后产生。发送起始字符。呼叫OUT_HOSTMOV A, R6;发送小时。呼叫OUT_HOSTMOV A, R7;发送分钟CALL OUT_HOSTSETB DS1620_RST;移除DS1620复位以启动操作。转换完成。 发送命令读取temp.CALL OUT_1620CALL IN_1620;读取温度的LSB并发送给主机。读取温度的MSB并将其发送给主机。断言DS1620结束操作。流行ACC;恢复蓄电池和回到sleep.RETI ;************************************************************************; OUT_HOST——这个例程通过串口将数据发送给主机系统1 .;************************************************************************ OUT_HOST: MOV SBUF1;搬出字节。等待数据传输完成。CLR TI1; TI1.RET清晰 ;************************************************************************; OUT_1620——这个例程通过串口发送数据到DS1620 0 .;************************************************************************ OUT_1620: MOV SBUF0;搬出字节。JNB TI0, $;等待数据传输完成。CLR TI0; TI1.RET清晰 ;************************************************************************; IN_1620——这个例程从DS1620中读取一个字节和回声回来;通过串行端口1 .;************************************************************************ IN_1620: SETB REN0;使接收机时钟数据。JNB RI0, $;等待接收到数据。禁用接收器以阻止接收。CLR RI0;清除RI。MOV A, SBUF0;通过串口1回显数据。叫OUT_HOSTRET
下面的程序是一个通用接口例程,用于设置RTC并显示其状态。该程序通过串口0进行通信,允许用户设置时间和日期,设置报警寄存器,并指示何时发生报警。为了简单起见,程序输入时间的十进制值并输出十六进制值。
;***************************************************************************; 程序RTC_UTIL.ASM;;这个程序响应命令接收串口设置,和阅读的日期,程序初始化28800波特的串口,使用11.0592MHz时钟;***************************************************************************;寄存器等于tableSP equ 81h;堆栈指针dpl equ 82h;数据指针低寄存器dph equ 83h;数据指针高寄存器pcon equ 87h;电源控制寄存器tcon equ 88h;定时器控制寄存器tmod equ 89h;定时器模式寄存器th1 equ 8Dh;定时器1 MSBEXIF equ 91h外部中断标志RegisterSCON0 equ 98h;串口0控制RegisterSBUF0 equ 99h;串口0数据缓冲p3 equ 0B0h;端口3TA equ 0C7h;定时访问RegisterACC equ 0E0h;AccumulatorB equ 0F0h;B RegisterRTASS equ 0F2h;实时告警子秒RegisterRTAS equ 0F3h;实时告警秒RegisterRTAM equ 0F4h;实时告警分钟RegisterRTAH equ 0F5h;实时告警小时RegisterEIP equ 0F8h;扩展中断优先级RegisterRTCC equ 0F9h;实时时钟控制rtcssequ 0FAh;实时时钟亚秒寄存器rtcs equ 0FBh;实时时钟SecondRTCM equ 0FCh;实时时钟分钟寄存器0FDh;实时时钟小时rtcd0 equ 0FEh;实时时钟日寄存器0RTCD1 equ 0FFh;实时时钟日寄存器1;位等价表lle0 equ 98h;串口0接收中断标志0 equ 99h;串口0发送中断标志equ 0AFh;全局中断使能。ERTCI equ 0EDh;实时时钟中断使能;常数相等表elecr equ 0DhLF equ 0Ahcseg at 0;复位向量。LJMP STARTcseg at 6BH;实时时钟中断向量。LJMP RTC_INTcseg at 100H;代码段开始;字符串表。HEX_TABLE: DB '0123456789ABCDEF' new_line: DB CR, LF, 0YES: DB 'Y ', 0NO: DB 'N ', 0COMPARE: DB CR, LF, 'Compare enabled: ', 0COMPARE_Q: DB ' Enable Compare (Y/N)?', 0 alarm_msg: DB CR、低频的警报:“0 tt_banner: DB CR,低频、CR、低频,“DS87C530 RTC效用'DB CR、低频,”T -设置报警,设置时间'DB CR,低频,“任何其他关键显示寄存器'DB CR、低频、CR、低频,“RTC寄存器:”,0 alm_banner: DB CR,低频,“报警寄存器:”,0 new_banner: DB CR,低频、CR、低频,输入新的报警寄存器设置:,0 set_banner: DB CR,低频,进入新的时间:,0 ss_banner: DB CR,低频,次秒级:,0 s_banner: DB CR,低频,第二:,0 m_banner: DB CR,低频,“分钟:”,0 h_banner:DB CR, LF, 'Hour: ', 0DW_BANNER: DB CR, LF, 'Day of Week: ', 0DC_BANNER: DB CR, LF, 'Day Count: ', 0DW_STRING: DB 'Disabled ',0,'Sunday ',0,'Monday ',0,'Tuesday ', 0DB 'Wednesday',0,'Thursday ',0,'Friday ',0,'Saturday ',0;初始化部分。启动:MOV SP, #80h;Set RXD0, TXD0 &INT1作为输入。将报警寄存器初始化为已知值。MOV RTAS, #00hMOV RTASS, #00hMOV TA, #0AAh;MOV TA, #55hMOV RTCC, #01hMOV SCON0, #050h;设置串口0为模式1,除以12。MOV TH1, #0FEh;定时器1值为28800波特,11.0592MHz。MOV TMOD, #20h;设置定时器1为8位自动加载并启动。设置SMOD位以获得28800波特。启用RTC中断。SETB EALJMP TELL_TIME,显示时间 .;***************************************************************************; 这是主程序循环。 在串口0,等待一个角色,然后采取适当的措施 .;*************************************************************************** CHAR_TEST: JNB RI0美元;等待传入命令字符。测试一下,看看该怎么做。check: CJNE A, #'T', check;T -设置时间。LJMP SET_TIMECHECKA: CJNE A, #'A', TT_JUMP;A -设置闹钟。LJMP SET_ALARMTT_JUMP: LJMP TELL_TIME;其他显示时间 .;***************************************************************************; SET_TIME设置当前时间 .;*************************************************************************** SET_TIME: MOV焦度,# SET_BANNER;显示设定时间横幅。CALL OUT_STRINGMOV DPTR, #H_BANNER;保存临时副本。确保星期几位为0。MOV R4, MOV DPTR, #M_BANNER;保存临时副本。CALL OUT_STRINGCALL IN_TIMEMOV R5, AMOV DPTR, #S_BANNER;保存临时副本。CALL OUT_STRINGCALL IN_TIMEMOV R6, AMOV DPTR, #DC_BANNER;获取日计数(2字节)&保存临时副本。CALL OUT_STRINGCALL IN_TIMEMOV R2, CALL IN_TIMEMOV R3, AMOV DPTR, #DW_BANNER;获取星期几值并将其添加到toCALL OUT_STRING;小时寄存器的上3位。调用IN_TIMESWAP, #0E0hORL A, R4XCH A, R4MOV DPTR, #NEW_LINE;我们有了所有的值,现在保存它们。MOV TA, #055h;执行一个定时访问写工具RTCC, #04h;设置新的时间&日期。CJNE A, ACC, $;延迟4个机器周期。MOV RTCSS, R7MOV RTCS, R6MOV RTCM, R5MOV RTCH, R4MOV RTCD0, R3MOV RTCD1, R2MOV TA, # 0aaah;清除RTCWE位防止意外MOV TA, #055h;时间寄存器的更改。退火RTCC # 0 fbhljmp CHAR_TEST;返回,等待另一个事件 .;***************************************************************************; TELL_TIME显示当前时间、报警寄存器和报警状态 .;*************************************************************************** TELL_TIME: MOV焦度,# TT_BANNER;显示当前时间。CALL OUT_STRINGCALL OUT_TIMEMOV DPTR, #ALM_BANNER;显示告警寄存器。CALL OUT_STRINGMOV R7, RTASMOV R6, RTASMOV R5, RTAMMOV R4, RTAHCALL DISP_TIMEMOV DPTR, #COMPARE;现在显示比较位。显示小时比较位。显示分钟比较位。显示第二个比较位。显示次秒比较位。ORL RTCC, #08h;设置读位停止RTC更新。CJNE A, ACC, $;延迟4个机器周期。MOV R4, RTCH;读取小时寄存器。MOV R3, RTCD0;读取日计数寄存器MOV R2, RTCD1ANL RTCC, #0F7h;清除读位重启RTC。输出一周中每一天的横幅。调用out_string;小时寄存器的上3位。MOV A, R4;星期几存储在上3位的swap A;小时寄存器。 移动到位2-0RR A;并乘以10得到locationANL A, #07h;周表在天内开始。MOV B, #0AhMUL, #DW_STRING;计算newJNC NO_INC的数据表;数据指针位置。DPHNO_INC: MOV DPL, call OUT_STRINGMOV DPTR, #DC_BANNER;输出日计数横幅。CALL OUT_STRINGMOV A, R2;发送两个寄存器的天数计数。为美观添加一个空白行。返回并等待另一个事件这个例程显示比较启用位的状态。DISP_COMP: JNB ACC.4, NO_COMP;显示小时比较位。MOV DPTR, #NOOUT_COMP: CALL OUT_STRINGRET;这个程序输出当前时间。OUT_TIME: ORL RTCC, #08h;设置读位停止RTC更新。CJNE A, ACC, $;延迟4个机器周期。抓取当前时间/日期并存储MOV R6, RTCS;他们暂时在工作寄存器中。MOV R5, RTCMMOV R4, RTCHANL RTCC, #0F7h;DISP_TIME: MOV A, R4;输出小时。ANL A, #01Fh;屏蔽掉一周中的一天位。调用OUT_DIGITMOV A, R5;输出分钟。CALL OUT_CDIGITMOV A, R6;输出秒。CALL OUT_CDIGITMOV A, R7;叫OUT_CDIGITRET ;***************************************************************************; SET_ALARM设置报警寄存器 .;*************************************************************************** SET_ALARM: CLR ERTCI;禁用RTC中断和明确flagANL RTCC, # 0跳频;在此期间,报警将;当启用正在更改时不被调用。MOV DPTR, #H_BANNERCALL OUT_STRINGCALL IN_TIME;保存临时副本。MOV ddptr, #M_BANNERCALL OUT_STRINGCALL IN_TIME;获取分钟;保存临时副本。MOV R5, ASK_SORL RTCC, #20h;启用分钟比较ask_s: MOV DPTR, #S_BANNERCALL OUT_STRINGCALL IN_TIME;保存临时副本。MOV R6, ASK_SSORL RTCC, #40h;启用秒比较ask_ss: MOV DPTR, #SS_BANNERCALL OUT_STRINGCALL IN_TIME;保存临时副本。启用次秒比较,#80h;ASK_X: MOV DPTR, #NEW_LINECALL OUT_STRINGMOV RTASS, R7;保存新的告警值。MOV RTAS, R6MOV RTAM, R5MOV RTAH, R4ANL RTCC, #0FDh;如果RTCI标志为;偶然定下的时候我们都在;操作比较位。重新启用RTC中断。LJMP CHAR_TESTQUERY: MOV DPTR, #COMPARE_QCALL OUT_STRINGJNB RI0, $CLR RI0MOV A, SBUF0CALL OUT_CHAR;#'Y', NO_ENABLE;SETB CRETNO_ENABLE: CLR C; flag.RET用户不希望比较清楚 ;******************************************************************; 输出例程 .;******************************************************************; 这个子程序输出一个ASCII字符串。字符串的起始点在DPTR中,结束字符为'0'。OUT_STRING: PUSH ACC;保存累加器。CHAR_LOOP: CLR A;为下一条指令清除累加器。从jnz中获取下一个字符;字符串,如果为0,则退出。POP ACC;恢复蓄电池。下一个字符是有效的,所以传输DPTR;它。增加数据点jmp CHAR_LOOP;到下一个位置并循环;这个子程序输出一个长冒号,表示分、秒和次秒;显示时间时。完成后,它将传递到OUT_DIGIT。OUT_CDIGIT: MOV SBUF0, #':';显示冒号。这个子程序通过串口0输出一个ASCII格式的十六进制数。做高nibbleMOVC A, #0Fh;清除未使用的nibbleMOVC A, @A+DPTR;从tableCALL OUT_CHAR中获取字符;传输字符。现在做低咬。清除未使用的nibbleMOVC A, @A+DPTR;从tableCALL OUT_CHAR中获取字符;$;;;;;;;端口并等待完成。CLR TI0RET ;******************************************************************; 输入例程 .;******************************************************************; 从串口IN_TIME需要两个十进制字符,和格式;作为十六进制数。IN_TIME:调用IN_CHAR;获取十位数字。第一个数字乘以10,保存toMUL AB;加到一位数上。获取一个数字并将其相加。添加A, B;Acc现在有十六进制值2十进制数;号码。退出。IN_CHAR: JNB RI0, $;返回字符。如果bit7 -4不是3h,则characterCJNE A, #30h, IN_CHAR;不是0-9。 换一个角色。流行ACC,恢复A.ANL # 0 fh; ACC现在包含0-9RET ;***************************************************************************; RTC_INT——这ISR通知用户发生警报,并给出;闹钟的时间 .;*************************************************************************** RTC_INT:退火RTCC # 0外籍;明确RTC中断标志。MOV DPTR, #ALARM_MSG;显示报警信息和报警时间。调用out_string_timereti返回
RTC(或任何振荡器)精度的最重要因素是振荡器晶体的特性。在设备的整个工作范围内,该设备的额定精度为每月±2分钟。通过控制设备的温度和使用稍后描述的RTC校准程序,可以获得更高的精度。该器件设计用于32.768kHz RTC晶体,负载电容(C(L))为6pF或12.5pF。不像一些晶体放大器,不需要外部负载电容器与RTC晶体。
器件产品与行业标准晶体兼容。表2显示了一些常见的32.768kHz晶体。此列表绝不是详尽无遗的,从此列表中包含或排除任何供应商都不能对客户应用中特定晶体的适用性进行评论。
制造商 | 模型 | C(左) | 包 |
爱普生水晶公司 | Mc-306 32.768k e | 6.0 pf | SMT |
Mc-306 32.768k a | 12.5 pf | SMT | |
KDS美国 | DT-26S 32.768千赫 | 6. pf | 油缸 |
DT-26S 32.768千赫 | 12.5 pf | 油缸 | |
DMX-26 32.768千赫 | 6. pf | SMT | |
DMX-26 32.768千赫 | 12.5 pf | SMT | |
AVX /京瓷 | KF-38G-12P5200 | 12.5 pf | 油缸 |
ks - 309 g - 12 - p5200 | 12.5 pf | SMT |
C(L)值对RTC的长期精度影响最大。该参数指定晶体需要“看到”其引脚以额定频率振荡的电容性负载。请注意,c (L)不是晶体本身的电容,而是振荡器电路和连接到晶体上的任何电容器的电容。使用与电路实际负载电容C(L)不同的晶体会影响振荡器的频率。一般来说,使用C(L)大于振荡器电路负载电容的晶体将导致振荡器运行速度快于晶体规定的标称频率,反之亦然。
默认模式使其与12.5pF晶体兼容,但可以通过清除RTC电容选择位X12/6 (TRIM.6)切换到6pF。虽然两种晶体类型都将保持在规定的精度范围内,但每种都有不同的优点。减少6pF晶体的损耗将使RTC晶体振荡器的功耗降低25%至50%,从而增加备用电池的寿命。然而,12.5pF晶体受噪声的影响较小,并且在较长时间内保持较高的精度。改变RTC晶体放大器的电容对连接在X1和X2引脚上的系统时钟晶体没有影响。
虽然RTC被设计为精确地在32.768kHz振荡,但器件、晶体、温度和电路板布局的变化可以产生较小的时序变化。通过调整RTC Trim寄存器(Trim;96h)中的RTC Trim位,可以稍微调整RTC电路的内部电容,以提高超过最小规定的定时精度。虽然修剪位不对应于电容或频移的绝对值,但它们提供了一个相对的调整。
请注意,在正常情况下,调整RTC修剪位是不必要的。在无电池复位时,内部电容复位为默认值,以保证指定的最小精度。如果您不需要每月超过2分钟的准确性,请跳过本节。
为了帮助用户确定RTC的真实频率,通过设置E4K位(TRIM.7),可以在P1.7引脚上获得来自32.768kHz晶体的4096Hz信号。这可以用频率计数器来测量,以确定RTC频率。不要试图测量晶体引线处RTC的频率。示波器探头的电容会扭曲晶体的工作并报告错误的值。以分钟为单位的RTC每月误差可由下式计算:
(P1.7频率- 4096.000Hz) ×(10.547)[分钟/月]
注意,这个误差是在特定的温度和电压下计算的。晶体特性随温度变化,建议设计人员在系统的预期工作条件范围内对误差进行表征。
修剪寄存器具有广泛的保护,以避免意外损坏。修整寄存器的所有位都需要一个定时访问过程来修改它们。此外,对trim寄存器的写操作必须成对完成。三个修整位中的每一个都有一个必须同时设置的补位。这是为了确保对TRIM寄存器的任何写操作都是有意的。如果将无效的位序列写入修剪位,则修剪寄存器将重置为0x100101二进制。这是无电池复位值,除了X12/6位将保持不变。TRIM位的设置不对应于电容或频率的绝对值,而仅用于提供相对调整。
要调整RTC修剪位,将设备与选定的晶体放入目标系统中,并从P1.7中移除任何长源。然后将频率计数器连接到P1.7并执行以下步骤。
执行定时访问过程
设置TRIM.7, E4K,并修改TRMx位,在同一指令中将它们的补码写入TRMx位。这将启用P1.7上的外部4096Hz信号。
记录频率
重复步骤1-3八次,直到所有修剪位的组合都被测量。
在进行了所有测量之后,最接近4096.00Hz的测量是TRMx位的最准确设置。将此值编程到TRIM寄存器中以获得最大的精度。下面提供了一个示例程序。
提供以下程序示例以帮助系统设计人员校准其RTC以获得最大精度。它演示了如何设置RTC修剪位并暂停程序以允许时间读取P1.7上的频率输出。
;***************************************************************************; 程序RTC_CALB.ASM;;这个程序配置设备的内部RTC频率;被测量。将32.768kHz RTC除以8得到的4kHz信号将在引脚P1.7上断言。设备将步进RTC修剪位的8个设置,显示端口3上修剪寄存器的当前内容。每次设置之间插入大约15秒的延迟(在25MHz时),以便有时间记录频率。要校准RTC电容,请将频率计数器连接到引脚P1.7并执行此程序。记录的频率计数器和修剪一点;设置一样在端口3所示步骤通过8可能削减设置。产生频率接近4096 hz的设置是最准确的,设置RTC的电容 .;*************************************************************************** 0 0 f9h; RTCC装备的实时时钟ControlTA装备c7h;定时访问96 h RegisterTRIM装备;RTC修剪RegisterP3 equ 0 b0h;港口3门闩;这些定义为6 pf水晶校准。TRIM0 equ 95h;第一修整位设置(6pF)TRIM1 equ 96h;第二修整位设置(6pF)TRIM2 equ 99h;第三修整位设置(6pF)TRIM3 equ 9Ah;第四修整位设置(6pF)TRIM4 equ 0A5h;第五修整位设置(6pF)TRIM5 equ 0A6h;第六修整位设置(6pF)TRIM6 equ 0A9h;第七修整位设置(6pF)TRIM7 equ 0AAh;第八修整位设置(6pF);这些定义用于12.5pF晶体校准;TRIM0 equ 0D5h;第一修整位设置(12.5pF);TRIM1 equ 0D6h;第二修整位设置(12.5pF);TRIM2 equ 0D9h;第三修剪位设置(12.5pF);TRIM3 equ 0DAh;第四修剪位设置(12.5pF);TRIM4 equ 0E5h;第五修剪位设置(12.5pF);TRIM5 equ 0E6h;第六修剪位设置(12.5pF);TRIM6 equ 0E9h;第七修剪位设置(12.5pF);TRIM7 equ 0EAh;第八修剪位设置(12.5pF);cseg at 0;复位矢量。程序开始;Start: MOV P3, #0AAh;我还活着。限时访问。MOV TA, #55hMOV RTCC, #01h;给RTC振荡器时间的延迟;热身。初始化结束。现在步骤通过所有的设置修剪位。修剪设置1LCALL NEXT_SETTINGMOV R0, #TRIM1;修剪设置2LCALL NEXT_SETTINGMOV R0, #TRIM3;修剪设置3LCALL NEXT_SETTINGMOV R0, #TRIM4;修剪设置4LCALL NEXT_SETTINGMOV R0, #TRIM5;修剪设置5LCALL NEXT_SETTINGMOV R0, #TRIM6;修剪设置6LCALL NEXT_SETTINGMOV R0, #TRIM7;修剪设置7LCALL NEXT_SETTINGMOV P3, #0FFh;我们做完了 .;***************************************************************************; NEXT_SETTING——这子例程编写新的设置RTC修剪登记,;显示端口3上的修剪寄存器的值以供参考,;和延迟一段时间给记录数据 ;*************************************************************************** NEXT_SETTING: MOV助教,# 0啊;定时访问。MOV TA, #55hMOV TRIM, R0;设置E4K和新的TRIM设置。NOPMOV P3, TRIM;修整寄存器的输出值。SEC30: MOV R3, #30;15秒延迟,25MHz晶体。SECLOOP: LCALL HALFSECDJNZ R3, SECLOOPRET ;***************************************************************************; HALFSEC——这个子程序生成一个延迟大约0.5秒;25兆赫水晶 .;*************************************************************************** HALFSEC: MOV R0, # 25外:MOV R1, # 125中产:MOV R2, # 249内部:NOPDJNZ R2, INNERDJNZ R1, MIDDLEDJNZ R0, OUTERRET
RTC的晶体输入(RTCX1, RTCX2)具有非常高的阻抗。不幸的是,这可能导致晶体的引线作为天线,将高频信号从系统的其余部分耦合到RTC电路中。这可能导致晶体振荡器信号的失真,导致额外的或缺失的时钟边。在大多数情况下,高频噪声会带来最大的问题,导致时钟跑得快。
以下程序可用于确定噪声是否是RTC不准确的原因:
启动系统并将RTC同步到一个已知的精确时钟
将V(CC)移到设备上(但保持V(BAT))
等待时间过长(24小时)
应用V(CC),读取RTC,并与已知的精确时钟进行比较
将RTC重新同步到已知的精确时钟
保持系统上电,等待步骤3中相同的时间
读取RTC并与已知的精确时钟进行比较。
上述程序允许设计人员在系统运行和关机时测量时钟的不准确性。如果时钟在开机时显得不太准确,那么最有可能的罪魁祸首是系统噪音。如果无论系统是打开还是关闭,不准确性仍然存在,那么原因很可能不是系统噪声。
由于晶体引脚非常容易受到耦合噪声的影响,因此在PCB上定位外部晶体和布线时必须小心。为了减少外界噪音对RTC的影响,现提出以下指引。
将晶体尽可能靠近RTCX1和RTCX2引脚。短走线减少杂散电容和噪声耦合。
保持使用小晶键垫和短走线到RTCX1和RTCX2引脚。更大的焊盘和更长的走线更有可能耦合来自相邻电路的噪声。
在水晶周围放置一个地面守卫环。这有助于将晶体与相邻信号隔离开来。
避免在晶体或RTCX1/RTCX2走线下方布线信号。这有助于将晶体与相邻信号隔离开来。尤其重要的是要使高频信号和器件尽可能远离晶体。
在接地保护环正下方放置一个本地接平面。这有助于将晶体与晶体下方的信号层隔离开来。
图2显示了RTC晶体、保护环和接地面的推荐位置。该图显示了4针表面贴装晶体的一个常见方向,但针的方向会因制造商和封装类型而异。
图2、例子晶体放置在PC板上
社群二维码
关注“华强商城“微信公众号
Copyright 2010-2023 hqbuy.com,Inc.All right reserved. 服务热线:400-830-6691 粤ICP备05106676号 经营许可证:粤B2-20210308