一怪得、根據(jù)電路圖實(shí)現(xiàn)動(dòng)態(tài)數(shù)碼管
1. 對(duì)于動(dòng)態(tài)數(shù)碼管
首先需要知道的是咱枉,動(dòng)態(tài)數(shù)碼管是一種對(duì)數(shù)碼管的實(shí)現(xiàn)方式,并不是數(shù)碼管的種類徒恋,靜態(tài)數(shù)碼管也是一種實(shí)現(xiàn)方式蚕断,所以說,靜動(dòng)態(tài)的數(shù)碼管內(nèi)部結(jié)構(gòu)沒有差異入挣。
動(dòng)態(tài)數(shù)碼管常見于對(duì)多個(gè)數(shù)碼管進(jìn)行編程亿乳,采用掃描方式對(duì)各個(gè)數(shù)碼管給源給碼(源可以理解成電源,碼可以理解成段碼径筏,段碼即顯示的內(nèi)容)葛假,再通過單片機(jī)CPU的高速循環(huán),使各個(gè)數(shù)碼管得以同時(shí)呈現(xiàn)不同的數(shù)字匠璧。
2. 電路圖
可以看到桐款,該8位數(shù)碼管是通過J16給源,J12給碼的方式來實(shí)現(xiàn)數(shù)碼管的亮滅夷恍。電路圖中,數(shù)碼管將8個(gè)LED燈的引腳全部接到了J12口的八根線上媳维,統(tǒng)一給碼酿雪,再通過J16來控制。由于是共陰極數(shù)碼管侄刽,故當(dāng)J16對(duì)某一位給0時(shí)指黎,該位對(duì)應(yīng)的數(shù)碼管則亮。
注:74573本身是個(gè)鎖存器州丹,但在這個(gè)電路中沒有用到鎖存功能醋安,只是簡(jiǎn)單的當(dāng)作功放來用,用來驅(qū)動(dòng)發(fā)光管的功率放大墓毒。
3. 51 C編程
- 這里使用P0口控制數(shù)碼管的段碼位吓揪,P2口控制數(shù)碼管的COM口。
#include <reg51.h>
unsigned char screenNum[8]={1,3,5,7,2,4,6,8};
void printNum(int i,int state)
{
//0123456789AbCDEF
unsigned char num[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
if(state==0) P0=num[i]; //共陽(yáng)
else P0=~num[i]; //共陰
}
int main()
{
unsigned char i;
unsigned char j;
while(1)
{
for(i=0;i<8;i++)
{
P2=~(1<<i); // P2 接 J16 控制數(shù)碼管的亮滅
printNum(screenNum[i],1); //顯示數(shù)字
j=8;
while(j--) ; //延時(shí)
P0=0x0; //消隱
}
}
return 0;
}
- 注意:【消隱操作】在送出第N+1位的段碼前所计,一定要先把第N位的位段碼關(guān)閉柠辞,不然第N+1位的段碼會(huì)在第N位有個(gè)短暫的殘留。這個(gè)短暫的殘留影象就是殘影了主胧。
二叭首、配合38譯碼器實(shí)現(xiàn)動(dòng)態(tài)數(shù)碼管
1. 首先习勤,什么是38譯碼器?
38譯碼器有3個(gè)輸入端口A焙格、B图毕、C和8個(gè)輸出端口Y0~Y7。由輸入端口控制輸出端口的值眷唉。
2. 為什么使用38譯碼器予颤?
使用38譯碼器來控制數(shù)碼管的COM口可以節(jié)約IO口,其原理是:輸入口的3位總共可以代表8個(gè)十進(jìn)制數(shù)0-7厢破,分別對(duì)應(yīng)輸出端口的8個(gè)引腳荣瑟,使得38譯碼器實(shí)現(xiàn)以3個(gè)引腳控制八個(gè)輸出端口,不過這樣就造成8個(gè)端口無法同時(shí)被選中摩泪,一次只能選擇一個(gè)端口笆焰,但是在實(shí)現(xiàn)動(dòng)態(tài)數(shù)碼管時(shí)可以使用它來控制COM口,因?yàn)樵趧?dòng)態(tài)掃描過程中见坑,要的就是一次只選擇一個(gè)端口嚷掠。
3. 3個(gè)輸入端口如何控制8個(gè)輸出端口?
查詢74HC138芯片的數(shù)據(jù)手冊(cè)荞驴,可找到芯片的譯碼表不皆。
表中,Enable項(xiàng)已經(jīng)初始化好了熊楼,我們只需要關(guān)心Select項(xiàng)中的A霹娄、B、C輸入端口即可鲫骗。
4. 編程
- 這里使用P0口控制數(shù)碼管的段碼位犬耻,P2口控制數(shù)碼管的COM口。
#include <reg51.h>
unsigned char screenNum[8]={1,3,5,7,2,4,6,8};
unsigned char placeArr[8]={0x0,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
void printNum(int i,int state)
{
//0123456789AbCDEF
unsigned char num[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
if(state==0) P0=num[i]; //共陽(yáng)
else P0=~num[i]; //共陰
}
int main()
{
unsigned char i;
unsigned char j;
while(1)
{
for(i=0;i<8;i++)
{
P2 = placeArr[i];
printNum(screenNum[i],1);
j=100;
while(j--) ;
P0=0x0;
}
}
return 0;
}
5. 改進(jìn)
考慮到控制38譯碼器只用到P2的P2.0执泰、P2.1枕磁、P2.2三個(gè)引腳,其他引腳不應(yīng)該去改動(dòng)它們?cè)镜闹凳趿撸首饕韵赂倪M(jìn):
- 對(duì)P2.0计济、P2.1、P2.2三位清零排苍,然后在循環(huán)中每次加一來改變其內(nèi)的值沦寂。
- 每掃描一排,則重新清零再次累加纪岁。
#include <reg51.h>
unsigned char screenNum[8]={1,3,5,7,2,4,6,8};
void printNum(int i,int state)
{
//0123456789AbCDEF
unsigned char num[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
if(state==0) P0=num[i]; //共陽(yáng)
else P0=~num[i]; //共陰
}
int main()
{
unsigned char i;
unsigned char j;
while(1)
{
P2 &= 0xf8;
for(i=0;i<8;i++)
{
printNum(screenNum[i],1);
j=100;
while(j--) ;
P0=0x0;
P2 += 1;
}
}
return 0;
}
- 注意:需要將P2+=1放到消隱之后凑队,原因是:P2從000開始,若加1后再顯示則會(huì)發(fā)生錯(cuò)位。
三漩氨、【實(shí)例】使用動(dòng)態(tài)數(shù)碼管實(shí)現(xiàn)倒計(jì)時(shí)
- 接線與上圖相同
1. 使用延時(shí)函數(shù)實(shí)現(xiàn)倒數(shù)間隔
#include <reg51.h>
unsigned char screenNum[8]={1,3,5,7,2,4,6,8};
void printNum(int i,int state)
{
//0123456789AbCDEF
unsigned char num[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
if(state==0) P0=num[i]; //共陽(yáng)
else P0=~num[i]; //共陰
}
int main()
{
unsigned char i;
unsigned char j;
unsigned long count=10000;
unsigned int timeCount=0;
while(1)
{
unsigned long temp=count;
for(i=0;i<8;i++)
{
screenNum[7-i]=temp%10;
temp/=10;
}
P2 &= 0xf8;
for(i=0;i<8;i++)
{
printNum(screenNum[i],1);
j=100;
while(j--) ;
P0=0x0;
P2 += 1;
}
delay_ms(100);
count--;
}
return 0;
}
燒錄后發(fā)現(xiàn)西壮,數(shù)字變化時(shí)會(huì)閃爍。
經(jīng)分析叫惊,應(yīng)該是延時(shí)函數(shù)導(dǎo)致的款青,因?yàn)閯?dòng)態(tài)數(shù)碼管需要不斷掃描數(shù)碼管,如果存在延時(shí)函數(shù)則會(huì)中斷數(shù)字的顯示霍狰。
改進(jìn)后使用一個(gè)計(jì)數(shù)器來實(shí)現(xiàn)近似延時(shí)抡草,見2.
2. 使用計(jì)數(shù)器實(shí)現(xiàn)倒數(shù)間隔
#include <reg51.h>
unsigned char screenNum[8]={0,0,0,0,0,0,0,0};
void printNum(int i,int state)
{
//0123456789AbCDEF
unsigned char num[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
if(state==0) P0=num[i]; //共陽(yáng)
else P0=~num[i]; //共陰
}
int main()
{
unsigned char i;
unsigned char j;
unsigned long count=10000;
unsigned int timeCount=0;
while(1)
{
unsigned long temp=count;
if(timeCount++>100)
{
for(i=0;i<8;i++)
{
screenNum[7-i]=temp%10;
temp/=10;
}
timeCount=0;
count--;
}
//P2接38譯碼器控制數(shù)碼管COM口
P2 &= 0xf8; //P2.0-2置0
for(i=0;i<8;i++)
{
printNum(screenNum[i],1);
j=100;
while(j--) ; //延時(shí)
P0=0x0; //消隱
P2 += 1;
}
}
return 0;
}
這里還有兩個(gè)問題:
①數(shù)字變化間隔不為真正的一秒
②數(shù)字變化時(shí)會(huì)輕微閃爍
待解決。蔗坯。康震。