/*===================================
/--------------------------------------
項目名稱(chēng):89s52+ds1302電子鐘
功能說(shuō)明:6位數碼管顯示-時(shí)--分--秒,約30秒鐘。然后顯示星期--月--年約10秒鐘
設置說(shuō)明:
P0--段,P2--位(p2.5為個(gè)位),自帶充電功能(470UF電容作為電源)
作者:朱世民
說(shuō)明:通過(guò)實(shí)驗板驗證通過(guò)
時(shí)間:2010.2.11
==========================================*/
#include "reg51.h"
#include "ds1302.h" //自建庫文件
//unsigned char code tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
// 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
//0~~9段碼 abcdefgh,共陽(yáng)
unsigned char code tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x77,0x7C,0x39,0x80,0x79,0xC0};
// 師大版顯示代碼
/*************************ds1302與at89s52引腳連接********************/
sbit k1=P1^0; //調時(shí)分秒按鍵(移位)
sbit k2=P1^1; //加1按鍵
sbit k3=P1^3; //調星期,月,日,按鍵(移位)
sbit k4=P1^4; //加1按鍵
sbit flag=P3^1; //秒顯標志(板上接p3.1)
unsigned char k,ks;
unsigned char time[6]; //秒,分,時(shí)寄存器初始值
/***********************顯示程序**********************************************/
/* 動(dòng)態(tài)掃描條件(單個(gè)LED在1秒內): count >=50次 //點(diǎn)亮次數 */
/* */
/* DS1302秒,分,時(shí)寄存器是BCD碼形式: 用16求商和余進(jìn)行"高4位"和"低4位"分離 */
/* 0xdf,0xef,0xf7,0xfb,0xfd,0xfe : 位選 */
/****************************************************************************/
void disp()//
{ unsigned char m; //m為緩沖;
m=time[0]; //把
P0=tab[m%16]; //取秒低4位BCD碼
P2=0xdf; //顯示秒(個(gè)位);
delay(500); //持續2ms
P2=0xff; //消影
P0=tab[m/16]; //取高4位BCD碼:顯示秒(十位);
P2=0xef;
delay(500);
P2=0xff;
m=time[1]; //把分--送緩存
P0=tab[m%16]; //第3個(gè)數碼管:顯示分(個(gè)位)
P2=0xf7;
delay(500);
P2=0xff;
P0=tab[m/16]; //第4個(gè)數碼管:顯示分(十位)
P2=0xfb;
delay(500);
P2=0xff;
m=time[2]; //把時(shí)--送緩存
P0=tab[m%16]; //第5個(gè)數碼管:顯示時(shí)(個(gè)位)
P2=0xfd;
delay(500);
P2=0xff;
P0=tab[m/16]; //第6個(gè)數碼管:顯示時(shí)(十位)
P2=0xfe;
delay(500);
P2=0xff;
}
//==============
//顯示星期---月---日
void disp2()
{ unsigned char m; //m為緩沖;
m=time[3]; //把日
P0=tab[m%16]; //取秒低4位BCD碼
P2=0xdf; //顯示秒(個(gè)位);
delay(500); //持續2ms
P2=0xff; //消影
P0=tab[m/16]; //取高4位BCD碼:顯示秒(十位);
P2=0xef;
delay(500);
P2=0xff;
m=time[4]; //把月--送緩存
P0=tab[m%16]; //第3個(gè)數碼管:顯示分(個(gè)位)
P2=0xf7;
delay(500);
P2=0xff;
m=m/16;
if(m==0) m=13;//若十位為0,關(guān)閉顯示 0x80
P0=tab[m]; //第4個(gè)數碼管:顯示分(十位)
P2=0xfb;
delay(500);
P2=0xff;
m=time[5]; //把星期--送緩存
P0=tab[15]; //第5個(gè)數碼管:顯示時(shí)(個(gè)位)
P2=0xfd;
delay(500);
P2=0xff;
P0=tab[m%16]; //第6個(gè)數碼管:顯示時(shí)(十位)
P2=0xfe;
delay(500);
P2=0xff;
}
//========初始化
void Write_time()
{ unsigned char i,addr;
addr=0x80;
write_1302(0x8e,0x00); //WP=0 寫(xiě)操作
for(i=0;i<6;i++)
{
write_1302(addr,time[i]);
addr+=2;
}
write_1302(0x8e,0x80); //WP=1 寫(xiě)保護
}
//===================================
void testk1()
{k1=1;
if(!k1)//
{disp();//延時(shí)去抖
if(!k1)//
{while(!k1)disp();//等待松開(kāi)
if(++k>6)k=0; //移位標志,只調
}
}
}
//=======加一鍵=================
void testk2()
{ unsigned char n,buf;
k2=1;
if(!k2)
{disp();disp();disp();
if(!k2)
do //按鍵沒(méi)有松開(kāi),連續加
{disp();disp();disp();
switch(k)
{case 6:buf=time[0];//
buf&=0xf0; //保留高四位;
if(++n>9)n=0; //加數
time[0]=buf|n;break;//秒的個(gè)wei加一
case 5:buf=time[0]; buf&=0x0f; if(++n>5)n=0; time[0]=buf+n*16;break;//分的十位加1
case 4:buf=time[1]; buf&=0xf0; if(++n>9)n=0; time[1]=buf|n;break;//分的個(gè)wei加一
case 3:buf=time[1]; buf&=0x0f; if(++n>5)n=0; time[1]=buf+n*16;break;//分的十位加1
case 2:buf=time[2];buf&=0xf0; if(++n>9)n=0; time[2]=buf|n;break;//時(shí)的個(gè)位加一
case 1:buf=time[2];buf&=0x0f; if(++n>2)n=0; time[2]=buf+n*16; break;//
//時(shí)十位加1
default:break;
}
disp();disp();disp();
}
while(!k2);//直到按鍵松開(kāi)
Write_time(); //寫(xiě)進(jìn)1302去
}
}
//==========
void testk3()
{k3=1;
if(!k3)//
{disp2();//延時(shí)去抖
if(!k3)//
{while(!k3)disp2();//等待松開(kāi)
if(++ks>5)ks=0; //移位標志,只調
}
}
}
//=======加一鍵=================
void testk4()
{ unsigned char n,buf;
k4=1;
if(!k4)
{disp2();disp2();
if(!k4)
do //按鍵沒(méi)有松開(kāi),連續加
{disp2();disp2();disp2();
switch(ks)
{case 5:buf=time[3];//
buf&=0xf0; //保留高四位;
if(++n>9)n=0; //加數
time[3]=buf|n;break;//秒的個(gè)wei加一
case 4:buf=time[3]; buf&=0x0f; if(++n>3)n=0; time[3]=buf+n*16;break;//分的十位加1
case 3:buf=time[4]; buf&=0xf0; if(++n>9)n=0; time[4]=buf|n;break;//分的個(gè)wei加一
case 2:buf=time[4]; buf&=0x0f; if(++n>1)n=0; time[4]=buf+n*16;break;//分的十位加1
case 1:buf=time[5];buf&=0xf0; if(++n>7)n=1; time[5]=buf|n;break;//時(shí)的個(gè)位加一
//時(shí)十位加1
default:break;
}
disp2();disp2();
}
while(!k4);//直到按鍵松開(kāi)
Write_time(); //寫(xiě)進(jìn)1302去
}
}
/************************主程序**********************************************/
void main(void)
{ unsigned char i,addr,s,n;
k=0,ks=0;
write_1302(0x8e,0x00); //WP=0 寫(xiě)操作
write_1302(0x90,0xa5); // 開(kāi)涓流充電
write_1302(0x8e,0x80); //WP=1 寫(xiě)保護
write_1302(0x80,0x00);
while(1)
{
testk1(); //調時(shí)移位鍵k=1,2,3,4分別分個(gè)、十,時(shí)個(gè),十
while(k!=0) //若進(jìn)入調節
{ testk2();disp();testk1(); }//調時(shí)間
{ //否則取數,顯示
for(n=0;n<100;n++)
{ addr=0x81;
for(i=0;i<3;i++)
{
time[i]=read_1302(addr);// 讀出時(shí)間
disp(); //星期,月,日
addr+=2;//地址加2
}
if(time[0]!=s) // 讀出秒,和上次比較不等
{flag=!flag;//秒閃指示(變化一次閃一次)
s=time[0]; // 將秒的值送入緩存,以便下次比較,取出跳變
}
}
}
testk3(); //調時(shí)移位鍵k=1,2,3,4分別調節星期,月,日
while(ks!=0) //若進(jìn)入調節星期,月,日
{ testk4();disp2();testk3(); }//進(jìn)入調節
{ addr=0x87;
for(i=3;i<6;i++)
{
time[i]=read_1302(addr);// 讀出星期,月,日
addr+=2;//地址加2
}
for(n=0;n<80;n++) disp2();//顯示星期,月,日
}
}
}
聯(lián)系客服
微信登錄中...
請勿關(guān)閉此頁(yè)面
