DS12C887時鐘日歷芯片,是由美國 DALLAS公司生產(chǎn)的新型時鐘日歷芯片,采用CMOS技術(shù)制成。芯片采用24引腳雙列直插式封裝,內(nèi)部集成晶振、振蕩電路、充電電路和可充電鋰電池,組 成一個加厚的集成電路模塊,在沒有外部電源的情況下可工作10年。具有良好的微機(jī)接口、精度高、外圍接口簡單、工作穩(wěn)定可靠等優(yōu)點,可廣泛使用于各種需要 較高精度的實時場合。
一、器件特性
·可計算到2100年前的秒、分、小時、星期、日期、月、年七種日歷信息并帶閏年補(bǔ)償;
·自帶晶體振蕩器和鋰電池。在沒有外部電源的情況下可工作10年;
·對于一天內(nèi)的時間記錄,有12小時制和24小時制兩種模式。在12小時制模式中,用AM和PM區(qū)分上午和下午;
·可選用夏令時模式
·時間表示方法有兩種:一種用二進(jìn)制數(shù)表示,一種用BCD碼表示;
·DS12C887中帶有128字節(jié)RAM,其中11字節(jié)用來存儲時間信息,4字節(jié)RAM用來存儲DS12C887的控制信息,稱為控制寄存器,113字節(jié)RAM供用戶使用;
·數(shù)據(jù)/地址總線復(fù)用
·用戶可編程以實現(xiàn)多種方波輸出
·可應(yīng)用于MOTOROLA和INTEL兩種種線?!疫@里只闡述INTEL總線實現(xiàn)方法
·三種可編程中斷:定鬧中斷、時鐘更新結(jié)束中斷、周期性中斷
DS12C887各引腳的功能說明
GND、VCC:直流電源,其中VCC接+5V輸入,GND接地。
當(dāng)VCC輸入為+5V時,用戶可以訪問DS12C887內(nèi)RAM中的數(shù)據(jù),并可對其進(jìn)行讀、寫操作;
當(dāng)VCC輸入小于+4.25V時,禁止用戶對內(nèi)部RAM進(jìn)行讀、寫操作,此時用戶不能正確獲取芯片內(nèi)的時間信息;
當(dāng)VCC輸入小于+3V時,DS12C887會自動將電源切換到內(nèi)部自帶的鋰電池上,以保證內(nèi)部的電路能夠正常工作。
MOT:模式選擇引腳
DS12C887有兩種工作模式,即Motorola模式和Intel模式。
當(dāng)MOT接VCC時,選用的工作模式是Motorola模式;
當(dāng)MOT接GND或不接時,選用的是Intel模式。本文主要討論Intel模式。
SQW:方波輸出引腳
當(dāng)供電電壓VCC大于4.25V時,SQW引腳可進(jìn)行方波輸出,此時用戶可以通過對控制寄存器編程來得到13種方波信號的輸出。
AD0~AD7:復(fù)用地址/數(shù)據(jù)總線
該總線采用時分復(fù)用技術(shù),在總線周期的前半部分,出現(xiàn)在AD0~AD7上的是地址信息,可用以選通DS12C887內(nèi)的RAM;總線周期的后半部分出現(xiàn)在AD0~AD7上的是數(shù)據(jù)信息。
AS:地址選通輸入引腳
在進(jìn)行讀寫操作時,AS的上升沿將AD0~AD7上出現(xiàn)的地址信息鎖存到DS12C887上,而下一個下降沿清除AD0~AD7上的地址信息,不論是否有效,DS12C887都將執(zhí)行該操作。
DS/RD:數(shù)據(jù)選擇或讀輸入引腳
該引腳有兩種工作模式:
Motorola工作模式中,每個總線周期的后一部分的DS為高電平,被稱為數(shù)據(jù)選通。在讀操作中,DS的上升沿使DS12C887將內(nèi)部數(shù)據(jù)送往總線AD0~AD7上,以供外部讀取。在寫操作中,DS的下降沿將使總線 AD0~AD7上的數(shù)據(jù)鎖存在DS12C887中;
Intel工作模式中,DS被稱作RD。該引腳是讀允許輸入腳,即Read Enable。是讀(RD)信號輸入端。當(dāng)他有效時表示DS12C887正往總線輸出數(shù)據(jù)。RD信號線在存儲器芯片上被稱作OE信號線。
R/W:讀/寫輸入端
該引腳也有2種工作模式:
Motorola工作模式中,該引腳的作用是區(qū)分進(jìn)行的是讀操作還是寫操作,當(dāng)R/W為高電平時為讀操作,R/W為低電平時為寫操作;
Intel工作模式中,此時該作為寫允許輸入,即Write Enable。是寫(WR)信號輸入端。
CS:片選輸入,低電平有效。
IRQ:中斷請求輸入,低電平有效,該引腳有效對DS12C887內(nèi)的時鐘、日歷和RAM中的內(nèi)容沒有任何影響,僅對內(nèi)部的控制寄存器有影響,在典型的應(yīng)用中,RESET可以直接接VCC,這樣可以保證DS12C887在掉電時,其內(nèi)部控制寄存器不受影響。
RESET:復(fù)位端
在典型的應(yīng)用中,RESET直接接VCC
NC:空引腳
下面講解一下DS12C887的控制和狀態(tài)寄存器。
DS12C887有四個控制和狀態(tài)寄存器:A、B、C、D
寄存器A
更新位UIP:用來標(biāo)志芯片是否即將進(jìn)行更新。
當(dāng)UIP位為1時,表示芯片正處于更新周期或即將開始更新周期。此時不準(zhǔn)讀/寫時標(biāo)寄存器;
當(dāng)它為0時,表示在至少244us后才開始更新周期(即在這244us內(nèi),芯片不會更新)。此時,時鐘、日歷和鬧鐘信息可以通過讀寫相應(yīng)的字節(jié)獲得和設(shè)置。
UIP位為只讀位且不受復(fù)位信號(RESET)的影響。通過把寄存器B中的SET位設(shè)置為1,可以禁止更新并將UIP位清0。
大頭爸爸:因此,在讀/寫前應(yīng)該檢測UIP位。比如在1602液晶上顯示秒
while(從DS12C887讀(0x0A)&0x80);//這句意思就是如果UIP位為1,則等待。為0則退出
秒值=從DS12C887讀(0)//讀秒數(shù)據(jù)
向1602寫入秒值
DV0,DV1,DV2
這3位是用來開關(guān)晶體振蕩器和復(fù)位分頻器。
當(dāng)[DV0 DV1 DV2]=[010]時,晶體振蕩器開啟并且保持時鐘運行;
當(dāng)[DV0 DV1 DV2]=[01X]時,晶體振蕩器開啟,但分頻器保持復(fù)位狀態(tài)。<---不太明白,如果設(shè)置01X時,有什么作用呢?
RS3,RS2,RS1,RS0
作用:
1、設(shè)置周期中斷允許位(PIE);
2、設(shè)置方波輸出允許位(SQWE);
3、兩位同時設(shè)置為有效并且設(shè)置頻率;
4、全部禁止。
下表列出了可通過RS寄存器選擇的周期中斷的頻率和方波的頻率。這四個可讀寫的位不受復(fù)位信號的影響。
寄存器B
SET:當(dāng)該位為0時,芯片處于正常工作狀態(tài),每秒產(chǎn)生一個更新周期來更新時標(biāo)寄存器;該位為1時,芯片停止工作,程序在此期間可初始化芯片的各個時標(biāo)寄存器。
SET位可讀寫,并不會受到復(fù)位信號的影響。
PIE——周期中斷
當(dāng)PIE=0:禁止周期中斷輸出到IRQ;
當(dāng)PIE=1:允許周期中斷輸出到IRQ。
AIE——鬧鐘中斷
當(dāng)AIE=0:禁止鬧鐘中斷輸出到IRQ;
當(dāng)AIE=1:允許鬧鐘中斷輸出到IRQ。
UIE——更新結(jié)束中斷
當(dāng)UIE=0:禁止更新結(jié)束中斷輸出到IRQ;
當(dāng)UIE=1:允許更新結(jié)束中斷輸出到IRQ。
此位在復(fù)位或設(shè)置SET為高時清0
SQWE——方波輸出允許位
當(dāng)SQWE=0:SQW腳保持低電平;
當(dāng)SQWE=1:按寄存器A輸出 速率選擇位 所確定的頻率方波。
DM——格式選擇位
DM=0:BCD格式;
DM=1:二進(jìn)制格式。
此位不受復(fù)位信號影響
24/12——小時模式設(shè)置位
為1—24小時制;為0—12小時制
DSE——夏令時允許標(biāo)志
DSE=1,夏令制設(shè)置有效,夏時制結(jié)束可自動刷新恢復(fù)時間;DES=0,無效。
夏令時:在四月的第一個星期日的1:59:59AM,時鐘調(diào)到3:00:00AM;在十用的最后一個星期日的1:59:59AM,時鐘調(diào)到1:00:00AM。
寄存器C
該寄存器的特點是:程序訪問該寄存器或復(fù)位后,該寄存器的內(nèi)容將自動清0,從而使IRQF標(biāo)志位變?yōu)楦唠娖剑ù箢^爸爸:是低電平吧?不理解這句),否則,芯片將無法向CPU申請下一次中斷。
2010-5-14 16:18 上次將本文章打印出來,昨晚在看一遍時,對上面紅色部分重新理解內(nèi)容如下:
IRQF為高電平時,引腳變?yōu)榈碗娖揭鹬袛嗌暾?。假設(shè),我開放鬧鐘中斷,寄存器B中的AIE需要置 1,當(dāng) 當(dāng)前時間與所設(shè)置的鬧鐘時間吻合時,寄存器C中的AF位被硬件置1(詳見下面的:更新周期的基本功能),此時根據(jù)IRQF的邏輯表達(dá) 式:IRQF=PF·PIE+AF·AIE+UF·UIE可得知:IRQF的值為1,當(dāng)IRQF位變?yōu)?時,引腳變?yōu)榈碗娖揭鹬袛嗌暾垼ㄈ绻捎猛獠恐袛?,則初始化時使IT1=1,通過他的下降沿來引起中斷)。
在中斷申請中,要讀一次寄存器C,目的就是使寄存器C中的內(nèi)容自動清0。IRQF為0,則不再引起中斷申請。目的就是使下一次鬧鐘時間與當(dāng)前時間符合時,可以再次申請中斷。
另一個理解:如果在中斷服務(wù)程序中不讀寄存器C,即,不使寄存器C中的各位清0的話,那么就會不斷的申請中斷。因為IRQF值為1?!疫@個理解未做測試,以后將測試結(jié)果放上。
IRQF:中斷申請標(biāo)志位。該位的邏輯表達(dá)式為:IRQF=PF·PIE+AF·AIE+UF·UIE。當(dāng)IRQF位變?yōu)?時,引腳變?yōu)榈碗娖揭鹬袛嗌暾垺?/p>
在有以下情況中的一種或幾種發(fā)生時,中斷請求標(biāo)志位IRQF置高:
PF=PIE=1
AF=AIE=1
UF=UIE=1
IRQF=PF·PIE+AF·AIE+UF·UIE
IRQF一旦為高,IRQ引腳輸出低。
PF:周期中斷標(biāo)志位。
AF:鬧鐘中斷標(biāo)志位。
UF:更新周期結(jié)束中斷標(biāo)志位。
寄存器C的低三位:未定義的保留位。不能寫入,讀出值始終為0。
寄存器D
寄存器D為只讀寄存器。
當(dāng)VRT=0時表示內(nèi)置電池能量耗盡,此時RAM中的數(shù)據(jù)正確性無法保證。低6位無用,只讀,讀出值恒為0。
DS12C887的中斷和更新周期
DS12C887處于正常工作狀態(tài)時,每秒鐘將產(chǎn)生一個更新周期。芯片片于更新周期的標(biāo)志是寄存器A中的UIP位為1。在更新周期內(nèi),芯片內(nèi)部時標(biāo)寄存器的數(shù)據(jù)處于更新階段。所以,在這個階段微處理器不能讀時標(biāo)寄存器的內(nèi)容,否則將得到不確定數(shù)據(jù)。
更新周期的基本功能主要是:
1、刷新各個時標(biāo)寄存器中的內(nèi)容,同時秒時標(biāo)寄存器內(nèi)容加1,并檢查其他時標(biāo)寄存器內(nèi)容是否有溢出,如果有溢出則相應(yīng)進(jìn)位分、時、日、月、年。
2、檢查3個——時、分、秒鬧鐘時標(biāo)寄存器的內(nèi)容是否與對應(yīng)時標(biāo)寄存器的內(nèi)容相符。如果相符,則寄存器C中的AF位置1;如果鬧鐘時標(biāo)寄存器的內(nèi)容為C0H~FFH之間數(shù)據(jù),則為不關(guān)心狀態(tài)。
那什么是不關(guān)心狀態(tài)?設(shè)置鬧鐘時標(biāo)寄存器為不關(guān)心狀態(tài)有什么作用呢?
DS12C887共有三個鬧鐘單元,分別為時、分、秒鬧鐘單元。在其中寫入鬧鐘時間值并且在時鐘中斷允許的情況下,每天到該時刻就會產(chǎn)生中斷申請信 號。但這種方式每天只提供一次中斷信號。如果每小時都產(chǎn)生中斷申請信號,或每分鐘產(chǎn)生中斷申請信號怎么辦呢?這時就要用到“不關(guān)心碼”,即:
在“時鬧鐘”單元寫入C0H~FFH之間數(shù)據(jù),可每小時產(chǎn)生一次中斷;
在“時鬧鐘”單元和“分鬧鐘”單元寫入C0H~FFH之間數(shù)據(jù),可每分鐘產(chǎn)生一次中斷。
在“時鬧鐘”單元、“分鬧鐘”單元和“秒鬧鐘”單元都寫入C0H~FFH之間數(shù)據(jù),則每秒產(chǎn)生一次中斷。
但 這種方式也只能在整點、整分或每秒產(chǎn)生一次中斷。若控制系統(tǒng)要求的定時間隔不是整數(shù)時,應(yīng)該通過軟件來調(diào)整實現(xiàn)。比如每3分鐘實現(xiàn)一次中斷。大頭爸爸:在 “時鬧鐘”單元寫入C0H~FFH之間數(shù)據(jù),在“分鬧鐘”單元寫入3,在“秒鬧鐘”單元寫入C0H~FFH之間數(shù)據(jù)即可。
下面在講講關(guān)于DS12C887的初始化
DS12C887采用連續(xù)工作制,一般無需每次都初始化,即使是系統(tǒng)復(fù)位時也是如此。一般是新產(chǎn)品買回來,第一次使用的時候初始化;或者你想要初始化的時候。那么如何初始化DS12C887呢?
1、首先應(yīng)禁止芯片內(nèi)部的更新周期操作。所以應(yīng)先將DS12C887狀態(tài)寄存器B中的SET位置1。
2、然后初始化00H到09H時標(biāo)參數(shù)寄存器的值和狀態(tài)寄存器A
3、再通過讀狀態(tài)寄存器C,清除寄存器C中的周期中斷標(biāo)志位PF、鬧鐘中斷標(biāo)志位AF、更新周期結(jié)束中斷標(biāo)志位UF。
4、《新編MCS-51單片機(jī)應(yīng)用設(shè)計》一書,在第4步,還需通過讀取寄存器D。(讀寄存器D后,VRT位自動置1)——他所針對的是DS12887。關(guān)于這個內(nèi)容,以后確定在補(bǔ)充。
5、將狀態(tài)寄存器B中的SET位置0,芯片開始計時工作。
下面是關(guān)于DS12C887讀/寫時序
下面是關(guān)于DS12C887的操作函數(shù)
//向某地址寫數(shù)據(jù)
void DS12C887_Write(uint8 _address,uint8 _data)
{
DS12C887_CS=0;
DS12C887_DS=1;
DS12C887_WR=1;
DS12C887_AS=1;
P0=_address;
DS12C887_AS=0;
DS12C887_WR=0;
P0=_data;
DS12C887_WR=1;
DS12C887_AS=1;
DS12C887_CS=1;
}
//讀某地址的數(shù)據(jù)
uint8 DS12C887_Read(uint8 _address)
{
uint8 tmpData;
DS12C887_CS=0;
DS12C887_AS=1;
DS12C887_DS=1;
DS12C887_WR=1;
P0=_address;
DS12C887_AS=0;
DS12C887_DS=0;
P0=0xff;//單片機(jī)從I/O口讀取數(shù)據(jù)之前先給I/O口賦個高。
tmpData=P0;
DS12C887_DS=1;
DS12C887_AS=1;
DS12C887_CS=1;
return(tmpData);
}
附:下面是通過xbyte操作DS12C887的方法,可學(xué)習(xí)并吸收掌握。
其中DS12C887的基地址為7F00H,相應(yīng)的程序采用C51語言編寫(以Intel工作模式為例)。
由8031單片機(jī)和DS12C887構(gòu)成的時間獲取電路的初始化程序如下:
XBYTE[0x7F00+0x0B]=0x82;
XBYTE[0x7F00+0x0A]=0xA0;
XBYTE[0x7F00+0x0A]=0x20;
XBYTE[0x7F00+0x0B]=0x02;
/*所有的中斷禁止,24小時制,BCD碼模式*/
以下均獲取時間程序:
unsigned char data t-century;
unsigned char data t-year;
unsigned char data t-month;
unsigned char data t-date;
unsigned char data t-week;
unsigned char data t-hour;
unsigned char data t-minute;
unsigned char data t-second;
if((XBYTE[7F00+0x0A]&0x80)!=0){
t-century=XBYTE[0x7F00+0x32];/*讀取世紀(jì)*/
t-year=XBYTE[Ox7F00+0x09];/*讀取年份*/
t-month=XBYTE[Ox7F00+0x08];/*讀取月份*/
t-date=XBYTE[Ox7F00+0x07];/*讀取日期*/
t-week=XBYTE[Ox7F00+0x06];/*讀取星期幾*/
t-hour=XBYTE[Ox7F00+0x04];/*讀取小時*/
t-minute=XBYTE[DS12887+0x02];/*讀取分鐘*/
t-second=XBYTE[Ox7F00+0x00];}/*讀取秒*/
在網(wǎng)上獲得的另一段代碼:
需要的,仔細(xì)看看資料,一般包括以下幾個方面
//硬件地址p2.7接12887的cs
#define p12887_sec xbyte[0x7f00]
#define p12887_asec xbyte[0x7f01]
#define p12887_min xbyte[0x7f02]
#define p12887_amin xbyte[0x7f03]
#define p12887_hour xbyte[0x7f04]
#define p12887_ahour xbyte[0x7f05]
#define p12887_week xbyte[0x7f06]
#define p12887_day xbyte[0x7f07]
#define p12887_month xbyte[0x7f08]
#define p12887_year xbyte[0x7f09]
#define p12887_cona xbyte[0x7f0a]
#define p12887_conb xbyte[0x7f0b]
#define p12887_irqf xbyte[0x7f0c]
#define p12887_vf xbyte[0x7f0d]
//初始化操作
void start12887(void)//啟動時鐘
{
u_char i;
i=p12887_vf;
p12887_cona=0x70;// 掛起時鐘
p12887_conb=0x86;// noupdate,all int disable, bin,24,normal time
p12887_conb=0x06;// update
p12887_cona=0x20;// start
i=p12887_irqf;
}
下面是從網(wǎng)絡(luò)上找到的,某網(wǎng)友對xbyte用法的疑問及某網(wǎng)友回復(fù),借鑒:
提問:
在一般的讀寫外部RAM的程序中,經(jīng)常看到這樣的句子:
XBYTE[address]=data 寫數(shù)據(jù)
data=XBYTE[address] 讀數(shù)據(jù)
但是我想問的是,為什么用了XBYTE后,就不用顧及其時序了呢?
就是說,讀寫數(shù)據(jù)的時候,WR和RD怎么都不用用程序去控制了呢?
參考了很多讀寫外部RAM的程序,都找不到其控制WR和RD控制線的語句
哪位大俠能幫忙解釋一下這是為什么嘛?
最好還能說說XBYTE具體的用法.....
回答:
在ABSACC中你看一下就明白了
#define CBYTE ((unsigned char volatile code *) 0)
#define DBYTE ((unsigned char volatile data *) 0)
#define PBYTE ((unsigned char volatile pdata *) 0)
#define XBYTE ((unsigned char volatile xdata *) 0)
XBYTE [address]=data;
相當(dāng)于
unsigned char xdata *p;
p=address;
*p=data;
但是用XBYTE會節(jié)省一個指針變量的R