51單片機系列-倒計時器的實現

倒計時器是我們日常生活中常用的計時工具之一,用於實現各類活動的計時。本文以51單片機為例,對倒計時器編程實現進行說明。實現效果描述如下:

本例實現效果如上圖所示,倒計時器基本問題描述如下:

1、使用4為數碼管作為最終顯示設備,允許倒計時範圍為0-9999秒。

2、倒計時時需要對最後10秒使用蜂鳴器進行提示,發出提示音,提示音結束表示計實結束


編程實現

本例使用51開發板進行實際練習操作載體,該板集成了51單片機操作基本功能模塊,學習板結構如下:

51單片機系列-倒計時器的實現

51學習開發板

編程實現思路:

1、數碼管的動態顯示

數碼管顯示部分包括段與位,其中段表示每一位數碼管中顯示的內容,位表示選擇的數碼管中的哪一位,本例使用4位數碼管。段可以顯示0-9及a、b、c、e、f、h等字符。我們定義數組存儲表示各顯示值,數組描述如下:

51單片機系列-倒計時器的實現

段選字符數組

段選字符數組如上,其中0x3f表示數字0,其餘依次為1,...9。

2、將時間數字分解為單個字符,讓單個字符與數碼管顯示字符對應

在數碼管顯示時需要讀取計時數字中的每一位,然後才能對應設置顯示的字符。因此如何將時間進行分解是顯示的第一步,本例我們選擇了4位數碼管,數字最大為4位,因此我們可以編寫函數實現各位數字的讀取,為統一標準我們設計長度為4的數組存儲其中獲取的每一位,假設設置計時時間為120秒,則可分解為{0,1,2,0}。該函數描述如下:

<code>void getNumber(unsigned int a)
{
\tunsigned int tempa,tempb;
\tif(a>=1000)//表示有4位
\t{
\t\ttempa=a/1000;
\t\tt[0]=tempa;
\t\ttempb=a%1000;
\t\ttempa=tempb/100;
\t\tt[1]=tempa;
\t\ttempb=tempb%100;
\t\ttempa=tempb/10;
\t\tt[2]=tempa;
\t\tt[3]=tempb%10;
\t}
\tif(a>=100 && a<1000)//表示有3位
\t{
\t\tt[0]=0;

\t\ttempa=a/100;
\t\tt[1]=tempa;
\t\ttempb=a%100;
\t\ttempa=tempb/10;
\t\tt[2]=tempa;
\t\tt[3]=tempb%10;
\t}
\tif(a>=10 && a<100)//表示有2位
\t{
\t\tt[0]=0;
\t\tt[1]=0;
\t\tt[2]=a/10;
\t\tt[3]=a%10;
\t}
\tif(a>=0 && a<10)//表示有1位
\t{
\t\tt[0]=0;
\t\tt[1]=0;
\t\tt[2]=0;
\t\tt[3]=a;
\t}
}/<code>

數字位獲取函數如上所示,我們定義數組t實現對各位進行存儲。

3、將時間數字與數碼管顯示對應

在獲取計時時間每一位之後,就需要將其數字與數碼管對應的字符進行對應處理。本例通過函數實現將數字與數碼管字符進行對應,實現代碼描述如下:

<code>void getString(unsigned int a[],unsigned int m)
{
\tunsigned int i;
\tfor(i=0;i\t{
\t\tswitch(a[i])
\t\t{
\t\t\tcase 0:

\t\t\t\ttm[i]=st[0];
\t\t\tbreak;
\t\t\tcase 1:
\t\t\t\ttm[i]=st[1];
\t\t\tbreak;
\t\t\tcase 2:
\t\t\t\ttm[i]=st[2];
\t\t\tbreak;
\t\t\tcase 3:
\t\t\t\ttm[i]=st[3];
\t\t\tbreak;
\t\t\tcase 4:
\t\t\t\ttm[i]=st[4];
\t\t\tbreak;
\t\t\tcase 5:
\t\t\t\ttm[i]=st[5];
\t\t\tbreak;
\t\t\tcase 6:
\t\t\t\ttm[i]=st[6];
\t\t\tbreak;
\t\t\tcase 7:
\t\t\t\ttm[i]=st[7];
\t\t\tbreak;
\t\t\tcase 8:
\t\t\t\ttm[i]=st[8];
\t\t\tbreak;
\t\t\tcase 9:
\t\t\t\ttm[i]=st[9];
\t\t\tbreak;
\t\t}
\t}
}
/<code>

其中tm存儲與數字數組對應的顯示字符編碼,st用於存儲段選字符數組。通過該函數我們可以實時獲取倒計時數字並將其對應的數碼管字符獲取。

4、數碼管顯示的實現

獲取字符編碼之後我們可以定義函數實現將其顯示到數碼管中,實現代碼描述如下:

<code>void showled(unsigned char a,unsigned char b,unsigned char c,unsigned char d)
{
\tduan=a;//最右
\twei1=0;
\twei2=0;
\twei3=0;
\twei4=1;
\tdelay(1);
\tduan=b;
\twei1=0;
\twei2=0;
\twei3=1;
\twei4=0;
\tdelay(1);
\tduan=c;//需要顯示分隔符
\twei1=0;
\twei2=1;
\twei3=0;
\twei4=0;
\tdelay(1);
\tduan=d;
\twei1=1;
\twei2=0;
\twei3=0;
\twei4=0;
\tdelay(1);
\t
}/<code>

計時器初始化函數

本例計時器使用51單片機內部計時器T0進行計時器的開發,在使用前需要設置T0計時器參數,打開計時器等,將其封裝到計時器初始化函數,該函數定義如下:

<code>void time_init(void)//初始化計時器
{
\tTMOD=0X01;
\tTH0=0xB8;

\tTL0=0x00;
\tTR0=1;//啟動T0計時器
\tled=0;
}/<code>

主函數

完成各類函數定義之後,可以編寫主函數用於實現計時器功能,main主函數定義描述如下:

<code>void main(void)
{
\tfm=1;
\ttime_init();
\tgetNumber(alltime);
\tgetString(t,4);
\twhile(alltime>0)
\t{
\t\tshowled(tm[3],tm[2],tm[1],tm[0]);
\t\tif(TF0==1)//判斷是否溢出
\t\t{
\t\t\tTF0=0;
\t\t\tTH0=0xB8;
\t\t\tTL0=0x00;
\t\t\tcount++;
\t\t\tif(count>=50)
\t\t\t{
\t\t\t\tcount=0;
\t\t\t\tled=~led;
\t\t\t\talltime--;
\t\t\t\tgetNumber(alltime);
\t\t\t\tgetString(t,4);
\t\t\t\tif(alltime<=10)
\t\t\t\t\t{
\t\t\t\t\t\tfm=~fm;
\t\t\t\t\t}
\t\t\t}
\t\t}
\t}
\twhile(1)
\t{
\t\tfm=1;
\t\tled=0;
\t\tTR0=0;

\t\tshowled(st[0],st[0],st[0],st[0]);
\t\t//delay(100);
\t\t
\t}
}/<code>



本頭條號長期關注編程資訊分享;編程課程、素材、代碼分享及編程培訓。如果您對以上方面有興趣或代碼錯誤、建議與意見,可以聯繫作者,共同探討。更多單片機教程及實例分享期待大家關注!


分享到:


相關文章: