8.1 八段數碼管簡介
在我們生活中隨處可見數碼管的應用,數碼管的應用形式多種多樣,拋開事物表象,深入到它的本質,正所謂萬變不離其中,數碼管應用的原理都是基本相通的。本章我們將詳細介紹數碼管的基本原理以及數碼管的應用。最典型的數碼管為8段LED數碼管,外觀如下圖所示:
如上圖所示,數碼管包括A、B、C、D、E、F、G以及DP共8段,實際上8段為8個獨立的LED。上面8段LED組成1位數碼管。數碼管按照內部連接方法的不同分為共陰型或共陽,當8段LED的陰極連接在一起稱為為共陰型,陽極連接在一起稱為共陽型。如下圖所示為4位共陽型的8 段數碼管。
如上圖所示,4位數碼管每一位的8段LED的陽極連在一起,組成共陽極型數碼管,8段數碼管的陰極分別連接在一起。當選中某一位的陽極使其為高電平,使8段數碼管的陰極對應的位低電平便可點亮數碼管。例如,DP、G、F、E、D、C、B、A電平值依次為:1、1、1、1、1、0、0、1時數碼管顯示為數字1。據此可以編輯共陽數碼管的真值表,如下表所示:
一般點亮一段數碼管需要至少10mA, 而單片機管腳輸出的電流較小,無法驅動數碼管,可以采用上拉電阻、三極管驅動或采用專用驅動芯片進行驅動。RY-51單片機開發板采用兩個74HC573驅動芯片,驅動2個4位的數碼管,共8位數碼管如下圖所示:
8.2 鎖存器74HC573功能介紹
如上圖所示,U3,U4為8位的數據鎖存器74HC573,D7-D0為數據輸入端,Q7-Q0為與輸入端一一對應的輸出端。74HC573有2個控制信號分別為第1、11管腳、1管腳為芯片使能控制端,11管腳為數據鎖存控制端。
當1接高電平時,芯片不工作,無論數據輸入端為高、低電平,輸出端Q7-Q0為高阻態。只有當1管腳為低電平時,芯片才能正常工作,如圖8-3所示U3、U4均將1管腳直接接地。
在1管腳接地的情況下,當11管腳為高電平時,D7-D0輸入為高電平時,Q7-Q0輸出為高、同理當輸入為低電平時,輸出為低電平,此時相當于芯片的D7-D0與Q7-Q0是一一連通的。
當11管腳為低電平時,無論輸入端D7-D0是高或者低電平,Q7-Q0保持原來的值不變。
利用上面的特點我們就可以實現數據的鎖存了。假設我們要把0xFB鎖存到Q7-Q0,首先使11管腳為高電平,給輸入端D7-D0賦值0xFB,此時輸出端Q7-Q0輸出為0xFB,此時將11管腳拉為低電平并一直保持,那么此后無論輸入端D7-D0為何值,Q7-Q0均為0xFB,因此完成了數據的鎖存。74HC573真值表如下表所示:
如上面原理圖所示,根據鎖存器74HC573的特點,利用單片的一個8位端口,以及兩個用于控制的I/O口便能控制8位數碼管了。如圖所示,輸入數據D7-D0與單片的P0口相連,U3、U4的11管腳分別與單片機的I/O口P2.7、P2.6相連。鎖存器U3的輸出端Q7~Q0分別與數碼管的a-g,DP相連,鎖存器U4的輸出端Q7-Q0分別與8位數碼管的公共端相連。
8.3 單片機控制數碼管
下面我們通過舉例來講解數碼管的控制過程,以使第5位數碼管顯示數字8為例。如表8-1所示數字8對應數碼管真值為0x80,通過單片機的P0口將0x80鎖存到U3的輸出口。如圖8-3所示,第5位數碼管公共端WE5對應的是鎖存器U4的Q4,應只需Q4為高電平,Q7-Q5,Q3-Q1為低電平,便可使第5位數碼管顯示數字8,其它數碼管不顯示。因此通過單片機的P0口將0x10鎖存到U4。數碼管的顯示總結如下,首先將字碼鎖存到U3,然后將數碼管的顯示位鎖存到U4。數碼管顯示程序如下所示:
/*----------------------------------------------------
** 數碼管5顯示數字8
----------------------------------------------------*/
#include< reg52.h >
sbit DU = P2^7;
sbit WE = P2^6;
void main()
{
P0 = 0x80;//顯示數字8
DU = 1;
DU = 0;
P0 = 0x10;//第5位數碼管
WE = 1;
WE = 0;
while(1);
}
程序代碼如上所示,在主程序中首先把數字8鎖存到鎖存器U3,然后將數碼管5公共端的高電平鎖存到U4,將程序編譯并下載到單片機檢驗實際顯示效果。每一個數字對應數碼管都是固定的,在實際應用中每條語句中都對P0進行賦值的話會比較繁瑣而且不便于程序閱讀,我們往往將數碼管的真值放在一個數組中,程序中調用數組即可,改進程序如下所示:
/*----------------------------------------------------
** 數碼管5顯示數字8,字碼組放入數組中
----------------------------------------------------*/
#include< reg52.h >
#define uchar unsigned char
#define uint unsigned int
sbit DU = P2^7;
sbit WE = P2^6;
//共陽型(0~9,A,b,C,d,E,F,全亮,全滅),字碼組
uchar code table_D[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x00,0xFF};
//位選數組
uchar code table_W[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xFF,0x00};
void main()
{
P0 = table_D[8];//顯示數字8
DU = 1;
DU = 0;
P0 = table_W[4];//第5位數碼管
WE = 1;
WE = 0;
while(1);
}
如代碼所示,將數碼管真值表放入數組table_D[],數組的第0位對應的數字為0,第8位對應的數字為8,因此,如代碼所示,需要顯示數字8,直接將table_D[8],賦值給P0即可,方便又好記。Table_W[]設計的原理相同。將程序下載到開發板,顯示效果與前面保持一致。
前面講解的都是讓某一個數碼管顯示某一個固定的值,下面我們講解較為復雜一點數碼管顯示。例如,第1位數碼管顯示數字0,500ms之后第2位數碼管顯示數字1,直到第8位數碼管顯示7,然后循環上述步驟。要實現上面的功能我們需要用到前面講解的定時器功能,即每500ms在定時器中斷程序中給數碼管更新一次數值。程序代碼如下所示。
/*----------------------------------------------------
** 數碼管1~8循環顯示數字0~7,間隔500ms
** 定時器中斷方式
----------------------------------------------------*/
#include< reg52.h >
#define uchar unsigned char
#define uint unsigned int
#define FOSC 11059200 //單片機晶振頻率
#define T_1ms (65536 - FOSC/12/1000) //定時器初始值計算
uint count = 0;
uint flag = 0;
sbit DU = P2^7;
sbit WE = P2^6;
//共陽型(0~9,A,b,C,d,E,F,全亮,全滅),字碼組
uchar code table_D[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x00,0xFF};
//位選數組
uchar code table_W[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xFF,0x00};
void main()
{
TMOD = 0x01; //定時器工作模式配置
TL0 = T_1ms; //裝載初始值
TH0 = T_1ms >>8;
TR0 = 1; //啟動定時器
ET0 = 1; //允許定時器中斷
EA = 1; //開總中斷
while(1); //循環
}
void timer0() interrupt 1
{
TL0 = T_1ms;//重裝初始值
TH0 = T_1ms >>8;
count++;
if(count >= 500)//每一毫秒進入一次中斷,達到500次則為500ms,跟新一次數碼管顯示。
{
count = 0;
P0 = table_D[flag];//數字0~7循環
DU = 1;
DU = 0;
P0 = table_W[flag];//數碼管1~8循環點亮
WE = 1;
WE = 0;
flag++;
if(flag >=8)
flag =0;
}
}
將程序下載到單片機開發板檢驗效果是否與預期一致。
8.4動態顯示數碼管
前面講解的數碼管顯示均為在某個時間內只能顯示一個數碼管,那么如何讓8個數碼管同時顯示不同的數。前面我們講解的例子為數碼管1到8分別顯示數字1到8,顯示的間隔時間為500ms,如果我們將時間間隔該為100ms,那么數碼管切換的速度比以前快了5倍,當把間隔該為2ms時,由于間隔時間太短,感覺前一個數碼管還沒來的及完全熄滅,后面的數碼管就點亮了,這就是人眼睛的視覺暫留效應。
因此,你可以看到數碼管上同時顯示了01234567共八個數,這就是動態數碼管顯示的原理。只需要將上面的程序稍加改動便可實現,將語句“if(count>=500)”改為“if(count>=2)”。將修改好的程序編譯下載到開發板觀察效果。
8.5 數碼管消隱
當把上面的程序下載到開發板時,8位數碼管會同時顯示“01234567”共8個數字。但是,細心的同學會發現,有的數碼管不應該顯示的段會有點亮,但亮度會比較低,看起來像陰影一樣。這種現象是怎么形成的呢,又該怎么消除呢?下面我們通過程序來具體分析。
8.4節所講的定時器中斷程序如上圖所示,根據前面介紹可知,每隔2ms語句51-59會執行一次,每次flag的值會加1。第一次時flag=0,數碼管1顯示數字0,第二次時,flag=1,數碼管2顯示數字1,如此循環下去。當第二次執行到第51行語句時,此時還沒有選擇數碼管2,而是第一次執行語句57時選中了的數碼管1,只有當語句執行到57時,才完成數碼管2的選定,因此,在執行語句51-57期間,是數碼管1顯示了數字1,當執行到57之后的2ms時間內是數碼管2顯示了數字1。由于語句執行語句51-57的時間遠小于2m,因此亮度較低,這就是我們上面觀察到的陰影。陰影產生的原因找到了,下面我們講解陰影的消除了。如果我們在語句51之前先把所有的數碼關都關掉,就不會出現上述情況了。程序如下:
void timer0() interrupt 1
{
TL0 = T_1ms;//重裝初始值
TH0 = T_1ms >>8;
count++;
if(count >= 2)//每一毫秒進入一次中斷,達到2次則為2ms更新一次數碼管。
{
count = 0;
P0 =table_W[9];//關閉所有數碼管,消隱處理
WE = 1;
WE = 0;
P0 = table_D[flag];//數字0~7循環
DU = 1;
DU = 0;
P0 = table_W[flag];//數碼管1~8循環點亮
WE = 1;
WE = 0;
flag++;
if(flag >=8)
flag =0;
}
}
將程序重新編譯,下載到開發板。正如程序設計所愿,數碼管陰影成功被消除。
8.6 數碼管應用
這里我們在擴展一下數碼管的應用,做一個簡單秒表,在數碼管上顯示。程序設計原理如下:在定時器中斷程序中增加一個變量T_count,當1ms進入一次定時器中斷時自加一次,然后在主程序中判斷是否達到了1000次即1s的時間,每秒鐘變量Sec自加1次,記錄時間。將sec個、十、百、千位保存到數組Buf_LED[]中,在將數組顯示到數碼管上,程序如下所示:
/*----------------------------------------------------
** 秒表
----------------------------------------------------*/
#include< reg52.h >
#define uchar unsigned char
#define uint unsigned int
#define FOSC 11059200 //單片機晶振頻率
#define T_1ms (65536 - FOSC/12/1000) //定時器初始值計算
uint count = 0;
uint flag = 0;
uint T_count = 0;
uint Sec = 0;
sbit DU = P2^7;
sbit WE = P2^6;
uchar Buf_LED[8] ={0};
//共陽型(0~9,A,b,C,d,E,F,全亮,全滅),字碼組
uchar code table_D[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x00,0xFF};
//位選數組
uchar code table_W[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xFF,0x00};
void main()
{
TMOD = 0x01; //定時器工作模式配置
TL0 = T_1ms; //裝載初始值
TH0 = T_1ms >>8;
TR0 = 1; //啟動定時器
ET0 = 1; //允許定時器中斷
EA = 1; //開總中斷
while(1) //循環
{
if(T_count >=1000)
{
T_count =0;
Sec++;
Buf_LED[7]= Sec%10;
Buf_LED[6]= Sec/10%10;
Buf_LED[5]= Sec/100%10;
Buf_LED[4]= Sec/1000%10;
}
}
}
void timer0() interrupt 1
{
TL0 = T_1ms;//重裝初始值
TH0 = T_1ms >>8;
T_count++;
count++;
if(count >= 2)//每一毫秒進入一次中斷,達到2次則為2ms更新一次數碼管。
{
count = 0;
P0 =table_W[9];//關閉所有數碼管,消隱處理
WE = 1;
WE = 0;
P0 = table_D[Buf_LED[flag]];//顯示秒
DU = 1;
DU = 0;
P0 = table_W[flag];//數碼管1~8循環點亮
WE = 1;
WE = 0;
flag++;
if(flag >=8)
flag =0;
}
}
8.7本章小結
本章詳細介紹了數碼管的工作原理、鎖存器74HC573的工作原理及使用。數碼管的顯示控制以數碼管顯示中的定時器應用。
-
單片機
+關注
關注
6037文章
44558瀏覽量
635355 -
數碼管
+關注
關注
32文章
1882瀏覽量
91125 -
鎖存器
+關注
關注
8文章
906瀏覽量
41509 -
開發板
+關注
關注
25文章
5050瀏覽量
97483
發布評論請先 登錄
相關推薦
評論