实时时钟ISL1208的原理与应用
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
478
其中:引脚X1、X2接外部晶振输入端,可直接以32. 768kHz的晶体源驱动;Vbat接后备电源/电容,该引脚不用时接地;SDA为串行数据输入输出端;SCL为串行时钟输入端;IRQ/Fout为中断/频率输出端,可用作中断/频率输出;Vdd和GND为电源和接地端。
3. ISL1208内部结构及其工作原理
ISL1208内部结构框图如图2。由图可知,ISL1208主要包括:I2C接口控制单元、实时时钟控制逻辑、时钟分频器、电源管理单元和寄存器单元。其中寄存器单元被分成四段:实时时钟、控制与状态、报警寄存器和用户SRAM;这四段寄存器各自含有不同的功能:实时时钟和报警寄存器用于写入/读出时间值和报警值,其写入形式为BCD码;控制与状态寄存器可完成对其他寄存器读写控制、报警与频率输出控制、模拟与数字微调控制等功能,其存储映射图如表1。
控制与状态寄存器(Control and Status)
控制与状态寄存器包括状态寄存器、中断与报警寄存器、模拟微调与数字微调寄存器。
状态寄存器(SR):用来控制RTC失效、电池模式、报警触发、时钟计数器写保护、晶体振荡器使能以及状态位的自动复位或者提供相应的状态信息。在时钟上电时,需将写RTC使能位WRTC置“1”,以便
启动时钟计数。
中断控制寄存器(INT):主要用于控制时钟的周期性和单事件报警。其中频率输出控制位FO3-FO0使能/禁止频率输出功能,并选择IRQ/FOUT引脚的输出频率(2-5Hz-215Hz)。在频率模式被激活时它将覆盖IRQ/FOUT引脚上的报警模式。报警使能位ALME使能/禁止报警功能,中断/报警模式位IM使能单
周期定时事件(IM=0)/周期定时事件(IM=1)。
模拟微调寄存器(ATR):ATR0至ATR5为六位模拟微调位,可调整片内负载电容(CX1、CX2)的值,这一电容值用于RTC的频率补偿,其每一位都有不同的电容调节比重。有效的片内串联负载电容CLOA D 的范围从4.5pF至20.25pF,中间值为12.5pF(默认)。CLOAD可通过X1/X2引脚之间两个数字控制
电容器CX1和CX2调节。
数字微调寄存器(DTR):数字微调位DTR0、DTR1和DTR2用来调整每秒钟的平均计数值和平均误差以获取更好的精度。其中DTR2为符号位(DTR2=0频率补偿>0,DTR2=1频率补偿<0),DTR1和DTR 0为刻度位:DTR1提供40ppm调整,DTR0提供20ppm调整。用以上三位可以表示-60ppm至+60ppm
的补偿范围。
4. 应用举例
4.1 硬件结构
ISL1208具有I2C接口,使其便于与各类处理器连接且硬件结构十分简单,传输速率最高可达400Hz。硬件结构如图3。其中时钟输入口SCL、数据输入输出口SDA分别与AT89C51的P1.6、P1.7腿相连,中断输出口IRQ/Fout接外部中断INT0。AT89C51通过RS232口与计算机相连,通过计算机对实时时钟产生
控制。Vbat引脚接后备电容器。
4.2 软件设计
由于ISL1208为I2C接口,因此其接口协议也满足I2C规范,这里不再累述。需要提到一点是:在每次访问寄存器时,应先输入一个有效的辨识字节。该字节高7位(1101111)为器件辨识符。辨识字节的最后一位定义进行读/写操作,当其为“1”时选择读,为“0”时选择写。图4为ISL1208读/写时序图。
图4 读/写ISL1208
对于ISL1208来说,由于其内部结构设计,可以很容易的实现2nHz中断输出和每分、每天至每年一次报警,但要求具体几分钟、几小时报警一次还需在程序的编制上要比较注意。以下程序为通过计算机、单片机来控制ISL1208每5秒钟产生一次中断程序,上位机程序由MATLAB编写[4],单片机程序由C语言编
写,由于篇幅有限仅列出部分单片机程序:
#include
#define ISLwr 0xde /*写辨识字节*/
#define ISLrd 0xdf /*读辨识字节*/
/*--------ISL1208管脚配置---------*/
sbit ISLSCL=P1^6; /*时钟*/
sbit ISLSDA=P1^7; /*数据*/
void sdelay(); /*短延时*/
void ISLstart(); /*I2C起始位*/
void ISLstop(); /*I2C停止位*/ void GetACK(); /*主机等待应答(GACK)*/
void OutACK(); /*主机应答(OACK)*/
/*--------读/写ISL1208函数--------*/
unsigned char readISL1208();
void writeISL1208(unsigned char datas);
/*-----------读/写寄存器-------------*/
void writeREG(unsigned char adds,unsigned char datas);
unsigned char readREG(unsigned char adds);
bit flag=0; /*启动时钟报警标志位*/
unsigned char alarm=0; /*报警时间参数*/
main()
{ ………………../*初始化*/
for(;;) /*等待上位机发送命令*/
{ if(flag = =1)
break; }
/*写状态寄存器,写RTC使能,报警自动复位*/
writeREG(0x07,0x90);
/*写中断寄存器,单事件报警,中断使能*/
writeREG(0x08,0x60);
/*写报警寄存器,报警使能*/
writeREG(0x0c,0x81);
/*写时钟寄存器,启动RTC*/
writeREG(0x00,0x00);