|
這次我們用4個獨立按鍵和8位數(shù)碼管來做一個正計數(shù)器和倒計時器,到時間后(正計時最大值,倒計時最小值)LED燈閃爍10秒熄滅(大家可以先自己想好步驟,再看一下我下面的思路步驟)我用的單片機(jī)是STC89C52
主要的步驟:1、先思考正計數(shù),倒計數(shù)需要定時器中斷。還需要按鍵處理函數(shù)。另外需要一個數(shù)碼管顯示函數(shù)。
2、如何將這三個程序有序的排列組合起來形成一個完整的程序,這時我們可以從正計時器入手(也可以從倒計時入手)(由簡入深,抓住主干)先規(guī)定K1代表正計數(shù)器的開和關(guān),K2代表秒分時的移位,K3代表自加,K4代表自減。還有就是正計數(shù)到達(dá)最大值的時候LED燈進(jìn)行閃爍。
3、這時就要用標(biāo)志位來分清關(guān)系。
第一部分按鍵程序,具體操作就是用flag0代表正計數(shù)器的開關(guān),knum代表K2按下的時候到底是秒分時哪個 ,K3代表按一下加,K4代表按一下減,這時我們的按鍵程序基本完成;
第二部分就是我們的定時器中斷函數(shù),因為定時器我選的時16位非自動重裝10ms,所以要累計100次到一秒,大家要注意如果你選的是1ms定時,就需要累計1000次,記著你的數(shù)據(jù)類型要選int或者unsigned int,這部分容易忽略。還有當(dāng)K2按下,標(biāo)志位knum進(jìn)行改變也就代表著秒分時要開始閃爍。這時要進(jìn)行計數(shù)操作也就是當(dāng)計數(shù)時間到時,flag1進(jìn)行改變,控制秒分時的閃爍時間間隔。當(dāng)計數(shù)時間到的時候還需要flag2的改變這樣控制LED燈的閃爍頻率以及時間。
第三部分就是我們的數(shù)碼管顯示程序,這個程序要根據(jù)knum的值進(jìn)行改變,當(dāng)knum=0時它直接進(jìn)行顯示,當(dāng)knum!=0也就是K2按下的時候,根據(jù)flag1的值來閃爍。
第四部分就是我們要看到效果,當(dāng)正計數(shù)器到達(dá)最大值的時候LED燈開始閃爍。只需在正計數(shù)結(jié)束的時候控制flag2。
第五部分當(dāng)你把前四部分都解決了之后,那么你就可以著手做互鎖關(guān)系了,當(dāng)我們正計數(shù)的時候我們不能進(jìn)行移位操作,也就是說正計數(shù)器的開啟與移位操作形成互鎖(我們可以加if語句這樣就實現(xiàn)了)。
接下來就是K3,4長按和短按操作,短按加減一次,長按連加減。
我們想要實現(xiàn)的還有倒計時器的設(shè)定這時我們可以將K1也設(shè)定為長按和短按,長按倒計時器,短按正計數(shù)器。同時此時也會出現(xiàn)兩者的相互干擾情況,于是再設(shè)定一個互鎖,這樣就就避免了(用if語句來解決,就用我們現(xiàn)成的標(biāo)志位)。因為我們將K1,K3,K4都用了長按短按,所以就讓K2的長按也有功能,就是全體清零,LED燈閃爍。
第六部分就是大家發(fā)現(xiàn)了嗎?就是在進(jìn)行長按的時候,由于我們這時候還想要數(shù)碼管繼續(xù)顯示,所以我在長按的while循環(huán)里做了顯示,但這個顯示函數(shù)單次顯示只用了1ms,這樣我們顯示了八次,再加上一次延時1ms,我近似認(rèn)為一次長按循環(huán)所需時間為10ms,這一點大家做長按,短按的時候會遇到的,還有就是數(shù)碼管顯示函數(shù)的延時時間長短,會改變數(shù)碼管亮度。大家可以自己寫一下這個程序,寫完就理解我為什么要這樣寫了。
有錯誤請指出,謝謝。
單片機(jī)源程序如下:
- #include"digdisplay.h"
- sbit k1=P3^1; //短按進(jìn)行計數(shù)操作,長按進(jìn)行倒計時操作
- sbit k2=P3^0; //短按進(jìn)行秒分時的移位閃爍,長按進(jìn)行秒分時歸零,沒有移位閃爍,LED燈閃爍開始
- sbit k3=P3^2; //短按進(jìn)行秒分時(看K2讓誰閃爍)的加一操作 ,長按進(jìn)行連加操作(K2讓誰閃爍)
- sbit k4=P3^3; //短按進(jìn)行秒分時(看K2讓誰閃爍)的減一操作 ,長按進(jìn)行連減操作(K2讓誰閃爍)
- sbit led=P2^0; //當(dāng)計數(shù)到最大值時LED燈開始閃爍,當(dāng)?shù)褂嫊r到零時開始閃爍
- u8 datenume[6]={0,0,0,0,0,0}; //當(dāng)做存儲秒分時的值,通過運算轉(zhuǎn)換為數(shù)碼管顯示的值
- u8 miao=0,fen=0,shi=0,count,knum=0,flag0=0,time=0,flag1=0,flag2=0,flag3=0,time_count=0; //flag0是否進(jìn)行計數(shù)操作,falg1秒分時的閃爍標(biāo)志位,falg2是定時或計數(shù)到時LED燈進(jìn)行閃爍,flag3是否進(jìn)行倒計時操作,knum進(jìn)行移位操作的標(biāo)志性
- u8 a,b,c,d,e; //這幾個都代表數(shù)值,計算時間用的,你可以在程序中發(fā)現(xiàn)它們
- void Delay5ms() //@12.000MHz
- {
- unsigned char i, j;
- i = 10;
- j = 183;
- do
- {
- while (--j);
- } while (--i);
- }
- void keyprogress() //對四個固定按鍵進(jìn)行操作,具體操作如下
- {
- if(!k1)
- {
- Delay5ms();
- if(!k1)
- {
- while(!k1)
- {
- digdisplay(0,datenume[0]);
- digdisplay(1,datenume[1]);
- digdisplay(2,16);
- digdisplay(3,datenume[2]);
- digdisplay(4,datenume[3]);
- digdisplay(5,16);
- digdisplay(6,datenume[4]);
- digdisplay(7,datenume[5]);
- d++;
- Delay1ms();
- if(d==100)
- {
- if(knum==0&&flag0==0&&(miao!=0||fen!=0||shi!=0)) //計數(shù)器和倒計時形成互鎖當(dāng)秒分時都為零時不能進(jìn)行倒計時
- {
- flag3=!flag3; //開啟倒計時和關(guān)閉倒計時
- }
- }
- }
- if(d<100)
- {
- if(knum==0&&flag3==0) //當(dāng)沒進(jìn)行移位操作時才可以啟動計數(shù)器,解決了移位時計數(shù)器開啟問題,互鎖
- { //計數(shù)器和倒計時形成互鎖
- flag0=!flag0; //開啟計數(shù)器和關(guān)閉計數(shù)器
- }
- }
- d=0;
- }
- }
- if(!k2)
- {
- Delay5ms();
- if(!k2)
- {
- while(!k2)
- {
- digdisplay(0,datenume[0]);
- digdisplay(1,datenume[1]);
- digdisplay(2,16);
- digdisplay(3,datenume[2]);
- digdisplay(4,datenume[3]);
- digdisplay(5,16);
- digdisplay(6,datenume[4]);
- digdisplay(7,datenume[5]);
- e++;
- Delay1ms();
- if(e==100) //全體歸零LED燈閃爍
- {
- flag0=0;
- flag1=0;
- flag2=1;
- flag3=0;
- knum=0;
- shi=0;
- fen=0;
- miao=0;
- }
- }
- if(flag0==0&&e<100) //解決了當(dāng)移位操作時計數(shù)器開啟問題,形成必須要計數(shù)器關(guān)閉才能開始移位,形成互鎖
- {
- knum++;
- if(knum==4)
- {
- knum=0;
- }
- }
- e=0;
- }
- }
- if(!k3) //必須在有移位操作的時候才能加,也算一個鎖定
- {
- Delay5ms();
- if(!k3)
- {
- while(!k3)
- {
- digdisplay(0,datenume[0]);
- digdisplay(1,datenume[1]);
- digdisplay(2,16);
- digdisplay(3,datenume[2]);
- digdisplay(4,datenume[3]);
- digdisplay(5,16);
- digdisplay(6,datenume[4]);
- digdisplay(7,datenume[5]);
- Delay1ms();
- a++;
- if(a==100)
- {
- a=50;
- if(knum==1)
- {
- miao++;
- if(miao==60)
- {
- miao=0;
- }
- }
- else if(knum==2)
- {
- fen++;
- if(fen==60)
- {
- fen=0;
- }
- }
- else if(knum==3)
- {
- shi++;
- if(shi==24)
- {
- shi=0;
- }
- }
- }
- }
- if(knum!=0)
- {
- if(a<50)
- {
- if(knum==1)
- {
- miao++;
- if(miao==60)
- {
- miao=0;
- }
- }
- else if(knum==2)
- {
- fen++;
- if(fen==60)
- {
- fen=0;
- }
- }
- else if(knum==3)
- {
- shi++;
- if(shi==24)
- {
- shi=0;
- }
- }
- }
- }
- a=0;
- }
- }
- if(!k4) //必須在有移位操作時才可以自減
- {
- Delay5ms();
- if(!k4)
- {
- while(!k4)
- {
- digdisplay(0,datenume[0]);
- digdisplay(1,datenume[1]);
- digdisplay(2,16);
- digdisplay(3,datenume[2]);
- digdisplay(4,datenume[3]);
- digdisplay(5,16);
- digdisplay(6,datenume[4]);
- digdisplay(7,datenume[5]);
- Delay1ms();
- a++;
- if(a==100)
- {
- a=50;
- if(knum==1)
- {
- miao--;
- if(miao==255)
- {
- miao=59;
- }
- }
- if(knum==2)
- {
- fen--;
- if(fen==255)
- {
- fen=59;
- }
- }
- if(knum==3)
- {
- shi--;
- if(shi==255)
- {
- shi=23;
- }
- }
- }
- }
- if(a<50)
- {
- if(knum==1)
- {
- miao--;
- if(miao==255)
- {
- miao=59;
- }
- }
- else if(knum==2)
- {
- fen--;
- if(fen==255)
- {
- fen=59;
- }
- }
- else if(knum==3)
- {
- shi--;
- if(shi==255)
- {
- shi=23;
- }
- }
- }
- a=0;
- }
- }
- }
- void shuma() //做數(shù)碼管顯示函數(shù),當(dāng)knum=0時普通顯示,當(dāng)knum!=0時靠標(biāo)志位flag1決定閃爍
- {
- if(knum==0)
- {
- digdisplay(0,datenume[0]);
- digdisplay(1,datenume[1]);
- digdisplay(2,16);
- digdisplay(3,datenume[2]);
- digdisplay(4,datenume[3]);
- digdisplay(5,16);
- digdisplay(6,datenume[4]);
- digdisplay(7,datenume[5]);
- }
- else if(knum==1)
- {
- if(flag1)
- {
- digdisplay(0,datenume[0]);
- digdisplay(1,datenume[1]);
- digdisplay(2,16);
- digdisplay(3,datenume[2]);
- digdisplay(4,datenume[3]);
- digdisplay(5,16);
- digdisplay(6,datenume[4]);
- digdisplay(7,datenume[5]);
- }
- else
- {
- digdisplay(0,17);
- digdisplay(1,17);
- digdisplay(2,16);
- digdisplay(3,datenume[2]);
- digdisplay(4,datenume[3]);
- digdisplay(5,16);
- digdisplay(6,datenume[4]);
- digdisplay(7,datenume[5]);
- }
- }
- else if(knum==2)
- {
- if(flag1)
- {
- digdisplay(0,datenume[0]);
- digdisplay(1,datenume[1]);
- digdisplay(2,16);
- digdisplay(3,datenume[2]);
- digdisplay(4,datenume[3]);
- digdisplay(5,16);
- digdisplay(6,datenume[4]);
- digdisplay(7,datenume[5]);
- }
- else
- {
- digdisplay(0,datenume[0]);
- digdisplay(1,datenume[1]);
- digdisplay(2,16);
- digdisplay(3,17);
- digdisplay(4,17);
- digdisplay(5,16);
- digdisplay(6,datenume[4]);
- digdisplay(7,datenume[5]);
- }
- }
- else if(knum==3)
- {
- if(flag1)
- {
- digdisplay(0,datenume[0]);
- digdisplay(1,datenume[1]);
- digdisplay(2,16);
- digdisplay(3,datenume[2]);
- digdisplay(4,datenume[3]);
- digdisplay(5,16);
- digdisplay(6,datenume[4]);
- digdisplay(7,datenume[5]);
- }
- else
- {
- digdisplay(0,datenume[0]);
- digdisplay(1,datenume[1]);
- digdisplay(2,16);
- digdisplay(3,datenume[2]);
- digdisplay(4,datenume[3]);
- digdisplay(5,16);
- digdisplay(6,17);
- digdisplay(7,17);
- }
- }
- }
- void main()
- {
- TMOD &= 0xF0; //設(shè)置定時器模式
- TMOD |= 0x01; //設(shè)置定時器模式
- TL0 = 0xF0; //設(shè)置定時初值 10毫秒定時器
- TH0 = 0xD8; //設(shè)置定時初值
- TF0 = 0; //清除TF0標(biāo)志
- TR0=1; //定時器開啟 定時器在程序運行過程中將一直啟動
- ET0=1;
- EA=1;
- while(1)
- {
- keyprogress(); //按鍵處理函數(shù)分別處理K1,K2,K3,K4的長按和短按程序
- shuma(); //數(shù)碼管管顯示程序,處理K2按鍵按下
- }
- }
- void int0() interrupt 1
- {
- TL0 = 0xF0; //設(shè)置定時初值
- TH0 = 0xD8; //設(shè)置定時初值
- datenume[0]=miao%10; //對秒分時進(jìn)行數(shù)據(jù)處理,用數(shù)碼管顯示做鋪墊
- datenume[1]=miao/10;
- datenume[2]=fen%10;
- datenume[3]=fen/10;
- datenume[4]=shi%10;
- datenume[5]=shi/10;
- if(flag0&&knum==0) //進(jìn)行正向計數(shù),knum判斷是否進(jìn)行了移位操作,flag0判斷是否進(jìn)行了開始操作
- {
- count++;
- if(count==100)
- {
- count=0;
- miao++;
- if(miao==60)
- {
- miao=0;
- fen++;
- if(fen==60)
- {
- fen=0;
- shi++;
- if(shi==24)
- {
- shi=0;
- flag2=!flag2; //開啟LED燈的閃爍
- flag0=!flag0; //關(guān)閉計數(shù)器
- }
- }
- }
- }
- }
- if(flag3&&knum==0) //進(jìn)行倒計時操作
- {
- time_count++;
- if(time_count==100)
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
數(shù)碼管與按鍵的組合使用.rar
(39.3 KB, 下載次數(shù): 26)
2020-2-11 12:59 上傳
點擊文件名下載附件
|
評分
-
查看全部評分
|