學了51,模仿了小時候電子手表的基本功能,可以在時鐘和秒表兩個功能間切換,用的是郭天祥的板子。采用四個獨立按鍵,通過對四個鍵按下的次數不同,實現不同的功能,程序詳注。(第一次嘗試很多地方未免復雜冗余,希望大神指點)
/*使用1602作為電子表的顯示屏,單片機上電后,首先通過按鍵設定當前時間,
完成初始化,同時該電子表還具有秒表功能,按下秒表鍵后,進入秒表界面。秒
表界面有開始,取次,停止,復位,返回時間,可以記錄三次取時,每個按鈕按
下都對應蜂鳴器短響一聲進入秒表界面,時間繼續運行,在時間界面,秒表處于
復位狀態。*/
單片機源程序如下:
- /*......................................................................................*/
- #include<reg52.h>
- sbit lcden=P3^4; //使能端
- sbit lcdrs=P3^5; //RS
- sbit dula=P2^6; //定義鎖存器的鎖存端
- sbit wela=P2^7;
- sbit s1=P3^0; //定義按鍵----功能鍵
- sbit s2=P3^1; //定義按鍵-----增加鍵
- sbit s3=P3^2; //定義按鍵------計次鍵
- sbit s4=P3^3; //定義按鍵------鐘與秒表的切換鍵
- sbit rd=P3^7; //初始化函數中使它接地從而使第四列矩陣鍵盤成為獨立鍵盤
- sbit beep=P2^3; //定義蜂鳴器
- char count,count1,s1num,s2num,s3num,s4num,stop, miao,shi, //stop保證在秒表工作模式下,定時器0的數值不會被送去lcd顯示。 count,count1是用到定時器里面, *num是用來計按鍵次數,miao*,shi*,fen*
- fen,miao1,shi1,fen1,miao3,fen3,shi3,miao4,fen4,shi4,miao5, //是用來保持lcd上的顯示的,結合下面應該可以看懂。
- fen5,shi5,miao6,fen6,shi6,miao7,fen7,shi7,miao8,fen8,shi8,
- miao9,fen9,shi9; //char表示的數據范圍-127~128
- void delay(int z) //延時子函數
- {
- int x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void xiang() //蜂鳴器發聲函數
- {
- beep=0;
- delay(20);
- beep=1;
- }
- void write_com(char com) //寫命令子函數
- {
- lcdrs=0;
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_date(char date) //寫數據子函數
- {
- lcdrs=1;
- P0=date;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_sfm(unsigned char add,unsigned char date) //寫時分秒函數
- {
- unsigned char shi,ge;
- shi=date/10; //分解一個2位數的十位和個位
- ge=date%10;
- write_com(0x80+0x40+add); //設置顯示位置
- write_date(0x30+shi); //送去液晶顯示十位
- write_date(0x30+ge); //送去液晶顯示個位
- }
- void init() //初始化函數
- {
- rd=0; //軟件將矩陣按鍵第四列一端置低用來分離出獨立按鍵
- dula=0;
- wela=0; //關閉鎖存器,防止數碼管分流,影響1602的顯示
- lcden=0;
- fen=0; //初始化鐘變量值
- miao=0;
- shi=0;
- count=0;
- count1=0;
- s1num=0;
- s2num=0;
- s3num=0;
- s4num=0;
- write_com(0x38); //設置16*2顯示,5*7點陣,8位數據口
- write_com(0x0c); //開顯示,不開光標 00001100
- write_com(0x06); //寫字符后地址指針自動加一,不移動 00000110
- write_com(0x01); //清除屏幕上原有的亂碼
- write_com(0x80+0x04); //從第一行的第五個字符位開始顯示
- write_com(0x80+0x40+6); //在第二行第第七個字符處寫入 “ :”
- write_date(':');
- delay(5);
- write_com(0x80+0x40+9); //在第二行第第十個字符處寫入 “ :”
- write_date(':');
- delay(5);
- write_sfm(10,miao);
- write_sfm(7,fen);
- write_sfm(4,shi);
- TMOD=0X11; //設置定時器0的工作模式1;
- TH0=(65536-50000)/256; //裝初值
- TL0=(65536-50000)%256;
- EA=1; //打開總中斷
- ET0=1; //開定時器0中斷
- TR0=1; //啟動定時器0
- }
- void init_stopwatch() //初始化秒表
- {
- write_com(0x01);
- miao1=0;
- fen1=0;
- shi1=0;
- write_com(0x80+0x40+6); //在第二行第第七個字符處寫入 “ :”
- write_date(':');
- delay(5);
- write_com(0x80+0x40+9); //在第二行第第十個字符處寫入 “ :”
- write_date(':');
- delay(5);
- write_sfm(10,miao1);
- write_sfm(7,fen1);
- write_sfm(4,shi1); //TMOD=0x10;錯誤處:采用兩個定時器時,一次設置工作模式就行
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;
- EA=1;
- ET1=1;
- TR1=0;
- }
- void keyscan() //鍵盤掃描函數
- {
- if(s1==0) //判斷s1是否被按下
- {
- delay(5);
- if(s1==0) //確實被按下
- {
- while(!s1); //按鍵抬起,
- xiang(); //蜂鳴器響
- s1num++; //功能鍵被按下次數
- if(s1num==1) //第一次被按下時
- {
- }
- if(s1num==2) //第二次被按下時
- {
- TR0=0; //關閉定時器
- write_com(0x80+0x40+10); //指針定到秒的地址
- write_com(0x0f); //指針開始閃爍
- }
- if(s1num==3) //第三次被按下時
- {
- write_com(0x80+0x40+7); //指針定位到分的地址
- }
- if(s1num==4) //第四次被按下時
- {
- write_com(0x80+0x40+4); //指針定位到時的地址
- }
- if(s1num==5) //第五次被按下時
- {
- s1num=0; //清零
- write_com(0x0c); //關閉光標
- TR0=1; //打開定時器
- }
- }
- }
- if(s1num==1)
- {
- if(s4==0) //切換到定時器模式
- {
- delay(5);
- if(s4==0);
- s4num++;
- while(!s4);
- xiang(); //s4確實被按下
- if(s4num==1)
- {
- stop=1;
- init_stopwatch();
- }
- if(s4num==2)
- {
- TR1=0;
- stop=0;
- s4num=0;
- write_sfm(10,(miao3+miao4));
- write_sfm(7,(fen3+fen4));
- write_sfm(4,(shi3+shi4));
-
- }
- }
- }
- if(s1num==1)
- {
- if(s2==0)
- {
- delay(5);
- if(s2==0)
- {
- while(!s2);
- xiang();
- s2num++;
- if(s2num==1)
- {
- TR1=1;
- }
- if(s2num==2)
- {
- s2num=0;
- TR1=0;
- }
- }
- }
- }
- if(s2num==1&&s4num==1)
- { if(s3==0)
- {
- delay(5);
- if(s3==0)
- {
- s3num++;
- while(!s3);
- xiang();
- if(s3num==1)
- {
- shi6=shi5;
- fen6=fen5;
- miao6=miao5;
- }
- if(s3num==2)
- {
- shi7=shi5;
- fen7=fen5;
- miao7=miao5;
- }
- if(s3num==3)
- {
- shi8=shi5;
- fen8=fen5;
- miao8=miao5;
- }
- if(s3num==4)
- {
- miao1=0;
- fen1=0;
- shi1=0;
- write_sfm(10,miao1);
- write_sfm(7,fen1);
- write_sfm(4,shi1);
- TR1=0;
- }
- if(s3num==5)
- {
- write_sfm(10,miao6);
- write_sfm(7,fen6);
- write_sfm(4,shi6);
- }
- if(s3num==6)
- {
- write_sfm(10,miao7);
- write_sfm(7,fen7);
- write_sfm(4,shi7);
- }
- if(s3num==7)
- {
- write_sfm(10,miao8);
- write_sfm(7,fen8);
- write_sfm(4,shi8);
- }
- if(s3num==8)
- {
- s3num=0;
- init_stopwatch();
- }
- }
- }
- }
- if(s1num!=0) //若是s1被按過
- {
- if(s2==0) //s2被按下
- {
- delay(5);
- if(s2==0) //s2確實被按下
- {
- while(!s2); //如果s2抬起
- xiang(); //蜂鳴器響
- if(s1num==2) //此時若是s1被按了一次
- {
- miao++; //秒加一
- miao4=miao;
- if(miao==60) //如果秒等于60
- miao=0;
- miao4=miao; //清零
- write_com(0x80+0x40+10);
- write_sfm(10,miao);
- }
- if(s1num==3)
- {
- fen++;
- fen4=fen;
- if(fen==60)
- fen=0;
- fen4=fen;
- write_com(0x80+0x40+7);
- write_sfm(7,fen);
- }
- if(s1num==4)
- {
- shi++;
- shi4=shi;
- if(shi==24)
- shi=0;
- shi4=shi;
- write_com(0x80+0x40+4);
- write_sfm(4,shi);
- }
- }
- }
-
- }
- }
- void main()
- {
- init(); //初始化1602
- while(1)
- {
- keyscan(); //一直掃描鍵盤
- }
- }
- void timer0() interrupt 1 //定時器0用于鐘表
- {
- TH0=(65536-50000)/256; //裝初值
- TL0=(65536-50000)%256;
- count++; //計數,保證每20次中斷一次,時長為一秒
- if(count==20)
- {
- count=0;
- miao++;
- miao3=miao;
- if(miao==60) //將更新的秒時分的值更新到1602
- {
- miao=0;
- miao3=miao;
- fen++;
- fen3=fen;
- if(fen==60)
- {
- fen=0;
- fen3=fen;
- shi++;
- shi3=shi;
- if(shi==24)
- {
- shi=0;
- shi3=shi;
- }
- if(stop==0) //在秒表模式,鐘表的時間不顯示,但是任然計時
- write_sfm(4,shi);
- }
- if(stop==0)
- write_sfm(7,fen);
- }
- if(stop==0)
- write_sfm(10,miao);
- }
- }
- void timer1() interrupt 3 //定時器1用于秒表計時
- {
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;
- count1++;
- if(count1==20)
- {
- count1=0;
- miao1++;
- miao5=miao1;
- if(miao1==60)
- {
- miao1=0;
- miao5=miao1;
- fen1++;
- fen5=fen1;
- if(fen1==60)
- {
- fen1=0;
- fen5=fen1;
- shi1++;
- shi5=shi1;
- if(shi1==24)
- {
- shi1=0;
- shi5=shi1;
- }
- write_sfm(4,shi1);
- }
- write_sfm(7,fen1);
- }
- write_sfm(10,miao1);
- }
- }
復制代碼
|