本文是江協科技up的課堂筆記!大家可以去bilibili配合這位up的51單片機入門教程食用,效果更佳~
我這里進行詳細介紹,希望你忘記數碼管的時候來這里看看!(你猜我為什么寫這個TAT)
一.基本介紹
LED數碼管:數碼管是一種簡單、廉價的顯示器,是由多個發光二極管封裝在一起組成“8”字型的器件
下面介紹引腳連接和段的概念

這個圖顯示的是數碼管從A-DP這八個段,對應一個字節的八個比特位
這是引腳定義,類似單片機,一號引腳也是在左下角,呈逆時針排列
這個叫做共陰極連接,右邊的叫做共陽極連接,我們觀察引腳分布和各個段的引腳鏈接,我們發現在電路上是就近原則的
3.8引腳是公共的陰極
二.顯示一個數字
比如說我們要顯示數字六:ACDEFG點亮,其他熄滅就可以(以共陰極為例!!!)
步驟:
1.公共端接地(位選端選中)——決定哪個數字“8”亮起
2.把下面棕色的數字輸入進去(段碼)——決定哪根LED亮起
接下來看看更復雜的四位一體數碼管!
上圖是共陰極,下圖是共陽極
相信聰明的你發現規律了:單個數碼管是八個段引腳加上兩個陰極的引腳,而四位一體就是把相同的引腳連在一起控制,然后再支出另外四個引腳作為每個數碼管的陰極(還是以共陰極為例)
自然想到通過控制陰極端口的電平高低來控制哪一個數碼管亮啦(負極接正極,那他就必然不會亮啊),然后控制其余引腳來控制他亮起來的數字是幾
但是就出現了一個問題,我的數碼管無論同時亮起幾個都只能顯示一個數字(比如我讓第一個和第三個亮起,但是如果讓1號亮起數字‘6’,第3號也只能亮起6)畢竟段的選擇是公用的引腳
公用引腳可以減少io口的使用,但是如何讓多位數字同時顯示呢?
U4的用途是雙向數據緩沖器,最下面的四個東西:
VCC:正極,GND:負極;OE:把它理解為下面的那個使能端得了,低電平有效,不用管;
DIR:方向選擇,看是把左邊的數據緩沖到右邊還是把右邊的數據輸送到左邊
(其實是接高電平就把數據輸送到右邊,這個是我買的電路,他是沒有跳線改變輸送方向的,直接連接正極,有些帶有跳線的是可以改變它的方向的)
不用這個芯片的話,左側的信號就是驅動,加入芯片他就是信號源;只需要低強度信號,讓芯片接受,再加上芯片有自己的電源,就可以加強信號啦
那些電阻是排阻,四位一體的電阻元件
原理已知,首先我要在LED1-8這些個引腳里來進行位選,如何進行?
138譯碼器解決這個問題,它使用三個端口就可以解決問題
具體怎么做?
ABC表示輸入端,右側就是輸出端,左下角就是使能端(其實不用管,知道這么接他就會工作就行)CBA是一次高位到低位
因為2^3=8,所以在abc處用二進制表示后,轉換到0-7這八個數,分別對應LED1-8(這里有個很無語的錯位哈。)
下圖標的Y0一杠的橫線表示0有效,就是說比如CBA順序是000,就是Y0有效,即Y0是0,其他都是1
(問題又來了,這樣搞得話,不就只有一個數碼管可以亮了嗎)
代碼實現:
#include <REGX52.H>unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};void Nixie(unsigned char Location,Number)
{switch(Location){case 1:P2_4=1;P2_3=1;P2_2=1;break;case 2:P2_4=1;P2_3=1;P2_2=0;break;case 3:P2_4=1;P2_3=0;P2_2=1;break;case 4:P2_4=1;P2_3=0;P2_2=0;break;case 5:P2_4=0;P2_3=1;P2_2=1;break;case 6:P2_4=0;P2_3=1;P2_2=0;break;case 7:P2_4=0;P2_3=0;P2_2=1;break;case 8:P2_4=0;P2_3=0;P2_2=0;break;}P0=NixieTable[Number];
}void main()
{
// //CBA的順序讀
// //6號led對應的是Y5
// P2_4=1;
// P2_3=0;
// P2_2=1;
// //數據的高位對應端口的高位
// P0=0x7D;Nixie(1,10);while(1){;}
}
各位要注意,數字是從下往上讀的!!!高位對高位
三.動態數碼管顯示
多個位顯示不同的數字,如何做到
原理就是讓數碼管不斷循環,這一個是1,下一個是2,在下一個是3,這樣的話借著快速移動的數字加上他熄滅的時間以及人眼的視覺暫留就可以達到效果
初次嘗試:
#include <REGX52.H>
#include <intrins.h>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};void Delay(unsigned int xms) //@11.0592MHz
{unsigned char i, j;while(xms--){_nop_();_nop_();_nop_();i = 11;j = 190;do{while (--j);} while (--i);}
}void Nixie(unsigned char Location,Number)
{switch(Location){case 1:P2_4=1;P2_3=1;P2_2=1;break;case 2:P2_4=1;P2_3=1;P2_2=0;break;case 3:P2_4=1;P2_3=0;P2_2=1;break;case 4:P2_4=1;P2_3=0;P2_2=0;break;case 5:P2_4=0;P2_3=1;P2_2=1;break;case 6:P2_4=0;P2_3=1;P2_2=0;break;case 7:P2_4=0;P2_3=0;P2_2=1;break;case 8:P2_4=0;P2_3=0;P2_2=0;break;}P0=NixieTable[Number];}void main()
{Nixie(1,10);while(1){Nixie(1,1);
// Delay(20);Nixie(2,2);
// Delay(20);Nixie(3,3);
// Delay(20);}
}
這個會出現數字串位的情況,因為數碼管的消影過程中
//位選 段選 位選 段選
?//在這個過程中,位變了,但是還沒來得及變化段,所以上一個數字會串到下一位
//所以我們可以對段選清零
從而我們對函數進行了優化
#include <REGX52.H>
#include <intrins.h>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};void Delay(unsigned int xms) //@11.0592MHz
{unsigned char i, j;while(xms--){_nop_();_nop_();_nop_();i = 11;j = 190;do{while (--j);} while (--i);}
}void Nixie(unsigned char Location,Number)
{switch(Location){case 1:P2_4=1;P2_3=1;P2_2=1;break;case 2:P2_4=1;P2_3=1;P2_2=0;break;case 3:P2_4=1;P2_3=0;P2_2=1;break;case 4:P2_4=1;P2_3=0;P2_2=0;break;case 5:P2_4=0;P2_3=1;P2_2=1;break;case 6:P2_4=0;P2_3=1;P2_2=0;break;case 7:P2_4=0;P2_3=0;P2_2=1;break;case 8:P2_4=0;P2_3=0;P2_2=0;break;}P0=NixieTable[Number];Delay(1);//先讓他穩定的亮一會,否則就會亮度過低P0=0x00;//讓他熄滅
}void main()
{Nixie(1,10);while(1){Nixie(1,1);
// Delay(20);Nixie(2,2);
// Delay(20);Nixie(3,3);
// Delay(20);//數碼管的消影//位選 段選 位選 段選// 【 】//在這個過程中,位變了,但是還沒來得及變化段,所以上一個數字會串到下一位//所以我們可以對段選清零}
}