前言
前面我們已經介紹了如何使用51單片機控制靜態數碼管顯示,在實際應用中通常都需要顯示多位數值,如果采用靜態數碼管顯示就不夠好,因此就需要采用另外一種顯示方式,即數碼管動態顯示。開發板上板載2 個四位一體的共陰數碼管,接下來我們就來介紹下如何使用51 單片機控制動態數碼管顯示。本教程所要實現的功能是:控制動態數碼管從左至右顯示數字0-7。學習本節可以參考前面的實驗內容。
一、數碼管介紹
1.多位數碼管簡介
多位數碼管,即兩個或兩個以上單個數碼管并列集中在一起形成一體的數碼管。當多位一體時,它們內部的公共端是獨立的,而負責顯示什么數字的段線(a-dp)全部是連接在一起的,獨立的公共端可以控制多位一體中的哪一位數碼管點亮,而連接在一起的段線可以控制這個能點亮數碼管亮什么數字,通常我們把公共端叫做“位選線”,連接在一起的段線叫做“段選線”,有了這兩個線后,通過單片機及外部驅動電路就可以控制任意的數碼管顯示任意的數字了。
一般一位數碼管有10 個引腳, 二位數碼管也是10 個引腳, 四位數碼管是12 個引腳,關于具體的引腳及段、位標號大家可以查詢相關資料,最簡單的辦法就是用數字萬用表測量,若沒有數字萬用表也可用5V 直流電源串接1k 電阻后測量,將測量結果記錄,通過統計便可繪制出引腳標號。多位數碼管有許多是按一定要求設計的,引腳不完全按照一般規則設定,所以需要在使用時查找手冊,最直接的辦法就是按照數碼管上的標示向生產商要求。
我們開發板上使用了2 個四位一體的共陰數碼管,這樣可在上面同時顯示8個數值。
2.數碼管動態顯示原理
多位數碼管依然可以靜態顯示,但是顯示時要么只顯示一位數碼管,要么多位同時顯示相同內容。當多位數碼管應用于某一系統時,它們的“位選”是可獨立控制的,而“段選”是連接在一起的,我們可以通過位選信號控制哪幾個數碼管亮,而在同一時刻,位選選通的所有數碼管上顯示的數字始終都是一樣的,因為它們的段選是連接在一起的,送入所有數碼管的段選信號都是相同的,所以它們顯示的數字必定一樣,數碼管的這種顯示方法叫做靜態顯示。
而動態顯示,就是利用減少段選線,分開位選線,利用位選線不同時選擇通斷,改變段選數據來實現的。比如在第一次選中第一位數碼管時,給段選數據0,下一次位選中第二位數碼管時顯示1。為了在顯示1 的時候,0 不會消失(當然實際上是消失了),必須在人肉眼觀察不到的時間里再次點亮第一次點亮的0。而這時就需要記住,人的肉眼正常情況下只能分辨變化超過24ms 間隔的運動。也就是說,在下一次點亮0 這個數字的時間差不得大于24ms。這時就會發現,數碼管點亮是在向右或者向左一位一位點亮,形成了動態效果。如果把間隔時間改長就能直接展現這一現象。
數碼管動態顯示的應用非常多,所以大家一要認真學好數碼管的動態顯示方法。
二、74HC245 和74HC138 芯片介紹
通過前面內容的介紹我們知道,要使單片機能控制開發板上2 位一體的共陰數碼管顯示,僅靠單片機IO 口來驅動是不行的,這里就需要增加外部驅動芯片,開發板上使用的是74HC245 芯片。2 個4 位一體的共陰數碼管的位選線有8 根,直接讓單片機IO 口控制是沒有任何問題的,但考慮到51 單片機IO 口資源的限制,通常我們會使用一種IO 擴展芯片,比如74HC138、74HC164、74HC595 芯片等,只需要很少的單片機IO 口就可以擴展出8 個控制口,通過級聯方式甚至可擴展出更多的控制口(這個在后面LED 點陣實驗章節中會有詳細介紹)。我們開發板上使用的是74HC138 譯碼器芯片,只需單片機3 個IO 口就可以實現8 個位選管腳的控制,節省了芯片的IO 資源。
下面就來看看這兩個芯片功能及使用方法:
1.74HC245介紹
74HC245 是一種三態輸出、八路信號收發器,主要應用于大屏顯示,以及其它的消費類電子產品中增加 驅動 。
(1)主要特性
①采用CMOS 工藝
②寬電壓工作范圍:3.0V-5.0V
③雙向三態輸出
④八線雙向收發器
⑤封裝形式:SOP20、SOP20-2、TSSOP20、DIP20
(2)管腳功能定義
從上面的管腳功能定義說明及真值表可以知道該芯片使用方法很簡單,給OE使能管腳低電平,DIR 管腳為高電平傳輸方向是A->B 輸出,DIR 為低電平傳輸方向是B->A,至于輸出高電平還是輸出低電平取決于輸入端的狀態,如果輸入為低電平,輸出即為低;輸入為高電平,輸出即為高。如果OE 使能管腳為高電平,不論DIR 管腳是高還是低,輸出是高組態。
通常我們使用74HC245 芯片用作驅動只會讓其在一個方向輸出,即DIR 管腳為高電平,傳輸方向是A->B。
2.74HC245介紹
74HC138D 是一種三通道輸入、八通道輸出譯碼器,主要應用于消費類電子產品。
(1)主要特性
①采用CMOS 工藝
②低功耗
③工作電壓:3.0V-5.0V
④封裝形式:SOP16
(2)管腳功能定義
從上面的管腳功能定義說明及真值表可以知道該芯片使用方法很簡單,給E1、E2 使能管腳低電平,E3 管腳為高電平,至于哪個管腳輸出有效電平(低電平),要看A0,A1,A2 輸入管腳的電平狀態。如果A0,A1,A2 都為低電平,則Y0 輸出有效電平(低電平),其他管腳均輸出高電平。如果A0 為高電平,A1,A2 都為低電平,則Y1 輸出有效電平(低電平),其他管腳均輸出高電平。其他幾種輸出大家可以對照真值表查看。如果E1、E2 使能管腳任意一個為高電平或者E3 為低電平,不論輸入是什么,輸出都為高電平。
這里給大家總結一個方法:A0、A1、A2 輸入就相當于3 位2 進制數,A0 是低位,A1 是次高位,A2 是高位。而Y0-Y7 具體哪一個輸出有效電平,就看輸入二進制對應的十進制數值。比如輸入是101(A2,A1,A0),其對應的十進制數是5,所以Y5 輸出有效電平(低電平)。
三、硬件設計
本實驗使用到硬件資源如下:
(1)動態數碼管模塊
(2)74HC138
開發板上的動態數碼管模塊電路如下圖所示:
從上圖中可以看出,該電路是獨立的,動態數碼管的控制管腳并未直接連接到51 單片機的IO 上,而是段選端連接到J6 端子上,位選端連接到J1 端子上。段選端通過74HC245 芯片驅動這兩個共陰數碼管的a-dp 段。
如果要想51 單片機控制動態數碼管,就必須將單片機管腳通過導線連接到J6 端子和J1 端子上。因此需使用一根8Pin 排線將單片機的管腳與J6 端子順序連接,使用一根8Pin 排線將38 譯碼器的輸出J10 端子與J1 端子順序連接,使用3 根杜邦線將單片機的管腳與J9 端子連接。由于動態數碼管模塊電路是獨立的,所以使用任意單片機管腳都可以,為了與我們例程程序配套,這里使用P0口控制數碼管段選,使用P2.2、P2.3、P2.4 管腳控制74HC138 譯碼器輸入從而控制數碼管位選。
注意 :要保證P0 口的P00 與A 段到P0 口的P07 與DP 段依次順序連接,單片機的P22、P23、P24 口與38 譯碼器的A、B、C 連接,38 譯碼器的輸出J10 端子的Y0-Y7 與位選端子J1 的W1-W8 連接,不能交叉,否則使用例程程序就會出錯,默認我們已經使用8 個黃色短接片將38 譯碼器的輸出J10 與數碼管位選J1短接好。
四、軟件設計
本教程所要實現的功能是:控制動態數碼管從左至右顯示數字0-7。
#include< reg52.h >
typedef unsigned int u16;
typedef unsigned char u8;
#define SMG_A_DP_PORT P0//宏定義 定義段選
sbit LSA=P2^2;//定義位選
sbit LSB=P2^3;
sbit LSC=P2^4;
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共陰極數碼管
void delay_10us(u16 time_us)
{
while(time_us--);
}
void smg_display(void)
{
u8 i=0;
for(i=0;i< 8;i++)
{
switch(i)//位選
{
case 0: LSC=0;LSB=0;LSA=0;break;
case 1: LSC=0;LSB=0;LSA=1;break;
case 2: LSC=0;LSB=1;LSA=0;break;
case 3: LSC=0;LSB=1;LSA=1;break;
case 4: LSC=1;LSB=0;LSA=0;break;
case 5: LSC=1;LSB=0;LSA=1;break;
case 6: LSC=1;LSB=1;LSA=0;break;
case 7: LSC=1;LSB=1;LSA=1;break;
}
SMG_A_DP_PORT=gsmg_code[i];//傳送段選數據
delay_10us(100);//延時一段時間,等待顯示穩定
SMG_A_DP_PORT=0x00;//消音
}
}
void main()
{
while(1)
{
smg_display();
}
}
其中對于依次輸出段選信號時的for循環可以改為如下片段:
void smg_display(void)
{
u8 i=0;
for(i=0;i< 8;i++)
{
switch(7-i)//位選
{
case 0: LSC=1;LSB=1;LSA=1;break;
case 1: LSC=1;LSB=1;LSA=0;break;
case 2: LSC=1;LSB=0;LSA=1;break;
case 3: LSC=1;LSB=0;LSA=0;break;
case 4: LSC=0;LSB=1;LSA=1;break;
case 5: LSC=0;LSB=1;LSA=0;break;
case 6: LSC=0;LSB=0;LSA=1;break;
case 7: LSC=0;LSB=0;LSA=0;break;
}
SMG_A_DP_PORT=gsmg_code[i];//傳送段選數據
delay_10us(100);//延時一段時間,等待顯示穩定
SMG_A_DP_PORT=0x00;//消音
}
}
main.c 文件內代碼非常少也很簡單,首先將51 單片機的頭文件包含進來,然后定義38 譯碼器的控制引腳,并將共陰數碼管0-F 段碼數據使用數組定義好。主函數功能也很簡單,直接進入while 循環,在循環體內執行smg_display()數碼管動態顯示函數。該函數是根據動態數碼管顯示原理所編寫,即選中所要顯示的那位數碼管,然后發送在該位數碼管上所要顯示的段碼數據,延時一定時間后在將段選口清零即消隱(消除之前的顯示),如此循環8 次即可實現8 位數碼管顯示。在動態顯示中,要注意延時時間,只要保證在人肉眼所能感覺時間之內即可,讓我們看到所要顯示的內容就像是同時顯示一樣。如果時間過長或者過短都可能會影響數碼管的顯示效果,大家可以在例程基礎上試著修改延時時間觀察效果。
評論