万年历数字钟及可调时钟系统.docx
- 文档编号:24842128
- 上传时间:2023-06-02
- 格式:DOCX
- 页数:46
- 大小:22.06KB
万年历数字钟及可调时钟系统.docx
《万年历数字钟及可调时钟系统.docx》由会员分享,可在线阅读,更多相关《万年历数字钟及可调时钟系统.docx(46页珍藏版)》请在冰豆网上搜索。
万年历数字钟及可调时钟系统
万年历数字钟及可调时钟系统
一、引言
万年历数字钟是一种用万年历时钟芯片实现年、月、日、时、分、秒计时,并通过单片机处理后送给显示芯片显示的装置,与机械式时钟相比具有更高的准确性和直观性,且具有更长的使用寿命。
本系统还可以扩展为可调的自动开关,对家电对用电设备进行控制,笔者在随后改制成为可调时的自动断电的供电系统.
二、原理图设计
1.单片机及其外围电路设计
复位采用X25045芯片,复位电路如图1所示。
图1复位电路设计
单片机采用贴片封装的AT89S51,晶振为11.0592MHz。
其中P1.5~P1.7为下载程序使用,电路如图2所示。
图2单片机89S51外围电路设计
2.时钟芯片电路设计
时钟芯片采用PCF8563,晶振采用32.768K,电容使用15pf。
PCF8563是PHILIPS公司推出的一款工业级内含I2C总线接口功能的具有极低功耗的多功能时钟/日历芯片。
内部时钟电路、内部振荡电路、内部低电压检测电路(1.0V)以及两线制I2C总线通讯方式,不但使外围电路及其简洁,而且也增加了芯片的可靠性。
同时每次读写数据后,内嵌的字地址寄存器会自动产生增量。
电路如图3所示。
图3时钟芯片电路设计
3.显示芯片电路设计
显示芯片采用ZLG7289,晶振为12MHz。
ZLG7289A是广州周立功单片机发展有限公司自行设计的,具有SPI串行接口功能的可同时驱动8位共阴式数码管(或64只独立LED)的智能显示驱动芯片,该芯片同时还可连接多达64键的键盘矩阵,单片即可完成LED显示﹑键盘接口的全部功能。
电路如图4所示。
图4显示芯片电路设计
4.双电源电路设计
系统采用双电源,平时使用V1=10V的外接电源,停电时使用电池,由V2输入。
电池有6节,其电压为9V。
当电池电压低于6V时,LED亮,说明电池电量不足。
电路如图5所示。
图5双电源电路设计
三、程序设计
程序开始时先对系统初始化,并设置好各种中断。
下步操作主要是对时钟芯片进行操作,首先要给时钟芯片设置初值,时钟芯片便自行计数。
此时检测是否有按键按下,按键是为了调整时钟。
有按键按下则执行按键中断程序,没有按键按下则执行下一步的操作,即取时钟芯片中的时钟值,然后送显示。
程序流程图如下。
图6总体流程图
四、源程序
#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_()
sbitzlg7289_cs=P1^1;
sbitzlg7289_clk=P2^6;
sbitzlg7289_dio=P2^7;
sbitzlg7289_key=P3^2;
sbitp07=P0^7;
sbitp06=P0^6;
sbitCS=P2^4;
sbitSCK=P2^2;
sbitSO=P2^5;
sbitSI=P2^3;
sbitp10=P1^0;
sbitSDA=P1^2;/*模拟I2C数据传送位*/
sbitSCL=P1^3;/*模拟I2C时钟控制位*/
ucharbuf[9]={0x00,0x00,0x30,0x23,0x15,0x1,0x05,0x04,0x05};
ucharbufdata,bb,date;
ucharSLA=0xA2,SUBA=0x00;
uchar*p;
ucharkeychange=0;
ucharkey=0;/*键盘值*/
bitkeyint=0;/*按键中断标志*/
bitkeyok=1;/*数据是否修改好*/
ucharnum=0;/*移位键移到哪个LED*/
voiddelay(uchari)
{
while(i--);
}
//********************TIMER1interruptprocess***************************//
timer0(void)interrupt1using1
{
TH0=0x3c;
TL0=0xb0;
RESWDI();
}
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);//发送06H写使能命令字
SCK=0;
CS=1;
zlg7289_cs=1;
}
voidWRDI(void)//写使能复位(禁止写{
{
zlg7289_cs=1;
SCK=0;
CS=0;
OUTByte(0x04);//发送04H写禁止命令字SCK=0;
CS=1;
zlg7289_cs=1;
}
voidWRSR(void)//写状态寄存器
{
WREN();
zlg7289_cs=1;
SCK=0;
CS=0;
OUTByte(0x01);//发送01H写寄存器命令字
OUTByte(0x00);//发送寄存器值BL0,BL1为0没写保护,WD0=0W01=1
//WD1=0WD1=0看门狗复位时间1.4S
SCK=0;
CS=1;
zlg7289_cs=1;
WIPCHK();//判断是否写入
}
unsignedcharRSDR(void)//读状态寄存器
{
unsignedcharTemp;
zlg7289_cs=1;
SCK=0;
CS=0;
OUTByte(0x05);//发送05H读状态寄存器命令字
Temp=INPUTByte();//读状态寄存器值
SCK=0;
CS=1;
returnTemp;;//这一个调试时没有执行,Temp的值总是0xFF;?
?
?
?
?
?
?
?
?
?
?
zlg7289_cs=1;
}
voidWIPCHK(void)//检查WIP位,判断是否写入完成
{
unsignedcharTemp,TempCyc;
for(TempCyc=0;TempCyc<50;TempCyc++)
{
Temp=RSDR();//读状态寄存器
if(Temp&0x01==0)
TempCyc=50;
}
}
//单字节指令或数据写入X25045
//在SI线上输入的数据在SCK的上升沿被锁存。
voidOUTByte(unsignedcharByte)//输出一个定节
{
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处于确定的状态
zlg7289_cs=1;
}
//单字节数据从X25045读到单片机
//数据由SCK的下降沿输出到SO线上。
unsignedcharINPUTByte(void)//输入一个字节
{
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,则最低位为1
else
Temp&=0xFE;
}
returnTemp;;//这一个调试时没有执行,Temp的值总是0
zlg7289_cs=1;
}
unsignedcharReadByte(unsignedcharADD)//读地址中的数据这里不做先导字处理,只能读00-FFH
{
unsignedcharTemp;
zlg7289_cs=1;
SCK=0;
CS=0;
SO=1;
SI=1;
OUTByte(0x3);//发送读指令03H如要支持000-FFF则要把高位地址左移3位再为03H相或
OUTByte(ADD);//发送低位地址
Temp=INPUTByte();
SCK=0;
CS=1;
returnTemp;//这一个调试时没有执行,Temp的
zlg7289_cs=1;
}
voidWriteByte(unsignedcharByte,ADD)//向地址写入数据这里同样不做先导字处理,只能写00-FFH
{
WREN();
zlg7289_cs=1;
SCK=0;
CS=0;
SO=1;
SI=1;
OUTByte(0x2);//发送写指令02H如要支持000-FFF则要把高位地址左移2位再为02H相或
OUTByte(ADD);//发送低位地址
OUTByte(Byte);//发送数据
SCK=0;
CS=1;
WIPCHK();
zlg7289_cs=1;
}
/********************************************************************
***************模拟I2C总线传输程序***********************************
********************************************************************/
bitack;/*应答标志位*/
/*******************************************************************
起动总线函数
********************************************************************/
voidStart_I2c()
{
SDA=1;/*发送起始条件的数据信号*/
_Nop();
SCL=1;
_Nop();/*起始条件建立时间大于4.7us,延时*/
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0;/*发送起始信号*/
_Nop();/*起始条件锁定时间大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0;/*钳住I2C总线,准备发送或接收数据*/
_Nop();
_Nop();
}
/*******************************************************************
结束总线函数
********************************************************************/
voidStop_I2c()
{
SDA=0;/*发送结束条件的数据信号*/
_Nop();/*发送结束条件的时钟信号*/
SCL=1;/*结束条件建立时间大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1;/*发送I2C总线结束信号*/
_Nop();
_Nop();
_Nop();
_Nop();
}
/*******************************************************************
字节数据传送函数
********************************************************************/
voidSendByte(ucharc)
{
ucharBitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++)/*要传送的数据长度为8位*/
{
if((c< elseSDA=0; _Nop(); SCL=1;/*置时钟线为高,通知被控器开始接收数据位*/ _Nop(); _Nop();/*保证时钟高电平周期大于4μs*/ _Nop(); _Nop(); _Nop(); SCL=0; } _Nop(); _Nop(); SDA=1;/*8位发送完后释放数据线,准备接收应答位*/ _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); _Nop(); if(SDA==1)ack=0; elseack=1;/*判断是否接收到应答信号*/ SCL=0; _Nop(); _Nop(); } /******************************************************************* 字节数据接收函数 ********************************************************************/ ucharRcvByte() { ucharretc; ucharBitCnt; retc=0; SDA=1;/*置数据线为输入方式*/ for(BitCnt=0;BitCnt<8;BitCnt++) { _Nop(); SCL=0;/*置时钟线为低,准备接收数据位*/ _Nop(); _Nop();/*时钟低电平周期大于4.7s*/ _Nop(); _Nop(); _Nop(); SCL=1;/*置时钟线为高使数据线上数据有效*/ _Nop(); _Nop(); retc=retc<<1; if(SDA==1)retc=retc+1;/*读数据位,接收的数据位放入retc中*/ _Nop(); _Nop(); } SCL=0; _Nop(); _Nop(); return(retc); } /******************************************************************** 应答子函数 ********************************************************************/ voidAck_I2c(bita) { if(a==0)SDA=0;/*在此发出应答或非应答信号*/ elseSDA=1; _Nop(); _Nop(); _Nop(); SCL=1; _Nop(); _Nop();/*时钟低电平周期大于4μs*/ _Nop(); _Nop(); _Nop(); SCL=0;/*清时钟线,钳住I2C总线以便继续接收*/ _Nop(); _Nop(); } /******************************************************************* 向有子地址器件发送多字节数据函数 ********************************************************************/ bitISendStr(ucharsla,ucharsuba,uchar*s) { uchari; Start_I2c();/*启动总线*/ SendByte(sla);/*发送器件地址*/ if(ack==0)return(0); SendByte(suba);/*发送器件子地址*/ if(ack==0)return(0); for(i=0;i<9;i++) { SendByte(*s);/*发送数据*/ if(ack==0)return(0); s++; } Stop_I2c();/*结束总线*/ return (1); } /******************************************************************* 向有子地址器件读取多字节数据函数 ********************************************************************/ 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程序结束***************************/ 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); 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)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 万年历 数字 可调 时钟 系统