|
僅使用內(nèi)部定時器,走時精度已經(jīng)可觀。
難度在于使用鍵盤調(diào)節(jié)萬年歷。
下載:
1602 定時器 點掃描做時鐘.rar
(2.62 KB, 下載次數(shù): 20)
2016-12-15 21:45 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
- #include<reg52.h>
- #define uint unsigned int
- #define uchar unsigned char
- uchar shi,fen,miao,ri,yue,nian,rimax,keyn,xq,flag;
- uint tt;
- uchar code table[]="2011-11-11 FRI";
- uchar code table1[]="23:59:51";
- uchar code tablex[]="MON TUE WED THU FRI SAT SUN ";
- sbit dula=P2^6;
- sbit wela=P2^7;
- sbit lcden=P3^4;
- sbit rs=P3^5;
- sbit key=P3^0;
- sbit keyg=P3^1;
- sbit keyd=P3^2; //原計劃寫調(diào)減,不想寫了。
- sbit gnd=P3^7;
- void init();
- void write_com(uchar com);
- void write_date(uchar date);
- void write_sfm(uchar wei,uchar date);
- void write_nyr(uchar wei,uchar date);
- void write_xq();
- void delay(uchar z);
- void yueday();
- void shunbianday();
- void keyscan();
- void clockrun();
- void main()
- {
- init();
- while(1)
- {
- keyscan();
- clockrun();
- }
- }
- void init()
- {
- uchar a,b;
- dula=0;
- wela=0;
- lcden=0;
- shi=23;
- fen=59;
- miao=58;
- nian=16;
- yue=2;
- ri=29;
- keyn=0;
- write_com(0x38);
- write_com(0x0c);
- write_com(0x06);
- write_com(0x01);
- write_com(0x80+1);
- for(a=0;a<14;a++)
- {
- write_date(table[a]);
- }
- write_com(0x80+0x40+4);
- for(b=0;b<8;b++)
- {
- write_date(table1[b]);
- }
- write_nyr(2,nian);
- write_nyr(5,yue);
- write_nyr(8,ri);
- write_sfm(0,shi);
- write_sfm(3,fen);
- write_sfm(6,miao);
- write_xq();
- yueday();
- TMOD=0x02; //設(shè)定定時/計數(shù)器工作方式2,自動重裝初值
- TH0=0; //高八位+1計數(shù)器,工作方式1中,(65536-46080)/256=高八位,高八位總共可以裝256,減76后可裝180,即:當(dāng)?shù)桶宋粸榱銜r,高八位加一計數(shù)器+1次數(shù)180次時剛好50ms
- TL0=0; //低八位+1計數(shù)器,工作方式2中,第八位用于+1計數(shù)完成計時,高八位用于保留初值給第八位重寫初值
- EA=1; //現(xiàn)在因不需占用機器周期重裝初值,若還有誤差,則只能是晶振的誤差
- ET0=1;
- TR0=1;
- }
- void timer0() interrupt 1
- {
- tt++; //由于第八位加計數(shù)器只能計256,
- }
- void write_sfm(uchar wei,uchar date)
- {
- uchar ge,shi;
- shi=date/10;
- ge=date%10;
- write_com(0x80+0x40+4+wei);
- write_date(0x30+shi);
- write_date(0x30+ge);
- }
- void write_nyr(uchar wei,uchar date)
- {
- uchar ge,shi;
- shi=date/10;
- ge=date%10;
- write_com(0x80+1+wei);
- write_date(0x30+shi);
- write_date(0x30+ge);
- }
- void write_xq() //寫星期數(shù)
- {
- uchar q;
- write_com(0x80+12);
- for(q=0;q<4;q++)
- {
- write_date(tablex[xq]);
- xq++;
- if(xq==28)
- xq=0;
- }
- }
- void yueday() //程序?qū)戦L了,改子函數(shù)名有困難,以后注意。
- { //該子函數(shù)表示月+1后計算引用的天數(shù)
- if(yue==1)
- rimax=32;
- if(yue==2)
- {
- if(nian%4==0)
- rimax=30;
- else
- rimax=29;
- }
- if(yue==3)
- rimax=32;
- if(yue==4)
- rimax=31;
- if(yue==5)
- rimax=32;
- if(yue==6)
- rimax=31;
- if(yue==7)
- rimax=32;
- if(yue==8)
- rimax=32;
- if(yue==9)
- rimax=31;
- if(yue==10)
- rimax=32;
- if(yue==11)
- rimax=31;
- if(yue==12)
- rimax=32;
- }
- void shunbianday() //該子函數(shù)表示月+0后計算引用的天數(shù)
- {
- if(yue==2) //實際調(diào)用1月份天數(shù)最大31
- rimax=31;
- if(yue==3) //實際調(diào)用2月份天數(shù)最大28/29
- {
- if(nian%4==0)
- rimax=29;
- else
- rimax=28;
- }
- if(yue==4)
- rimax=31; //實際調(diào)用3月份天數(shù)最大31
- if(yue==5)
- rimax=30; //實際調(diào)用4月份天數(shù)最大30
- if(yue==6)
- rimax=31; //實際調(diào)用5月份天數(shù)最大31
- if(yue==7)
- rimax=30; //實際調(diào)用6月份天數(shù)最大30
- if(yue==8)
- rimax=31; //實際調(diào)用7月份天數(shù)最大31
- if(yue==9)
- rimax=31; //實際調(diào)用8月份天數(shù)最大31
- if(yue==10)
- rimax=30; //實際調(diào)用9月份天數(shù)最大30
- if(yue==11)
- rimax=31; //實際調(diào)用10月份天數(shù)最大31
- if(yue==12)
- rimax=30; //實際調(diào)用11月份天數(shù)最大30
- }
- void delay(uchar z)
- {
- uchar i,j;
- for(i=z;i>0;i--)
- for(j=115;j>0;j--);
- }
- void write_com(uchar com)
- {
- rs=0;
- P0=com;
- delay(4);
- lcden=1;
- delay(4);
- lcden=0;
- }
- void write_date(uchar date)
- {
- rs=1;
- P0=date;
- delay(4);
- lcden=1;
- delay(4);
- lcden=0;
- }
- void keyscan()
- {
- uchar temp,p;
- gnd=0;
- if(key==0)
- {
- delay(5);
- if(key==0)
- {
- TR0=0;
- keyn++;
- if(keyn==7)
- keyn=0;
- write_com(0x0f);
- if(keyn==0)
- {
- TR0=1;
- write_com(0x0c);
- }
- if(keyn==1)
- write_com(0x80+0x40+11);
- if(keyn==2)
- write_com(0x80+0x40+8);
- if(keyn==3)
- write_com(0x80+0x40+5);
- if(keyn==4)
- write_com(0x80+10);
- if(keyn==5)
- write_com(0x80+7);
- if(keyn==6)
- write_com(0x80+4);
- while(!key);
- }
- }
- if(keyn==1)
- {
- if(keyg==0)
- {
- delay(5);
- if(keyg==0)
- {
- miao++;
- if(miao==60)
- miao=0;
- write_sfm(6,miao);
- write_com(0x80+0x40+11);
- while(!keyg);
- }
- }
- }
- if(keyn==2)
- {
- if(keyg==0)
- {
- delay(5);
- if(keyg==0)
- {
- fen++;
- if(fen==60)
- fen=0;
- write_sfm(3,fen);
- write_com(0x80+0x40+8);
- while(!keyg);
- }
- }
- }
- if(keyn==3)
- {
- if(keyg==0)
- {
- delay(5);
- if(keyg==0)
- {
- shi++;
- if(shi==24)
- shi=0;
- write_sfm(0,shi);
- write_com(0x80+0x40+5);
- while(!keyg);
- }
- }
- }
- if(keyn==4)
- {
- if(keyg==0)
- {
- delay(5);
- if(keyg==0)
- {
- yueday();
- ri++;
- if(ri>=rimax)
- {
- ri=1;
- temp=(rimax-2)%7;
- for(p=6-temp;p>0;p--)
- {
- write_xq(); //因為跳出循環(huán)后,下面還會再重復(fù)一次,所以這里只循環(huán)5次
- }
- }
- write_xq();
- write_nyr(8,ri);
- write_com(0x80+10);
- while(!keyg);
- }
- }
- }
- if(keyn==5)
- {
- if(keyg==0)
- {
- delay(5);
- if(keyg==0)
- {
- yue++;
- if(yue==13)
- {
- yue=1; //情況二,跨月數(shù)調(diào)月(12變1)后,間隔天數(shù)
- if(nian%4==0) //情況二分支1,閏年
- { //因為12月、1月均為月大,日編號不會變
- for(p=(366-33)%7;p>0;p--)
- write_xq();
- }
- else //情況二分支2,平年
- {
- for(p=(365-31)%7;p>0;p--)
- write_xq();
- }
- }
- write_nyr(5,yue);
- //標(biāo)記點
- yueday(); //情況一,順序調(diào)月后(1→12),間隔天數(shù)。本句判斷本月有多少天供后續(xù)利用
- if(ri>rimax-1) //情況一分支1。當(dāng)當(dāng)前顯示的天數(shù)小于本月最大天數(shù)時,顯示本月最大天數(shù)
- {
- write_nyr(8,rimax-1); //上個注釋的執(zhí)行部分,將示數(shù)改到最大值范圍
- temp=ri-rimax; //情況一分支1,判斷當(dāng)月數(shù)加一后,天數(shù)增加數(shù)量
- ri=rimax-1; //上個注釋的執(zhí)行部分,不能光改示數(shù),而不改實際運行值。
- shunbianday(); //更換rimax值
- for(p=(rimax+temp-1)%7;p>0;p--)
- write_xq();
- }
- else //情況一分支2,判斷當(dāng)月數(shù)加一后,天數(shù)增加數(shù)量
- { //當(dāng)初值大于29時,1月變2月,是順變,同時顯示值大于最大允許值
- shunbianday();
- for(p=rimax%7;p>0;p--)
- write_xq();
- }
- write_com(0x80+7);
- while(!keyg);
- }
- }
- }
- if(keyn==6)
- {
- if(keyg==0)
- {
- delay(5);
- if(keyg==0)
- {
- if(nian%4==0&&yue==2&&ri==29) //分支3,當(dāng)年+0為閏年2月29日時,年+1后2月只有28號。
- {
- ri=28; //改日的值
- write_nyr(8,ri); //改日顯示
- for(p=7;p>0;p--) //改星期顯示
- write_xq(); //循環(huán)七次,相當(dāng)于沒改
- flag=1; //分支4,當(dāng)閏年2月29調(diào)過年數(shù),調(diào)年再經(jīng)過閏年未能識別閏年
- }
- nian++;
- if(nian>99) //分支1,嘿嘿,百年蟲
- {
- nian=0;
- write_xq();
- }
- if(nian%4==0) //分支2.1,年+1為閏年
- {
- if(flag==1)
- {
- for(p=(365-28)%7;p>0;p--)
- write_xq();
- flag=2;
- }
- else
- {
- for(p=(366-35)%7;p>0;p--)
- write_xq();
- }
- }
- else //分支2.2,年+1為平年
- {
- if(flag==2)
- {
- for(p=2;p>0;p--)
- write_xq();
- flag=1;
- }
- else
- {
- for(p=(365-28)%7;p>0;p--)
- write_xq();
- }
- }
- write_nyr(2,nian);
- write_com(0x80+4);
- while(!keyg);
- }
- }
- }
- }
- void clockrun()
- {
- if(tt==3600)
- {
- tt=0;
- miao++;
- if(miao>=60)
- {
- miao=0;
- fen++;
- if(fen>=60)
- {
- fen=0;
- shi++;
- if(shi>=24)
- {
- shi=0;
- ri++;
- write_xq();
- yueday();
- if(ri>=rimax)
- {
- ri=1;
- yue++;
- if(yue>=13)
- {
- yue=1;
- nian++;
- if(nian>=100)
- nian=0;
- write_nyr(2,nian);
- }
- write_nyr(5,yue);
- }
- write_nyr(8,ri);
- }
- write_sfm(0,shi);
- }
- write_sfm(3,fen);
- }
- write_sfm(6,miao);
- }
- }
復(fù)制代碼
|
|