#include <reg52.h> #define uchar unsigned char #define uint unsigned int #define D P2 //段選 #define W P0 //位選 sbit IO=P1^1; //數據口 sbit SCLK=P1^2; //控制數據時鐘 sbit RST=P1^0; //使能端、復位端 /************按鍵引腳定義***********/ sbit s1=P1^5; //按鍵 加 sbit s2=P1^3; //按鍵 減 sbit s3=P1^4; //按鍵 選擇 sbit led=P1^7; //閃爍的小數點 uchar s, knum=0,snum,fnum; bit flag; /***********寫時分秒地址************/ #define write_shi 0x84 #define write_fen 0x82 #define write_miao 0x80 /***********讀時分秒地址************/ #define read_shi 0x85 #define read_fen 0x83 #define read_miao 0x81 bit miao_flag; char miao_num; char Dmiao; char shi,fen,miao; //讀出數據存儲變量 uchar d[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90}; //不帶小數點 uchar dd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //帶小數點 void delay(uint z) //延時函數,z的取值為這個函數的延時ms數,如 delay(200);大約延時200ms. { //delay(500);大約延時500ms. uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void t0_init() //定時50ms一個中斷 { TMOD=0X01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; TR0=1; } uchar read_1302(uchar add) //讀函數 { uchar i,date; RST=0; //禁止讀寫數據 for(i=0;i<8;i++) { RST=1; SCLK=0; IO=add&0x01; add>>=1; SCLK=1; } for(i=0;i<8;i++) { if(IO) date=date|0x80; else date=date|0x00; SCLK=1; date>>=1; SCLK=0; } RST=0; date=date/16*10+date%16;//進制轉換 16轉10進制 IO=0; //數據讀完后,IO口必須為0,不然小時一直顯示85 return date; } void write_1302(uchar add,uchar dat) //寫函數 { uchar i; RST=0; //禁止讀寫數據 SCLK=0; for(i=0;i<8;i++) //寫地址 { RST=1; //允許讀寫數據 SCLK=0; IO=add&0x01; add>>=1; SCLK=1; } for(i=0;i<8;i++) //寫數據 { RST=1; //允許讀寫數據 SCLK=0; IO=dat&0x01; dat>>=1; SCLK=1; } RST=0; } void init_1302() //初始化函數 設置時間 { flag=read_1302(0x81); if(flag&0x80) write_1302(0x8e,0x00); //保護取消,可以進行讀寫操作 write_1302(write_miao,0x56); write_1302(write_fen,0x49); write_1302(write_shi,0x14); write_1302(0x90,0xa5); write_1302(0x8e,0x80); //保護啟動,不能進行讀寫操作 } void display(uchar shi,uchar fen) //顯示函數 { if(knum==0) { snum=30; fnum=30; } if(knum==1) { fnum++; snum=30; } if(knum==2) { snum++; fnum=30; } if(snum>=30) { W=0xF7; //位選 s=d[shi/10];//段碼先給s,判斷其值是否為0, if(s==0xc0) { W=0xff; D=0xff; } D=s;//s不為零則給D,讓其顯示 delay(5); D=0Xff; //消隱 if(miao_flag) //小數點閃爍 { miao_flag=0; W=0xFb; D=dd[shi%10]; delay(5); D=0Xff; //消隱 } else { W=0xFb; D=d[shi%10]; delay(5); D=0Xff; } if(snum==60) snum=0; } if(fnum>=30) { W=0xFd; D=d[fen/10]; delay(5); D=0Xff; //消隱 W=0xFe; D=d[fen%10]; delay(5); D=0Xff; //消隱 if(fnum==60) fnum=0; } } void read_sf() { miao=read_1302(read_miao); /*if(miao!=Dmiao) { Dmiao=miao; TR0=1; miao_flag=1; } */ fen=read_1302(read_fen); shi=read_1302(read_shi); display(shi,fen); } void keyscan() //按鍵掃描函數 { if(s3==0) //選擇按鍵按下 { delay(10); if(s3==0) { while(!s3) display(shi,fen); //加上這句,按鍵按下就不會閃 knum++; if(knum==1) //分閃爍 { write_1302(0x8e,0x00); //保護取消 write_1302(write_miao,0x80); } if(knum==3) //時鐘啟動 { knum=0; write_1302(write_miao,0x00); write_1302(0x8e,0x80); //保護啟動 } } } if(knum==1) //分鐘調節 { if(s1==0) //加 { delay(10); if(s1==0) { while(!s1) display(shi,fen); //加上這句,按鍵按下就不會閃 fen++; if(fen==60) fen=0; write_1302(write_fen,fen/10*16+fen%10); //寫入1302 // read_sf(); //讀出時間,然后顯示 } } if(s2==0) { delay(10); if(s2==0) { while(!s2) display(shi,fen); //加上這句,按鍵按下就不會閃 fen--; if(fen==-1) fen=59; write_1302(write_fen,fen/10*16+fen%10); read_sf(); } } } if(knum==2) { if(s1==0) { delay(10); if(s1==0) { while(!s1) display(shi,fen); //加上這句,按鍵按下就不會閃 shi++; if(shi==24) shi=0; write_1302(write_shi,shi/10*16+shi%10); read_sf(); } } if(s2==0) { delay(10); if(s2==0) { while(!s2) display(shi,fen); //加上這句,按鍵按下就不會閃 shi--; if(shi==-1) shi=23; write_1302(write_shi,shi/10*16+shi%10); read_sf(); } } } } void main() { init_1302(); t0_init(); while(1) { if(miao_num<10) led=0; if(miao_num>=10) led=1; read_sf(); keyscan(); } } void t0_timer() interrupt 1 { TMOD=0X01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; miao_num++; if(miao_num>=20) { miao_num=0; miao_flag=1; } } |