數碼管是非常常見的東西,他能顯示數字,以及字母,應用非常的廣泛,本文我來和大家談談如何用單片機來驅動數碼管
數碼管的結構
數碼管由7個發光二極管組成,行成一個日字形,它門可以共陰極,也可以共陽極.通過解碼電路得到的數碼接通相應的發光二極而形成相應的字,這就是它的工作原理.
基本的半導體數碼管是由7個條狀的發光二極管(LED)按圖1所示排列而成的,可實現數字"0~9"及少量字符的顯示。另外為了顯示小數點,增加了1個點狀的發光二極管,因此數碼管就由8個LED組成,我們分別把這些發光二極管命名為 "a,b,c,d,e,f,g,dp",排列順序如下圖1。
![]() |
||
圖1: 數碼管引腳圖及外形圖
|
數碼管的分類
數碼管按各發光二極管電極的連接方式分為共陽數碼管和共陰數碼管兩種。
共陰數碼管是指將所有發光二極管的陰極接到一起形成公共陰極(COM)的數碼管。共陰數碼管在應用時應將公共極COM接到地線GND上,當某一字段發光二極管的陽極為高電平時,相應字段就點亮。當某一字段的陽極為低電平時,相應字段就不亮。共陰數碼管內部連接如圖3所示。
共陽數碼管是指將所有發光二極管的陽極接到一起形成公共陽極(COM)的數碼管。共陽數碼管在應用時應將公共極COM接到+5V,當某一字段發光二極管的陰極為低電平時,相應字段就點亮。當某一字段的陰極為高電平時,相應字段就不亮。共陽數碼管內部連接如圖2所示。
![]() |
||
圖2:共陽數碼管內部連接圖
|
圖3:共陰數碼管內部連接圖
|
數碼管的顯示方式
數碼管要正常顯示,就要用驅動電路來驅動數碼管的各個段碼,從而顯示出我們要的數字,因此根據數碼管的驅動方式的不同,可以分為靜態式和動態式兩類。
① 動態顯示驅動:數碼管動態顯示接口是單片機中應用最為廣泛的一種顯示方式之一,動態驅動是將所有數碼管的8個顯示筆劃"a,b,c,d,e,f,g,dp"的同名端連在一起,另外為每個數碼管的公共極COM增加位選通控制電路,位選通由各自獨立的I/O線控制,當單片機輸出字形碼時,所有數碼管都接收到相同的字形碼,但究竟是那個數碼管會顯示出字形,取決于單片機對位選通COM端電路的控制,所以我們只要將需要顯示的數碼管的選通控制打開,該位就顯示出字形,沒有選通的數碼管就不會亮。通過分時輪流控制各個數碼管的的COM端,就使各個數碼管輪流受控顯示,這就是動態驅動。在輪流顯示過程中,每位數碼管的點亮時間為1~2ms,由于人的視覺暫留現象及發光二極管的余輝效應,盡管實際上各位數碼管并非同時點亮,但只要掃描的速度足夠快,給人的印象就是一組穩定的顯示數據,不會有閃爍感,動態顯示的效果和靜態顯示是一樣的,能夠節省大量的I/O端口,而且功耗更低。
②靜態顯示驅動:靜態驅動也稱直流驅動。靜態驅動是指每個數碼管的每一個段碼都由一個單片機的I/O端口進行驅動,或者使用如BCD碼二-十進制譯碼器譯碼進行驅動。靜態驅動的優點是編程簡單,顯示亮度高,缺點是占用I/O端口多,如驅動5個數碼管靜態顯示則需要5×8=40根I/O端口來驅動,要知道一個89S51單片機可用的I/O端口才32個呢:),實際應用時必須增加譯碼驅動器進行驅動,增加了硬件電路的復雜性。
前面我們學習了數碼管的基礎知識,現在馬上來看看S51增強型實驗板的數碼管吧(圖4),S51實驗板上有5位高亮度共陽數碼管DG1~DG5,可以用來做計數器(最大計數值99999)、溫度顯示、電子鐘等顯示實驗,掌握數碼管的靜態顯示驅動和動態顯示驅動。
圖4
|
S51增強型實驗板的數碼管驅動原理圖如下圖5所示。
圖5
|
從原理圖可以看出,S51增強型實驗板中數碼管的段碼a,b,c,d,e,f,g,dp分別與單片機的P0.0~P0.7相連,控制數碼管中顯示的字形;數碼管的位選通由5個PNP三極管控制,分別接到單片機的P2.0、P2.1、P2.2、P2.3、P2.4端口上,程序中通過控制P2.0~P2.4端口的輸出電平就可以控制數碼管的顯示與關閉。如P2.0輸出低電平時,三極管T1導通,+5V電源加到第一個數碼管的COM端,那么第一個數碼管DG1就會顯示出相應的數字,顯示的數字由單片機P0.0~P0.7輸出段碼決定,當P2.0輸出高電平時,三極管T1截止,數碼管DG1就不顯示,從而實現數碼管位選通控制。同理,當P2.1輸出低電平時,則數碼管DG2顯示。。。
單片機驅動數碼管的靜態顯示編程
上面我們學習了一大堆的理論知識,對數碼管已經有了較全面的認識,是否躍躍欲試了呀!馬上動手編一個簡單的程序驗證一下理論吧,現在我們編程讓實驗板上的第一個數碼管DG1顯示數字“6”,最終的實驗效果見上面圖4所示。
啟動Keil C51單片機集成開發環境,新建一個工程,工程命名為smg1.uv2,(不懂如何建立新工程的初學者請看網頁 手把手教你建立Keil工程),打開一個文本編輯窗,在文本編輯窗中輸入如下代碼:
;********** 下面是數碼管顯示"6"的程序 **********
MAIN:CLR P0.0;P0.0輸出低電平,點亮數碼管段碼"a"
SETBP0.1;P0.1輸出高電平,熄滅數碼管段碼"b"
CLR P0.2;P0.2輸出低電平,點亮數碼管段碼"c"
CLR P0.3;P0.3輸出低電平,點亮數碼管段碼"d"
CLR P0.4;P0.4輸出低電平,點亮數碼管段碼"e"
CLR P0.5;P0.5輸出低電平,點亮數碼管段碼"f"
CLR P0.6;P0.6輸出低電平,點亮數碼管段碼"g"
SETBP0.7;P0.7輸出高電平,熄滅數碼管小數點段碼"dp"
CLR P2.0;P2.0輸出低電平,選通數碼管DG1
SETBP2.1;P2.1輸出高電平,不選通數碼管DG2
SETBP2.2;P2.2輸出高電平,不選通數碼管DG3
SETBP2.3 ;P2.3輸出高電平,不選通數碼管DG4
SETBP2.4;P2.4輸出高電平,不選通數碼管DG5
AJMPMAIN;跳轉到開始重新進行
END ;程序結束
注:程序中分號“;”后面的中文為每一行程序的注釋,是方便我們閱讀程序的,可以不輸入。
上面的源程序輸入完畢后,保存為"smg1.asm",然后添加到工程smg1.uv2中,最后源程序經過編譯得到目標文件"smg1.hex"(見下面的圖6所示),不熟悉Keil工程建立、設置及源程序編譯等詳細操作的初學者請參考網頁 >>> 手把手教你建立Keil工程。>>>
圖6:點擊放大該圖
|
現在讓我們把目標文件"smg1.hex"燒寫到單片機中去,看看實際的效果吧,將ISP編程器硬件連接好(見下圖7)。
圖7:ISP
|
將產品配套光盤中的“ISP編程器驅動軟件”文件夾復制到你電腦硬盤的D盤根目錄下,并將其目錄下的所有文件的只讀屬性去掉,具體操作如下:全選文件夾中的文件,鼠標右鍵單擊出現文件屬性對話框,單擊“只讀”屬性前面復選框中的勾,使其只讀屬性去掉即可。然后雙擊文件夾中的“ISP編程器驅動軟件.exe”啟動編程軟件,點擊"文件",在打開文件的對話框中找到工程文件夾中的目標文件"smg1.hex"打開即可,然后點擊“AUTORUN”將程序燒寫到單片機內部(如下圖8)。
圖8:將程序燒寫到單片機內部
|
燒寫完成了,把單片機從編程器中取出,然后插到S51增強型實驗板上,插上USB電源,看看顯示效果是不是和上面圖4顯示一樣,是否有一點點的成就感呀!初學者也許會問:數碼管顯示一個數字“6”就要15行程序,太復雜了?的確有點復雜了,在上面程序中為了顯示數字“6”,數碼管的段碼"b"、段碼"dp"輸出的是高電平,其它引腳輸出的是低電平,實際上從單片機的P0.0~P0.7輸出的是二進制碼“10000010”,轉換成十六進制為82H。因此,我們只要把所有要顯示的數字和字符的段碼根據硬件連接編制一個字形表,顯示時直接把相應的字形碼送到P0口就可以了。
共陽LED數碼管字形(段碼)表
|
||||||||||
顯示數字
(字符) |
P0.7
"dp" |
P0.6
"g" |
P0.5
"f" |
P0.4
"e" |
P0.3
"d" |
P0.2
"c" |
P0.1
"b" |
P0.0
"a" |
二進制代碼
|
十六進制代碼
|
0
|
1
|
1
|
0
|
0
|
0
|
0
|
0
|
0
|
11000000
|
C0H
|
1
|
1
|
1
|
1
|
1
|
1
|
0
|
0
|
1
|
11111001
|
F9H
|
2
|
1
|
0
|
1
|
0
|
0
|
1
|
0
|
0
|
10100100
|
A4H
|
3
|
1
|
0
|
1
|
1
|
0
|
0
|
0
|
0
|
10110000
|
B0H
|
4
|
1
|
0
|
0
|
1
|
1
|
0
|
0
|
1
|
10011001
|
99H
|
5
|
1
|
0
|
0
|
1
|
0
|
1
|
1
|
0
|
10010110
|
92H
|
6
|
1
|
0
|
0
|
0
|
0
|
0
|
1
|
0
|
10000010
|
82H
|
7
|
1
|
1
|
1
|
1
|
1
|
0
|
0
|
0
|
11111000
|
F8H
|
8
|
1
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
10000000
|
80H
|
9
|
1
|
0
|
0
|
1
|
0
|
0
|
0
|
0
|
10010000
|
90H
|
A
|
1
|
0
|
0
|
0
|
1
|
0
|
0
|
0
|
10001000
|
88H
|
B
|
1
|
0
|
0
|
0
|
0
|
0
|
1
|
1
|
10000011
|
83H
|
C
|
1
|
1
|
0
|
0
|
0
|
1
|
1
|
0
|
11000110
|
C6H
|
D
|
1
|
0
|
1
|
0
|
0
|
0
|
0
|
1
|
10100001
|
A1H
|
E
|
1
|
0
|
0
|
0
|
0
|
1
|
1
|
0
|
10000110
|
86H
|
F
|
1
|
0
|
0
|
0
|
1
|
1
|
1
|
0
|
10001110
|
8EH
|
H
|
1
|
0
|
0
|
0
|
1
|
0
|
0
|
1
|
10001001
|
89H
|
O
|
1
|
1
|
0
|
0
|
0
|
0
|
0
|
0
|
11000000
|
A3H
|
P
|
1
|
0
|
0
|
0
|
0
|
1
|
0
|
0
|
10000100
|
8CH
|
N
|
1
|
1
|
0
|
0
|
1
|
0
|
0
|
0
|
11001000
|
C8H
|
從上面表格中可以看到,顯示“6”的十六進制段碼值為"82H",因此我們把剛才的程序修改一下,修改后的完整程序如下:
MAIN:MOV P0,#82H ;將數字"6"的段碼輸出到P0口
MOV P2,#0FEH;從P2口輸出數碼管選通代碼,即輸出二進制“11111110”
AJMPMAIN;跳轉到開始重新進行
END ;程序結束
看看修改后的程序將變得更加簡潔,直觀了,程序代碼從原來的15行減少到僅4行,一樣實現了相同的功能。這也就是我們要學習的編程技巧哦!在編程中盡量用最少的代碼實現相同的功能。程序第1行的功能是將要顯示的數字“6”的十六進制段碼"82H"送到P0口,程序第2行的功能就是將數碼管的選通代碼#0FEH(即二進制"11111110")送到P2口,從而控制第一位數碼管顯示,其它數碼管熄滅。把修改過的程序編譯后的目標文件寫到單片機上看到顯示效果是一樣的。程序中用一行代碼 MOVP0,#82H 就輸出了字形,因此我們要顯示其它字形時只要從上面的數碼管段碼表中查出對應的十六進制字形碼,用同樣的方法把段碼輸出到P0口就可以了。比如我們要顯示一個數字“8”, 只需將程序中的 MOVP0,#82H 語句改成 MOVP0,#80H 即可,至此,我們終于可以隨心所欲地控制數碼管要顯示的字形了,是不是很簡單呀 :) 。
另外,如果想讓第二位數碼管DG2顯示,其它熄滅怎么辦呢?其實很簡單,只要把對應數碼管的選通端口輸出低電平就可以使該位數碼管顯示了,如指令 CLRP2.1 就可以讓第二個數碼管顯示。。。程序中如果使P2.0~P2.4都輸出低電平,那么實驗板上的5個數碼管都會被選通,顯示出相同的字形,即顯示“66666”。下面就是5位數碼管顯示出“66666”的程序,初學者可以實驗一下,以加深對數碼管顯示位選通(使能)控制的理解。
MAIN:MOV P0,#82H ;將數字"6"的段碼輸出到P0口
MOV P2,#0E0H;從P2口輸出數碼管選通代碼,使5位數碼管均選通,即輸出二進制“11100000”
AJMPMAIN;跳轉到開始重新進行
END ;程序結束
單片機驅動數碼管的動態顯示編程
上面我們已經學習了數碼管靜態顯示,接下來我們就學習數碼管動態顯示編程,編程讓實驗板上的數碼管顯示“89C51”。從原理圖中(圖5)我們可以看到,5個數碼管的8個顯示筆劃"a,b,c,d,e,f,g,dp"的同名端是2連在一起的,那么當程序從P0口輸出字形碼時,在同一個時間所有數碼管都會接收到相同的字形碼。你一定會問,這樣不是5個數碼管都顯示相同的數字了嗎?如何顯示出5個不同的字符“89C51”呢?因此,就要使用動態掃描了,在程序中,首先顯示一個數,然后關掉;然后顯示第二個數,又關掉,顯示第三個數,又關掉。。。直到所有要顯示的5個數完成,再從頭開始掃描。輪流點亮掃描過程中,每位顯示器的點亮時間是極為短暫的(約1ms),由于人的視覺暫留現象及發光二極管的余輝效應,盡管實際上各位顯示器并非同時點亮,但只要掃描的速度足夠快,給人的印象就是一組穩定的顯示數據,不會有閃爍感。
數碼管顯示“89C51”的具體編程思路如下:第一位數碼管顯示“8” → 延時1ms → 關閉所有數碼管顯示 → 第二位數碼管顯示“9” → 延時1ms → 關閉所有數碼管顯示 → 第三位數碼管顯示“C” → 延時1ms → 關閉所有數碼管顯示 → 第四位數碼管顯示“5” → 延時1ms → 關閉所有數碼管顯示 → 第五位數碼管顯示“1” → 延時1ms → 關閉所有數碼管顯示 → 返回到第一步重新進行新一輪掃描過程。下面就是根據該思路編出來的源程序,初學者可以把該程序粘貼到Keil工程中,編譯得到目標文件,然后燒寫到單片機驗證一下。
; *********** 在數碼管上動態顯示"89C51" *************
MAIN: MOV P0,#80H;第1位數碼管顯示“8”
CLR P2.0 ;允許第1位數碼管顯示
ACALL DELAY;顯示延時一段時間
MOV P0,#0FFH ;清除P0口字形碼
MOV P2,#0FFH ;停止所有數碼管顯示選通,關閉所有顯示
MOV P0,#90H;第2位數碼管顯示“9”
CLR P2.1 ;允許第2位數碼管顯示
ACALL DELAY;顯示延時一段時間
MOV P0,#0FFH ;清除P0口字形碼
MOV P2,#0FFH ;停止所有數碼管顯示選通,關閉所有顯示
MOV P0,#0C6H ;第3位數碼管顯示“C”
CLR P2.2 ;允許第3位數碼管顯示
ACALL DELAY;顯示延時一段時間
MOV P0,#0FFH ;清除P0口字形碼
MOV P2,#0FFH ;停止所有數碼管顯示選通,關閉所有顯示
MOV P0,#92H;第4位數碼管顯示“5”
CLR P2.3 ;允許第4位數碼管顯示
ACALL DELAY;顯示延時一段時間
MOV P0,#0FFH ;清除P0口字形碼
MOV P2,#0FFH ;停止所有數碼管顯示選通,關閉所有顯示
MOV P0,#0F9H ;第5位數碼管顯示“1”
CLR P2.4 ;允許第5位數碼管顯示
ACALL DELAY;顯示延時一段時間
MOV P0,#0FFH ;清除P0口字形碼
MOV P2,#0FFH ;停止所有數碼管顯示選通,關閉所有顯示
AJMPMAIN ;跳轉到開始重新進行
;******** 延時子程序 ********
DELAY:MOV R1,#10
Y1: MOV R2,#100
DJNZR2,$
DJNZR1,Y1
RET
END
【總結】
至此,我們已經較全面地學習了數碼管的工作原理和使用方法,相信你對數碼管的靜態顯示、動態顯示有了新的認識,掌握了數碼管的這兩種使用方法,你就可以根據你自己的意愿及要求來編寫各種各樣的數字顯示程序了,如電子溫度計、時鐘、秒表、頻率計、計數器的制作等等,可以充分發揮你的想象達到你所需要的各種顯示效果。我們附帶的配套軟件資料光盤配有相關的實驗例程、實驗視頻錄像、單片機多媒體教程、實用電子圖書資料、單片機開發軟件及編程器、仿真器的全部驅動程序,供大家學習使用,以幫助初學者快速入門。