第11集
一、數碼管工作原理
數碼管顯示亮度高,響應速度快,可以在一些比較差的環境中使用。有1位、2位、4位、8位連體等。。。也有專用于顯示時間的數碼管。
如圖,一位數碼管由8個二極管構成,7個構成“日”字型,1個是小圓點。分共陰和共陽。 共陰:所有二極管的負極連接在一起,接到電源負極。共陽:所有二極管的正極連接在一起,接到電源正極。(圖(a)引腳畫錯了。)
驅動的原理都很簡單,如共陽型數碼管的驅動。圖(b)右邊的電路圖可以看出,所有的二極管正極都接在電源正極,a、b、c、d、e、f、g、dp都接在單片機的IO口上,在《51單片機復習筆記1》:http://www.zg4o1577.cn/mcu/2111.html 中介紹過驅動二極管的原理,所以這里只需要在相應的二極管負極給低電平即可讓相應的二極管發光。
這里補充一下,為什么給高電平二極管就不亮,給低電平就亮呢。因為單片機是TTL電平,也就是說高電平即輸出5V,低電平就不輸出電壓0V,二極管的正極接在電源的正極那就是5V,那么二極管的負極如果也給高電平的話,那么就相當于在二極管的負極也接到了5V,二極管兩端都是5V 沒有電勢差,就相當于沒有通電一樣,自然不會發光。給低電平即0V,那么二極管就有一個5V的電勢差且是正向偏置,二極管自然就發光了,共陰型恰好相反。
看下圖(設共陽型),假如我們要讓數碼管顯示‘1’,那么只需要給b、c段的二極管低電平,其他為高電平即可讓數碼管顯示‘1’。假如我們要讓數碼管顯示‘2’,那么只給a、b、g、e、d低電平即可讓數碼管顯示‘2’。要顯示什么,只給相應的發光二極管低電平即可。
那么在實際編程中應該怎么寫程序呢。
我們將a、b、c、d、e、f、g、dp八個引腳接到單片機的P1口,P1^0←a、P1^1←b.....P1^7←dp。畫紅框的是低四位。那么如果要顯示2。
P1^0 = a =0、P1^1 = b = 0、P1^6 = g = 0、P1^4 = e = 0、P1^3 = d = 0
剩余的為1那么就是:1010 0100 = 0xA4
程序代碼中將0xA4賦值給P1即可,如 P1 = 0xA4; 看圖。
由于數碼管需要占用單片機的IO口很多,所以一般會搭配74HC573芯片來擴展IO口。《51單片機復習筆記1》有介紹該芯片的使用方法。驅動原理一樣。
數碼管顯示方式有兩種:
靜態顯示:其實和上面一樣,如P1=0xA4; 那么P1一直維持0xA4那么數碼管的每一段二極管的狀態都會保持字形不變。變動P1的電平狀態才會改變新字形。優點是占用CPU時間少。缺點是占用IO口多硬件設計復雜,特別是控制多位數碼管時尤為占用IO口,成本較高。
動態顯示:動態其實就是利用發光二極管的余暉和人眼視覺暫留作用。控制多位數碼管時,將所有數碼管的段選并聯在一起,由位選線控制是哪位數碼管接受段選編碼。如下圖一樣。
例如:
P0組是并聯所有數碼管的段選。P2^6、P2^7選擇哪位數碼管。我要顯示520,那么 首先選中第一位數碼管,然后送數字5的段編碼控制段選的P0口。
然后再選中第二位數碼管,再送數字2的段選編碼給P0,這時候第一位數碼管雖然斷電,但是二極管并沒有瞬間熄滅,所以還有余暉保持字形。
繼續再選中第三位數碼管送數字0的段選編碼給P0,這時候第一、第二位數碼管雖然都斷電,但由于切換速度太快,余暉仍沒有完全熄滅就造成三位數碼管同時顯示不同的數字字型的假象。
上圖是六位共陰型數碼管搭配兩片74HC573芯片的電路圖。L2是控制數碼管的a、b、c、d、e、f、g、dp,L3是選擇要顯示的數碼管。
下圖是74HC573芯片接在單片機上的10個IO口。(完美詮釋74HC573的實用性,哈哈~)
下圖是編碼列表
利用數碼管顯示秒表程序源碼:
/*****************************************
* 說明:動態顯示方式控制數碼管。秒表源碼
* 設計者:L、QQ:1007566569
* 開發板:DB-51 Ver2.1
* 數碼管:六位共陰型
******************************************/
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit dual = P2^6;// 控制 L2的74HC573芯片是否鎖存
sbit weal = P2^7;// 控制 L3的74HC573芯片是否鎖存
uchar aa;
// 數碼管顯示數字的編碼 table[0] 就是顯示 0
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
// 要顯示指定數字的數碼管
uchar code tablewe[]={
0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
#define Time 50000
#define YsTime 1
void ShowTime(uchar bai, uchar shi, uchar ge);
void delay(uint z);
/******** 主函數 ********/
void main()
{
uchar b, s, g;
TMOD = 0x01;// 選擇定時器工作方式 1
TH0=(65536-Time)/256;// (65536 - (50000/(12*(1/12))))/256 ;
TL0=(65536-Time)%256;// (65536 - (50000/(12*(1/12))))%256 ;
EA=1; // 開啟總中斷
ET0=1;// 開啟定時器 0 中斷
TR0=1;// 啟動定時器 0
while(1)
{
if(aa == 20)// 50ms*20 = 1000ms = 1s
{
aa = 0;
g ++; // 個位自增
if(g == 10)
{
s++; // 十位自增
g = 0;
}
if(s == 10)
{// 百位自增
b++;
s = g = 0;
}
if(b == 10)
b = s = g = 0;
}
ShowTime(table[b], table[s], table[g]);
}
}
/******** 數碼管顯示函數 ********/
void ShowTime(uchar bai, uchar shi, uchar ge)
{
// 顯示百位
dual = 1;
P0 = bai;
dual = 0;
P0 = 0xff;
weal = 1;
P0 = 0xfe;
weal = 0;
delay(YsTime);
// 顯示十位
dual = 1;
P0 = shi;
dual = 0;
P0 = 0xff;
weal = 1;
P0 = 0xfd;
weal = 0;
delay(YsTime);
// 顯示個位
dual = 1;
P0 = ge;
dual = 0;
P0 = 0xff;
weal = 1;
P0 = 0xfb;
weal = 0;
delay(YsTime);
}
/******** 延時函數 ********/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/******** 中斷函數 每50ms觸發一次 ********/
void timer0() interrupt 1
{
TH0=(65536-Time)/256;
TL0=(65536-Time)%256;
aa++;
}
也有采用BCD-7段譯碼芯片:共陽型的74LS48、74LS49、CD4511。共陰的74LS46、74LS47、CD4513。
第十二集
霖鋒教程中的是兩個四位一體共陰型數碼管,通過一片74HC573芯片控制兩個四位數碼管的段選,通過一片74HC138芯片選擇位數碼管(即位選)。
74HC138的引腳說明:
先把一些簡單的引腳說一下:
GND接地、VCC接電源正極。
E1、E2:低電平有效,如果其中一個為高電平則無法操控芯,Y0 — Y7 輸出全高電平。
E3:高電平有效,如果為低電平則無法操控芯片,Y0 — Y7 輸出全高電平。
如果要控制芯片首先是 VCC和GND接電源,E1、E2低電平或接低,E3高電平。
下面這三個引腳是比較重要的:
A組IO口是輸入,Y組端口是輸出。
A0、A1、A2是用來控制Y0 — Y7 輸出電平狀態,往里面輸入八進制數即可指定Y0 — Y7中其中一個為低電平。例如想要 Y5 為低電平,那么5的八進制為101,只需要給 A2 = 1、A1=0、A0=1,即可讓Y5為低電平。想要Y3為低電平,那么3的八進制為011,只需要給A2 = 0、A1 = 1、A0 = 0 即可。
記住,A組IO只是控制Y組的某一IO輸出低電平而已,其余都為高電平。
教程中有八位數碼管,所有剛好Y組全部都用上。