數碼管可以說是顯示屏的一種, 通過控制其不同管腳的電流通斷,會使其發光,從而顯示出數字。因此它能夠顯示時間、日期、溫度等所有可用數字表示的信息。由于它的價格便宜,使用簡單,在電器特别是家電領域應用極為廣泛,空調、熱水器、冰箱等等。絕大多數需要顯示的小家電都是使用數碼管,再複雜一點的應用則會采用液晶屏與熒光屏等。
數碼管結構
數碼管也稱LED數碼管,常用段數一般為7段,也有的另加一個小數點。也就是說一位數字就需要用到8個LED小燈。數碼管根據LED的接法不同分為共陰和共陽兩類:
共陽數碼管是指将所有發光二極管的陽極接到一起形成公共陽極(COM)的數碼管,共陽數碼管在應用時應将公共極COM接到 5V,當某一字段發光二極管的陰極為低電平時,相應字段就點亮,當某一字段的陰極為高電平時,相應字段就不亮。
共陰數碼管是指将所有發光二極管的陰極接到一起形成公共陰極(COM)的數碼管,共陰數碼管在應用時應将公共極COM接到地線GND上,當某一字段發光二極管的陽極為高電平時,相應字段就點亮,當某一字段的陽極為低電平時,相應字段就不亮。
當數碼管特定的段加上電壓後,這些特定的段就會發亮,以形成我們眼睛看到的字樣了。如:顯示一個“2”字,那麼應當是A亮B亮G亮E亮D亮;F不亮C不亮dp不亮。因此常用LED數碼管可以顯示的數字和字符是0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。
LED數碼管引腳定義
當然,也有更加複雜一點的數碼管,如下圖,我們就不詳加介紹了。
驅動方式
想要驅動數碼管顯示出我們想要的數字其實非常簡單,隻要對不同的LED段加上相應的電壓就行。但是想象一下,如果需要顯示下圖的時間13點08分,我們需要控制20個LED,使其亮;12個LED,使其滅。每個LED接一條線路,就要接32條,這樣其實是十分浪費資源的。
因此數碼管的驅動方式十分靈活,可以分為靜态驅動和動态驅動兩類。
靜态顯示驅動:
靜态驅動也稱直流驅動。靜态驅動是指每個數碼管的每一個段碼都由一個單片機的I/O端口進行驅動,或者使用如BCD碼二-十進制譯碼器譯碼進行驅動。靜态驅動的優點是編程簡單,顯示亮度高,缺點是占用I/O端口太多,如驅動5個數碼管靜态顯示則需要5×8=40根I/O端口來驅動。要知道一個89S51單片機可用的I/O端口才32個,實際應用時必須增加譯碼驅動器進行驅動,增加了硬件電路的複雜性。
動态顯示驅動:
數碼管動态顯示接口是單片機中應用最為廣泛的一種顯示方式之一,動态驅動是将所有數碼管的8個顯示筆劃"a,b,c,d,e,f,g,dp"的同名端連在一起,另外為每個數碼管的公共極COM增加位選通控制電路,位選通由各自獨立的I/O線控制,當單片機輸出字形碼時,所有數碼管都接收到相同的字形碼,但究竟是哪個數碼管會顯示出字形,取決于單片機對位選通COM端電路的控制,所以我們隻要将需要顯示的數碼管的選通控制打開,該位就顯示出字形,沒有選通的數碼管就不會亮。通過分時輪流控制各個數碼管的的COM端,就使各個數碼管輪流受控顯示,這就是動态驅動。在輪流顯示過程中,每位數碼管的點亮時間為1~2ms,由于人的視覺暫留現象及發光二極管的餘輝效應,盡管實際上各位數碼管并非同時點亮,但隻要掃描的速度足夠快,給人的印象就是一組穩定的顯示數據,不會有閃爍感,動态顯示的效果和靜态顯示是一樣的,能夠節省大量的I/O端口,而且功耗更低。
現實應用中,絕大部分的數碼管都是動态顯示的,隻是人眼看不出效果而已。但我們可以借助手機來驗證這一點。當我們将快門速度調慢,拍下的數碼管照片就是完整的顯示數字;當快門速度調快到一定速度時,拍下的顯示數字就是不完整的,這也就說明了這個數碼管是采用動态顯示的驅動方式。
快門速度1/24 時拍下的照片
快門速度1/625 時拍下的照片
模塊介紹下面我們來着重介紹一下一個八位的LED數碼管模塊的結構和驅動方式。
八位數碼管顯示模塊
一個八位的數碼管總共有64個LED,我們不可能用64個I/O引腳去控制,因此需要一個驅動芯片。這個模塊采用的是MAX7219芯片。它是一種集成化的串行輸入/輸出共陰極顯示驅動器。它連接微處理器與8位數字的7段數字LED顯示,也可以連接條線圖顯示器或者64個獨立的LED。其上包括一個片上的B型BCD編碼器、多路掃描回路,段字驅動器,而且還有一個8*8的靜态RAM用來存儲每一個數據。隻需要3個I/O口就能驅動8位數碼管,可以說效率是很高了。整個模塊的電路圖如下:
主要參數:
引腳定義:
下面我們就用Arduino UNO驅動8位數碼管模塊工作吧。
硬件設備:
接線圖:
将驅動模塊的DIN、CS、CLK分别連到Arduino 12、11、10數字引腳上,連接電源和接地線。
程序:
在編程之前我們需要知道一位數碼管對應顯示各個數字字符的段碼。我們可以用這樣的一個小程序進行查詢。例如數字2,它的段碼正碼就是5B,反碼就是A4,分别對應共陽和共陰的數碼管。
數字2的段碼查詢
//數碼管顯示程序
//事先輸入查詢好的各個字符的段碼
uint8_t SEGPLAY[] = { 0xC0, //"0"
0xF9, //"1"
0xA4, //"2"
0xB0, //"3"
0x99, //"4"
0x92, //"5"
0x82, //"6"
0xF8, //"7"
0x80, //"8"
0x90, //"9"
// 0x88, //"A"
// 0x83, //"B"
// 0xC6, //"C"
// 0xA1, //"D"
// 0x86, //"E"
// 0x8E, //"F"
// 0x89, //"H"
// 0xC7, //"L"
// 0xC8, //"n"
// 0xC1, //"u"
// 0x8C, //"P"
// 0xA3, //"o"
// 0xBF, //"-"
// 0xFF, //熄滅
// 0xFF //自定義
};
//定義位碼,也就是1到8位的數碼管的代碼
uint8_t DIG[] = {0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
};
//定義三個引腳
#define latchPin 10
#define clockPin 11
#define dataPin 12
void setup() {
//定義三個引腳為輸出
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop()
{
playnum (1308, 5014); //顯示 13085014
delay(20);
}
//
//函數作用:用于兩個四位數碼管顯示數字
//輸入值:unsigned int 範圍0-9999 //
//返回值: 無 //
void playnum (unsigned int i, unsigned int j)
{
SegDisplay(i / 1000, 0);
SegDisplay((i % 1000) / 100, 1);
SegDisplay((i % 100) / 10, 2);
SegDisplay((i % 10), 3);
SegDisplay( j / 1000, 4);
SegDisplay((j % 1000) / 100, 5);
SegDisplay((j % 100) / 10, 6);
SegDisplay((j % 10), 7);
}
//
//函數作用:用于單位數碼管顯示數字
//輸入值:i 範圍0-11 //
// 顯示位置 1-4 //
//返回值: 無 //
void SegDisplay(int i, int j)
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, DIG[j]); //位選
shiftOut(dataPin, clockPin, MSBFIRST, SEGPLAY[i]);//段選
digitalWrite(latchPin, HIGH);
delayMicroseconds(500);//調節這個和下面的參數可以調整顯示亮度,建議這兩個數加起來為860。這樣是為了顯示時間準确
// delayMicroseconds(360);
}
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!