千萬建筑資料下載 →
萬年歷數(shù)字鐘及可調(diào)時鐘系統(tǒng)
一、引言
萬年歷數(shù)字鐘是一種用萬年歷時鐘芯片實現(xiàn)年、月、日、時、分、秒計時,并通過單片機處理后送給顯示芯片顯示的裝置,與機械式時鐘相比具有更高的準確性和直觀性,且具有更長的使用壽命。本系統(tǒng)還可以擴展為可調(diào)的自動開關,對家電對用電設備進行控制,筆者在隨后改制成為可調(diào)時的自動斷電的供電系統(tǒng).
二、原理圖設計
1.單片機及其外圍電路設計
復位采用X25045芯片,復位電路如圖1
所示。
圖1復位電路設計
單片機采用貼片封裝的AT89S51,晶振為11.0592MHz。其中P1.5~P1.7為下載程序使用,電路如圖2所示。
圖2單片機89S51外圍電路設計
2.時鐘芯片電路設計
時鐘芯片采用PCF8563,晶振采用32.768K,電容使用15pf。PCF8563是PHILIPS公司推出的一款工業(yè)級內(nèi)含I2C總線接口功能的具有極低功耗的多功能時鐘/日歷芯片。內(nèi)部時鐘電路、內(nèi)部振蕩電路、內(nèi)部低電壓檢測電路(1.0V)以及兩線制I2C總線通訊方式,不但使外圍電路及其簡潔,而且也增加了芯片的可靠性。同時每次讀寫數(shù)據(jù)后,內(nèi)嵌的字地址寄存器會自動產(chǎn)生增量。電路如圖3所示。
圖3時鐘芯片電路設計
3.顯示芯片電路設計
顯示芯片采用ZLG7289,晶振為12MHz。ZLG7289A是廣州周立功單片機發(fā)展有限公司自行設計的,具有SPI串行接口功能的可同時驅(qū)動8位共陰式數(shù)碼管(或64只獨立LED)的智能顯示驅(qū)動芯片,該芯片同時還可連接多達64鍵的鍵盤矩陣,單片即可完成LED顯示﹑鍵盤接口的全部功能。電路如圖4
所示。
圖4
4.雙電源電路設計顯示芯片電路設計
系統(tǒng)采用雙電源,平時使用V1=10V的外接電源,停電時使用電池,由V2輸入。電池有6節(jié),其電壓為9V。當電池電壓低于6V時,LED亮,說明電池電量不足。電路如圖5所示。
圖5雙電源電路設計
萬年歷程序 C語言.doc下載三、程序設計
程序開始時先對系統(tǒng)初始化,并設置好各種中斷。下步操作主要是對時鐘芯片進行操作,首先要給時鐘芯片設置初值,時鐘芯片便自行計數(shù)。此時檢測是否有按鍵按下,按鍵是為了調(diào)整時鐘。有按鍵按下則執(zhí)行按鍵中斷程序,沒有按鍵按下則執(zhí)行下一步的操作,即取時鐘芯片中的時鐘值,然后送顯示。程序流程圖
如下。
圖6總體流程圖
四、源程序
<reg51.h>
<intrins.h>
<math.h>#include#include#include
#defineucharunsignedchar/*宏定義*/
#defineuintunsignedint
ucharclose_date,open_date;
voidRESWDI(void);
voidWREN(void);
voidWRDI(void);
voidWRSR(void);
unsignedcharRSDR(void);
voidWIPCHK(void);
voidOUTByte(unsignedcharByte);
unsignedcharINPUTByte(void);
unsignedcharReadByte(unsignedcharADD);
voidWriteByte(unsignedcharByte,ADD);
#define_Nop()_nop_()/*定義空指令*/sbit
sbit
sbit
sbit
sbit
sbit
sbit
sbit
sbit
sbit
sbit
sbit
sbitzlg7289_cs=P1^1;zlg7289_clk=P2^6;zlg7289_dio=P2^7;zlg7289_key=P3^2;p07=P0^7;p06=P0^6;CS=P2^4;SCK=P2^2;SO=P2^5;SI=P2^3;p10=P1^0;SDA=P1^2;SCL=P1^3;/*模擬I2C數(shù)據(jù)傳送位*//*模擬I2C時鐘控制位*/uchar
uchar
uchar
ucharbuf[9]={0x00,0x00,0x30,0x23,0x15,0x1,0x05,0x04,0x05};bufdata,bb,date;SLA=0xA2,SUBA=0x00;*p;/*接收指針*/
ucharkeychange=0;
ucharkey=0;/*鍵盤值*/
bitkeyint=0;/*按鍵中斷標志*/
bitkeyok=1;/*數(shù)據(jù)是否修改好*/
ucharnum=0;/*移位鍵移到哪個LED*/
/****延時函數(shù)****************************************/voiddelay(uchari)
{
while(i--);
}
//********************TIMER1interrupt***************************//
timer0(void)interrupt1using1{
TH0=0x3c;
TL0=0xb0;
RESWDI();
}process
voidRESWDI(void)////復位看門狗(喂狗){
zlg7289_cs=1;
CS=1;
CS=0;
CS=1;
zlg7289_cs=1;
}
voidWREN(void)//寫使能復位使用)?{
zlg7289_cs=1;
SCK=0;
CS=0;
OUTByte(0x06);//發(fā)送06H寫使能命令字SCK=0;
CS=1;
zlg7289_cs=1;
}
voidWRDI(void)//寫使能復位(禁止寫{{
zlg7289_cs=1;
SCK=0;
CS=0;
OUTByte(0x04);//發(fā)送04H寫禁止命令字SCK=0;CS=1;
zlg7289_cs=1;
}
voidWRSR(void)//寫狀態(tài)寄存器
{
WREN();
zlg7289_cs=1;
SCK=0;
CS=0;
OUTByte(0x01);//發(fā)送01H寫寄存器命令字
OUTByte(0x00);//發(fā)送寄存器值BL0,BL1為0沒寫保護,WD0=0W01=1//WD1=0WD1=0看門狗復位時間1.4S
SCK=0;
CS=1;
zlg7289_cs=1;
WIPCHK();//判斷是否寫入
}
unsignedcharRSDR(void)//讀狀態(tài)寄存器
{
unsignedcharTemp;
zlg7289_cs=1;
SCK=0;
CS=0;
OUTByte(0x05);//發(fā)送05H讀狀態(tài)寄存器命令字
Temp=INPUTByte();//讀狀態(tài)寄存器值
SCK=0;
CS=1;
returnTemp;;//這一個調(diào)試時沒有執(zhí)行,Temp的值總是0xFF;???????????zlg7289_cs=1;
}
voidWIPCHK(void)//檢查WIP位,判斷是否寫入完成
{
unsignedcharTemp,TempCyc;
for(TempCyc=0;TempCyc<50;TempCyc++)
{
Temp=RSDR();//讀狀態(tài)寄存器
if(Temp&0x01==0)
TempCyc=50;
}
}
//單字節(jié)指令或數(shù)據(jù)寫入X25045
//在SI線上輸入的數(shù)據(jù)在SCK的上升沿被鎖存。voidOUTByte(unsignedcharByte)//輸出一個定節(jié){
unsignedcharTempCyc;
zlg7289_cs=1;
for(TempCyc=0;TempCyc<8;TempCyc++)
{
SCK=0;
if(Byte&0x80)
SI=1;
else
SI=0;
SCK=1;
Byte=Byte<<1;//右移
}
SI=0;//使SI處于確定的狀態(tài)
zlg7289_cs=1;
}
//單字節(jié)數(shù)據(jù)從X25045讀到單片機
//數(shù)據(jù)由SCK的下降沿輸出到SO線上。
unsignedcharINPUTByte(void)//輸入一個字節(jié){
unsignedcharTemp=0,TempCyc;
zlg7289_cs=1;
for(TempCyc=0;TempCyc<8;TempCyc++)
{
Temp=Temp<<1;//右移
SCK=1;
SCK=0;
if(SO)
Temp=Temp|0x01;//SO為1,則最低位為1else
Temp&=0xFE;
}
returnTemp;;//這一個調(diào)試時沒有執(zhí)行,Temp的值總是0
zlg7289_cs=1;
}
unsignedcharReadByte(unsignedcharADD)//讀地址中的數(shù)據(jù)這里不做先導字處理,只能讀00-FFH
{
unsignedcharTemp;
zlg7289_cs=1;
SCK=0;
CS=0;
SO=1;
SI=1;
OUTByte(0x3);//發(fā)送讀指令03H如要支持000-FFF則要把高位地址左移3位再為03H相或
OUTByte(ADD);//發(fā)送低位地址
Temp=INPUTByte();
SCK=0;
CS=1;
returnTemp;//這一個調(diào)試時沒有執(zhí)行,Temp的
zlg7289_cs=1;
}
voidWriteByte(unsignedcharByte,ADD)//向地址寫入數(shù)據(jù)這里同樣不做先導字處理,只能寫00-FFH
{
WREN();
zlg7289_cs=1;
SCK=0;
CS=0;
SO=1;
SI=1;
OUTByte(0x2);//發(fā)送寫指令02H如要支持000-FFF則要把高位地址左移2位再為02H相或
OUTByte(ADD);//發(fā)送低位地址
OUTByte(Byte);//發(fā)送數(shù)據(jù)
SCK=0;
第11 / 32頁
CS=1;
WIPCHK();
zlg7289_cs=1;
}
/***********************************************************************************模擬I2C總線傳輸程序
***********************************
********************************************************************/bitack;/*應答標志位*/
/*******************************************************************
起動總線函數(shù)
********************************************************************/voidStart_I2c()
{
SDA=1;/*發(fā)送起始條件的數(shù)據(jù)信號*/
_Nop();
SCL=1;
_Nop();/*起始條件建立時間大于4.7us,延時*/
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0;/*發(fā)送起始信號*/
_Nop();/*起始條件鎖定時間大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0;/*鉗住I2C總線,準備發(fā)送或接收數(shù)據(jù)*/
_Nop();
_Nop();
}
/*******************************************************************
結(jié)束總線函數(shù)
********************************************************************/voidStop_I2c()
{
SDA=0;/*發(fā)送結(jié)束條件的數(shù)據(jù)信號*/
_Nop();/*發(fā)送結(jié)束條件的時鐘信號*/
SCL=1;/*結(jié)束條件建立時間大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1;/*發(fā)送I2C總線結(jié)束信號*/
_Nop();
_Nop();
_Nop();
_Nop();
}
/*******************************************************************
字節(jié)數(shù)據(jù)傳送函數(shù)
********************************************************************/voidSendByte(ucharc)
{
ucharBitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++)/*要傳送的數(shù)據(jù)長度為8位*/{
if((c<<BitCnt)&0x80)SDA=1;/*判斷發(fā)送位*/
elseSDA=0;
_Nop();
SCL=1;/*置時鐘線為高,通知被控器開始接收數(shù)據(jù)位*/_Nop();
_Nop();/*保證時鐘高電平周期大于4μs*/
_Nop();
_Nop();
_Nop();
SCL=0;
}
_Nop();
_Nop();
SDA=1;
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();/*8位發(fā)送完后釋放數(shù)據(jù)線,準備接收應答位*/
if(SDA==1)ack=0;
elseack=1;
SCL=0;
_Nop();
_Nop();
}/*判斷是否接收到應答信號*/
/*******************************************************************
字節(jié)數(shù)據(jù)接收函數(shù)
********************************************************************/ucharRcvByte()
{
ucharretc;
ucharBitCnt;
retc=0;
SDA=1;/*置數(shù)據(jù)線為輸入方式*/
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_Nop();
SCL=0;/*置時鐘線為低,準備接收數(shù)據(jù)位*/
_Nop();
_Nop();/*時鐘低電平周期大于4.7s*/
_Nop();
_Nop();
_Nop();
SCL=1;/*置時鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效*/
_Nop();
_Nop();
retc=retc<<1;
if(SDA==1)retc=retc+1;/*讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中*/_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return(retc);
}
/********************************************************************
應答子函數(shù)
********************************************************************/voidAck_I2c(bita)
{
if(a==0)SDA=0;
elseSDA=1;
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0;
_Nop();
_Nop();
}
/*******************************************************************
向有子地址器件發(fā)送多字節(jié)數(shù)據(jù)函數(shù)
********************************************************************/bitISendStr(ucharsla,ucharsuba,uchar*s)
{
uchari;
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(suba);
if(ack==0)return(0);/*啟動總線*//*發(fā)送器件地址*//*發(fā)送器件子地址*//*在此發(fā)出應答或非應答信號*//*時鐘低電平周期大于4μs*//*清時鐘線,鉗住I2C總線以便繼續(xù)接收*/
for(i=0;i<9;i++)
{
SendByte(*s);/*發(fā)送數(shù)據(jù)*/
if(ack==0)return(0);
s++;
}
Stop_I2c();/*結(jié)束總線*/
return(1);
}
/*******************************************************************
第15 / 32頁
向有子地址器件讀取多字節(jié)數(shù)據(jù)函數(shù)
********************************************************************/bitIRcvStr(ucharsla,ucharsuba,uchar*s)
{
uchari;
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(suba);
if(ack==0)return(0);
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
for(i=0;i<8;i++)
{
*s=RcvByte();
Ack_I2c(0);
s++;
}
*s=RcvByte();
Ack_I2c(1);
Stop_I2c();
return(1);
}
/**********模擬I2C程序結(jié)束***************************/
/*顯示函數(shù)*******************************************/
voiddisplay(uintdis)
{
ucharj;
zlg7289_clk=0;
delay(20);
zlg7289_cs=0;
for(j=0;j<16;j++)
{
if((dis&0x8000)==0x8000)zlg7289_dio=1;
elsezlg7289_dio=0;
delay(20);
zlg7289_clk=1;
delay(10);/*啟動總線*//*發(fā)送器件地址*//*發(fā)送器件子地址*//*發(fā)送數(shù)據(jù)*//*發(fā)送就答位*//*發(fā)送非應位*//*結(jié)束總線*/
zlg7289_clk=0;
delay(10);
dis=dis<<1;
}
zlg7289_cs=1;
delay(20);
}
voiddis_play(ucharaa)
{
uchari;
for(i=0;i<8;i++)
{
if(_crol_(aa,i)&0x80)
zlg7289_dio=1;
else
zlg7289_dio=0;
zlg7289_clk=1;
delay(10);/*延時*/
zlg7289_clk=0;
}
}
voiddisplaymonth()
{
bufdata=buf[5]&0x0f;
zlg7289_cs=0;
delay(10);
dis_play(0xc8);
delay(10);
dis_play(bufdata);/*顯示日個位*/zlg7289_cs=1;
delay(70);
bufdata=buf[5]&0x30;
bufdata=bufdata>>4;
bufdata=bufdata&0x0f;
zlg7289_cs=0;
delay(10);
dis_play(0xc9);
delay(10);
dis_play(bufdata);
zlg7289_cs=1;
delay(70);/*顯示日十位*/
bufdata=buf[7]&0x0f;zlg7289_cs=0;delay(10);
dis_play(0xca);delay(10);
dis_play(bufdata);zlg7289_cs=1;delay(70);
bufdata=buf[7]&0x10;bufdata=bufdata>>4;bufdata=bufdata&0x0f;zlg7289_cs=0;delay(10);
dis_play(0xcf);delay(10);
dis_play(bufdata);zlg7289_cs=1;delay(70);
}
voiddisplaytime(){
bufdata=buf[3]&0x0f;zlg7289_cs=0;delay(10);
dis_play(0xce);delay(10);
dis_play(bufdata);zlg7289_cs=1;delay(70);
bufdata=buf[3]&0x70;bufdata=bufdata>>4;bufdata=bufdata&0x0f;zlg7289_cs=0;delay(10);
dis_play(0xcd);delay(10);
dis_play(bufdata);zlg7289_cs=1;delay(70);
bufdata=buf[4]&0x0f;zlg7289_cs=0;/*顯示月個位*//*顯示月十位*//*顯示分個位*//*顯示分十位*/
delay(10);
dis_play(0xcc);delay(10);
dis_play(bufdata);zlg7289_cs=1;delay(70);
bufdata=buf[4]&0x30;bufdata=bufdata>>4;bufdata=bufdata&0x0f;zlg7289_cs=0;delay(10);
dis_play(0xcb);delay(10);
dis_play(bufdata);zlg7289_cs=1;delay(70);
}
voiddisplay_x5045(){
date=ReadByte(0x40);close_date=date;bufdata=date&0x0f;zlg7289_cs=0;delay(10);
dis_play(0xce);delay(10);
dis_play(bufdata);zlg7289_cs=1;delay(70);
bufdata=date&0x70;bufdata=bufdata>>4;bufdata=bufdata&0x0f;zlg7289_cs=0;delay(10);
dis_play(0xcd);delay(10);
dis_play(bufdata);zlg7289_cs=1;delay(70);
date=ReadByte(0x42);bufdata=date&0x0f;/*顯示時個位*//*顯示時十位*//*顯示分個位*//*顯示分十位*/
zlg7289_cs=0;
open_date=ReadByte(0x42);
delay(10);
dis_play(0xcc);
delay(10);
dis_play(bufdata);/*顯示時個位*/
zlg7289_cs=1;
delay(70);
bufdata=date&0x30;
bufdata=bufdata>>4;
bufdata=bufdata&0x0f;
zlg7289_cs=0;
delay(10);
dis_play(0xcb);
delay(10);
dis_play(bufdata);
zlg7289_cs=1;
delay(70);/*顯示時十位*/
}
/****************按鍵處理程序*********************///key=47:閃爍移位鍵(shift)
//key=39:+
//key=39:-
//key=31:確認鍵(ok)
voidkey_int()interrupt0/*鍵盤中斷程序*/{
keyint=1;
}
voidkeyexe()
{
uchari;
uchartemp=0;
ucharaa;
p06=1;
EX0=1;
zlg7289_cs=0;
delay(10);
dis_play(0x15);
delay(10);
for(i=0;i<8;i++)
{
temp=temp<<1;/*寫入讀鍵盤數(shù)據(jù)指令*/
aa=zlg7289_dio;//按位或
if(aa==1)//讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中temp=temp+1;
zlg7289_clk=1;
delay(10);//延時
zlg7289_clk=0;
}
zlg7289_cs=1;
key=temp;
if(key==47)//閃爍移位鍵
{
key=0;
keyok=0;
EX0=0;
if(num==8)
{
num=1;
}
else
num++;
switch(num)
{case1:{display(0x88fe);}break;
case2:{display(0x88fd);}break;
case3:{display(0x88fb);}break;
case4:{display(0x88f7);}break;
case5:{display(0x88ef);}break;
case6:{display(0x88df);}break;
case7:{display(0x88bf);}break;
case8:{display(0x887f);}break;
default:;
}
EX0=1;
}
elseif(key==39)//+
{
EX0=0;
key=0;
RESWDI();
if(num!=0)
{
keyok=0;
keychange=1;
RESWDI();
}
if(num==7)//在分個位上
{
if((buf[3]&0x0f)==0x09)buf[3]&=0xf0;else++buf[3];
EX0=1;
bufdata=buf[3]&0x0f;
zlg7289_cs=0;
delay(10);
dis_play(0xce);
delay(10);
dis_play(bufdata);/*顯示分個位*/zlg7289_cs=1;
delay(70);
RESWDI();
}
elseif(num==6)//在分十位上
{
if((buf[3]&0xf0)==0x50)buf[3]&=0x0f;elsebuf[3]+=0x10;
EX0=1;
bufdata=buf[3]&0x70;
bufdata=bufdata>>4;
bufdata=bufdata&0x0f;
zlg7289_cs=0;
delay(10);
dis_play(0xcd);
delay(10);
dis_play(bufdata);/*顯示分十位*/zlg7289_cs=1;
delay(70);
RESWDI();
}
elseif(num==5)//在小時個位上
{
if((buf[4]&0xf0)==0x20)
{
if((buf[4]&0x0f)>0x02)buf[4]&=0xf0;else++buf[4];
}
elseif((buf[4]&0x0f)==0x09)buf[4]&=0xf0;else++buf[4];
EX0=1;
久久建筑網(wǎng)m.brightonrobinsfc.com提供大量:建筑圖紙、施工方案、工程書籍、建筑論文、合同表格、標準規(guī)范、CAD圖紙等內(nèi)容。