微處理器C51-5輸出輸入端口_第1頁
微處理器C51-5輸出輸入端口_第2頁
微處理器C51-5輸出輸入端口_第3頁
微處理器C51-5輸出輸入端口_第4頁
微處理器C51-5輸出輸入端口_第5頁
已閱讀5頁,還剩65頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

輸出/輸入端口的應(yīng)用如何申請免費樣片輸出端口的應(yīng)用輸入口的應(yīng)用輸入輸出端口的高級應(yīng)用輸出端口的應(yīng)用輸出電路的設(shè)計89S51的輸出端口可直接連接數(shù)字電路,也可驅(qū)動LED、蜂鳴器、繼電器或固態(tài)繼電器等負(fù)載。1、驅(qū)動LEDLED具有二極管的特點,其特性曲線如圖,通過增加LED正向電流可以使其更亮,但會縮短其壽命或燒斷,以10-20mA為宜。89S51的I/O端口都有類似漏極開路的輸出,其中P1、P2與P3內(nèi)部具有30KΩ上拉電阻,它們不能輸出10-20mA電流,其電路如圖。此電路中,當(dāng)輸出低電平時,輸出端FET導(dǎo)通,輸出電壓接近0V;而LED正向?qū)妷簽榧s1.7V,限流電阻R兩端約3.3V(VCC=5.0V),此時限流電阻值為:R=(5-1.7)/0.01=330Ω

對于TTL電平的數(shù)字電流,LED所串接的限流電阻大多為470Ω。2、驅(qū)動蜂鳴器

蜂鳴器(buzzer)類似小型喇叭,一般用作電路板上的發(fā)聲裝置。它分為電壓型與脈沖型兩類,電壓型送電即響,其頻率固定;脈沖型必須加入脈沖信號,聲音頻率就是加入脈沖的頻率。

在此使用脈沖型蜂鳴器。

89S51驅(qū)動蜂鳴器的信號為各種頻率的脈沖,其驅(qū)動方式采用達林頓管,或以兩個常用的小三極管(cs9013)連接成達林頓結(jié)構(gòu)。如圖,這兩個驅(qū)動電路屬高電平動作,即輸出“1”蜂鳴器吸住。也可采用低電平動作,如圖輸出0時,蜂鳴器吸?。惠敵?時,蜂鳴器釋放。在晶體管BE之間連接一個泄放電阻(3.3KΩ),其目的是讓晶體管從飽和到截止時提供一個泄放BE間少數(shù)載流子的路徑,以加快切換,放止拖音。3、驅(qū)動繼電器

若要89S51控制不同電壓或較大電流的負(fù)載時,則可以通過繼電器(RELAY)來實現(xiàn)。

電路板上使用的繼電器體積小,使用電壓有DC12V、DC9V、DC6V和DC5V等,圖中,c-b之間為常閉(NC)觸點,c-a之間為常開(NO)觸點,只有一組觸點,稱為1P。89S51驅(qū)動的繼電器大多為DC6V或DC5V,盡管如此,89S51輸出口的驅(qū)動能力還是不夠的,而且,繼電器線圈感性負(fù)載還需要保護。如圖a為高電平驅(qū)動的繼電器驅(qū)動電路。

如圖b為低電平驅(qū)動繼電器電路圖。

對于微型計算機系統(tǒng),采用低電平動作的繼電器驅(qū)動電路屬于較優(yōu)的設(shè)計。

由于線圈是電感負(fù)載,續(xù)流二極管起到保護晶體管的損壞。

如果要同時驅(qū)動多個繼電器。可使用集電極開路(OC)輸出的反相門,如7405(驅(qū)動5V繼電器)或7406(驅(qū)動較高電壓繼電器,最高30V)。4、驅(qū)動固態(tài)繼電器

固態(tài)繼電器(SSR)類似一般繼電器,可用較小的控制信號來驅(qū)動,以控制較大的負(fù)載。SSR沒有實際的觸點,不會有觸點動作的火花與機械動作。一般SSR是由光耦合器輸入控制信號,而另一端則是較大容量的功率半導(dǎo)體器件(如SCR、TRIAC或IGBT)。

如圖為常見的SSR,其輸出端為AC250V/10A。SSR的輸入端為LED,所以其驅(qū)動方法與LED一樣,不過需要較大的電壓和電流。

如圖a為高電平驅(qū)動電路;圖b為低電平驅(qū)動電路。5、驅(qū)動七段數(shù)碼管

七段LED數(shù)碼管是利用7個LED組合而成的顯示裝置,可以顯示0-9數(shù)字和A-F字母。七段LED數(shù)碼管有共陰極與共陽極兩種。共陽極(CommonAnode)七段LED數(shù)碼管

電路連接如圖a,com接+5V,每個陰極引腳各接一個限流電阻。圖b為不合理的接法。若a接8051輸出端口的最低位(LSB),dp接8051的最高位(MSB),則0-9的驅(qū)動信號如表所示(小數(shù)點不亮)。共陰極(CommonCatchode)七段LED數(shù)碼管

電路連接如圖a,com接GND,每個陽極引腳各接一個限流電阻。圖b為不合理的接法。若a接8051輸出端口的最低位(LSB),dp接8051的最高位(MSB),則0-9的驅(qū)動信號如表所示(小數(shù)點不亮)。實例1、驅(qū)動蜂鳴器電路

蜂鳴器由P3.7經(jīng)晶體管驅(qū)動。聲音產(chǎn)生原理

聲音是蜂鳴器簧片振動產(chǎn)生的,若要產(chǎn)生f的頻率,需要在周期T時間內(nèi)進行吸、放各一次,即通斷時間各1/2T。程序設(shè)計

本程序?qū)a(chǎn)生1KHz信號持續(xù)0.1s,停止0.5s,再產(chǎn)生1KHz信號持續(xù)0.1s停止0.5s,然后從頭開始執(zhí)行。/*ch01.c-----蜂鳴器程序-----*///*******聲明區(qū)**********#include<reg51.h>sbitbuzzer=P3^7;voiddelay(int);voidpulse_BZ(int,int,int);//******主程序*********Main(){while(1){pulse_BZ(100,1,1);delay(1000);}}//****子程序*******/*延遲函數(shù)x×0.5ms*/voiddelay(intx){inti,j;for(i=0;i<x;i++)for(j=0;j<60;j++);}/*蜂鳴器發(fā)聲函數(shù)count計數(shù)TH高電平時間TL低電平時間*/voidpulse_BZ(intcount,intTH,intTL){inti;for(i=0;i<count;i++){buzzer=1;delay(TH);buzzer=0;delay(TL);}}對程序進行仿真調(diào)試,如圖高電平持續(xù)時間為0.000944-0.000422=0.000522s

同樣,低電平持續(xù)時間也為0.5ms。

如果有目標(biāo)板,可以將編譯生成的2.HEX文件下載至目標(biāo)器件,如圖。思考:

若想產(chǎn)生1KHZ聲音0.2S,暫停0.05S、600HZ聲音0.1S、暫停0.2S。應(yīng)如何修改程序。2、驅(qū)動繼電器電路

蜂鳴器由P3.7經(jīng)晶體管驅(qū)動,繼電器由P3.6經(jīng)晶體管驅(qū)動。繼電器驅(qū)動原理

由電路圖可知,P3.6輸出1,則晶體管飽和導(dǎo)通,繼電器線圈得電,繼電器吸合;P3.6輸出0,則晶體管截止,繼電器釋放。

繼電器使用時,一定要看清楚它上面的標(biāo)示,如“0.5A,120VACRES”,表示該繼電器觸點可以驅(qū)動0.5A,交流120V的電阻性負(fù)載。

本例子是由P3.6驅(qū)動繼電器每秒鐘開關(guān)一次,開關(guān)10次后,蜂鳴器響兩聲,然后從頭開始執(zhí)行。/*

-----ch02.c-------*/

#include

<reg51.h>

sbit

buzzer=P3^7;

sbit

relay=P3^6;

void

delay(int);

void

pulse_BZ(int,int,int);

void

pulse_RL(int,int,int);

main()

{

while(1)

{

pulse_RL(10,2000,2000);//relay

on/off

10tinmes,2000x0.5=1s

pulse_BZ(100,1,1);

//buzzer

first

on

100x(0.5+0.5)=0.1s

delay(200);

//

delay

200x0.5=0.1ms

pulse_BZ(100,1,1);

delay(200);

}

}

//----delay----

void

delay(int

x)

{

int

i,j;

for(i=0;i<x;i++)

for(j=0;j<60;j++);

}

//----pulse_BZ-----

void

pulse_BZ(int

count,int

TH,int

TL)

{

int

i;

for(i=0;i<count;i++)

{

buzzer=1;

delay(TH);

buzzer=0;

delay(TL);

}

}

//---relay

control-----

void

pulse_RL(int

count,int

TH,int

TL)

{

int

i;

for(i=0;i<count;i++)

{

relay=1;

delay(TH);

relay=0;

delay(TL);

}

}

思考:

若讓繼電器吸合10S,斷開5S,周而復(fù)始,應(yīng)如何修改程序。3、霹靂燈

霹靂燈是指在一排LED里(此處8個),任何一個時間只有一個LED亮,亮燈順序為由左而右再由右而左,感覺上就像一個LED由左跑到右,再由右跑到左。

在程序設(shè)計中,采用計數(shù)循環(huán)的方式,首先左移7次,在右移7次,如此循環(huán)。左移采用LED<<1指令,右移采用LED>>1指令。LED的初始值為11111110,左移時,右邊將移入0,必須將最右邊的位變成1,采用OR運算,即LED=(LED<<1)|0X01。同理,右移時,LED=(LED)>>1|0X80。

移位完成判斷可采用計數(shù)的方式,也可采用判斷最高位為0的方式(左移)或最低位為0(右移)。

/*

-----ch03.c-------*/

#include

<reg51.h>

#define

LED

P1

void

delay(int);

main()

{

unsigned

char

i;

LED=0xfe;

while(1)

{

for(i=0;i<7;i++)

{

delay(100);

//delay

100x5ms=0.5s

LED=(LED<<1)|0x01;

}

for(i=0;i<7;i++)

{

delay(100);

//delay

100x5ms=0.5s

LED=(LED>>1)|0x80;

}

}

}

//----delay----

void

delay(int

x)

{

int

i,j;

for(i=0;i<x;i++)

for(j=0;j<600;j++);//count

600

delay

5ms

}

思考:1、修改程序,將它變成雙燈的霹靂燈功能。2、用判斷的方式重寫上述程序。4、七段LED數(shù)碼管

電路如圖,由P0驅(qū)動共陽極數(shù)碼管。數(shù)碼管上顯示的數(shù)字從0開始,每隔0.5S增加1,直到9之后,再從0開始,如此循環(huán)。/*

-----ch04.c-------*/

#include

<reg51.h>

#define

SEG

P0

char

code

TAB[]={0xc0,0xf9,0xa4,0xb0,0x99,

0x92,0x83,0xf8,0x80,0x98};

void

delay(int);

main()

{

unsigned

char

i;

while(1)

{

for(i=0;i<10;i++)

{

SEG=TAB[i];

delay(500);

//delay

500x1ms=0.5s

}

}}

//----delay----

void

delay(int

x)

{

int

i,j;

for(i=0;i<x;i++)

for(j=0;j<120;j++);//count

120

delay

1ms

}

思考:1、修改程序,讓數(shù)碼管從9開始顯示,遞減到0循環(huán)。2、修改程序,讓數(shù)碼管從0開始顯示,遞增到9,再遞減到0,循環(huán)。輸入設(shè)備與輸入電路的設(shè)計1、輸入設(shè)備

對于數(shù)字電路,最基本的輸入器件是開關(guān),開關(guān)分為兩類:按鈕開關(guān),具有自動恢復(fù)(彈回)功能,在電路板中,最典型的按鈕開關(guān)是TackSwitch,如圖a所示,也有以導(dǎo)電橡皮所組成的按鈕組。閘刀開關(guān)(KnifeSwitch)不會自動恢復(fù),電路板中最典型的是撥碼開關(guān)(DIPSwitch),如圖b所示。有2P、4P、8P等,通常會在一邊標(biāo)示ON。輸入端口的應(yīng)用面板用數(shù)字型撥碼開關(guān)

是一種附有數(shù)字輪盤的撥碼開關(guān),嵌在控制面板上,如圖所示。可分為下列兩種類型:a.BCD撥碼開關(guān)提供0-9的BCD編碼輸出。b.十六進制撥碼開關(guān)提供0-F十六進制編碼輸出電路板用數(shù)字型撥碼開關(guān)

如圖所示。

2、輸入電路設(shè)計

在設(shè)計數(shù)字電路或微處理器輸入電路時,要避免不確定狀態(tài),即輸入端不要空接。

對開關(guān)輸入至數(shù)字電路,一般會接一個電阻到VCC或GND。3、抖動與去抖動抖動現(xiàn)象

開關(guān)動作并不是想象的那樣工作很確定,在操作的時候,由于觸點的彈性,會出現(xiàn)觸點反復(fù)動作而使輸入的電平出現(xiàn)波動的不穩(wěn)定現(xiàn)象,這個現(xiàn)象稱為按鍵的抖動。

抖動一般是一個過渡過程,出現(xiàn)在按鍵按下和松開的過程中,一般持續(xù)10-20毫秒的時間。硬件去抖動

如圖為與非門組成的去抖動電路(debouncer),這個電路需要的元件多,占用電路面積大,使用較少。

利用RC去抖動電路較多,如圖所示,電路中只需要增加一個電容。

應(yīng)用實例1、撥碼開關(guān)設(shè)計一個由撥碼開關(guān)控制LED的系統(tǒng),撥碼開關(guān)輸入到P2,對應(yīng)的LED燈由P1輸出控制,電路如圖。

/*

-----ch05.c-------*/

#include

<reg51.h>

#define

SW

P2

#define

LED

P1

main()

{

SW=0xff;

while(1)

{

LED=SW;

}

}

思考:1、本程序中,有沒有抖動的困擾。2、若希望撥碼開關(guān)的S1、S3、S5三個都合上時,前4個LED亮;S2或S4或S6合上時,后4個LED亮;S7及S8合上時,所有LED亮,編寫程序。2、按鈕開關(guān)如圖,若按下PB1,則P1.0所連接的LED亮;若按下PB2,則關(guān)閉P1.0所接的LED。/*-----ch05.c-------*/#include<reg51.h>sbitPB1=P2^0;sbitPB2=P2^1;sbitLED=P1^0;main(){ LED=1; PB1=1;PB2=1; while(1) { if(PB2==0)LED=1; elseif(PB1==0)LED=0; }}思考:1、本程序中,有沒有抖動的困擾。2、若同時按下PB1和PB2按鈕會怎樣?3、按鈕開關(guān)切換如圖,若初始P1.0接的LED不亮,按下PB1,則LED亮,再按一次PB1,則LED熄滅,以此類推;當(dāng)按住不放時,不會改變。/*

-----ch05.c-------*/

#include

<reg51.h>

sbit

PB1=P2^0;

sbit

LED=P1^0;

void

debouncer(void);

main()

{

LED=1;

//LED

off

PB1=1;

//

set

P2.0

to

input

while(1)

{

if(PB1==0)

{

debouncer();

LED=~LED;

while(PB1!=1);

debouncer();

}

}}

//----debouncer----

void

debouncer(void)

{

int

i;

for(i=0;i<2400;i++);

}

思考:

改變debouncer時間長短看看有什么影響。4、按鈕開關(guān)控制數(shù)碼管如圖,P0接數(shù)碼管,P2.0接按鈕PB1,P2.1接按鈕PB2,其中PB1控制數(shù)碼顯示遞增,PB2控制遞減。程序開始數(shù)碼管顯示0,當(dāng)按鈕按住不放時,數(shù)碼管顯示不變。/*

-----ch05.c-------*/

#include

<reg51.h>

#define

SEG

P0

char

code

TAB[]={0xc0,0xf9,0xa4,

0xb0,0x99,0x92,0x83,0xf8,

0x80,0x98};

sbit

PB1=P2^0;

sbit

PB2=P2^1;

void

debouncer(void);

main()

{

unsigned

char

i=0;

PB1=PB2=1;

//

set

to

input

SEG=TAB[i];

//

while(1)

{

if(PB1==0)

{

debouncer();

i=(i<9)?i+1:0;

SEG=TAB[i];

while(PB1==0);

debouncer();

}

if(PB2==0)

{

debouncer();

i=(i>0)?i-1:9;

SEG=TAB[i];

while(PB2==0);

debouncer();

}

}

}

//----debouncer----

void

debouncer(void)

{

int

i;

for(i=0;i<2400;i++);

}思考:

同時按住PB1和PB2會怎么樣?5、BCD撥碼開關(guān)如圖,P0接數(shù)碼管,P2的低4位連接到BCD型數(shù)字型撥碼開關(guān),數(shù)碼管顯示撥碼開關(guān)的值。/*

-----ch05.c-------*/

#include

<reg51.h>

#define

SEG

P0

#define

SW

P2

#define

SW_H()

SW&0x0f

char

code

TAB[]={0xc0,0xf9,0xa4,0xb0,

0x99,0x92,0x83,0xf8,0x80,0x98};

main()

{

SW=0xff;

//set

to

input

while(1)

{

SEG=TAB[SW_H()];

}

}

思考:1、本程序中有沒有抖動的困擾?2、如果將BCD型改成十六進制,程序如何修改?6、多開關(guān)如圖,P1接8個LED,P2的低4位連接4個按鈕開關(guān),程序功能要求如下。a.按下PB1:前4個LED,后4個LED交替顯示3次,間隔0.5S,然后8個LED閃爍3次。b.按下PB2:單燈左移3圈,然后8燈閃爍3次。c.按下PB3:單燈右移3圈,然后8燈閃爍3次。d.按下PB4:霹靂燈3圈,然后8燈閃爍3次。本例子目的是了解模塊化和按鈕優(yōu)先等級。/*----自己寫的鏈接----*/#defineLEDP1voiddebouncer(void);//去抖voiddelay10ms(int);//10ms延時voidalter(int);//交替閃爍voidleft(int);//單燈左移voidright(int);//單燈右移voidpili(int);//霹靂燈voidflash(int);//閃爍//---去抖函數(shù),延時約20ms-----voiddebouncer(void){ delay10ms(2);}//---延時函數(shù),延時=x*10ms-----voiddelay10ms(intx){inti,j;for(i=0;i<x;i++)for(j=0;j<1200;j++);}//----高低電平交替閃爍,執(zhí)行x次voidalter(intx){ inti; LED=0x0f; for(i=0;i<2*x-1;i++) { delay10ms(50); LED=~LED; } delay10ms(50);}//---全燈閃爍,執(zhí)行x次---voidflash(intx){ inti; LED=0x00; for(i=0;i<2*x-1;i++) { delay10ms(50); LED=~LED; } delay10ms(50);}//---單燈左移,執(zhí)行x圈----voidleft(intx){ inti,j; for(i=0;i<x;i++) { LED=0xfe; for(j=0;j<7;j++) { delay10ms(25); LED=(LED<<1)|0x01; } delay10ms(25); }}//---單燈右移,執(zhí)行x圈-----voidright(intx){inti,j;

for(i=0;i<x;i++){LED=0x7f;for(j=0;j<7;j++){delay10ms(25);LED=(LED>>1)|0x80;}delay10ms(25);}}//---霹靂燈,執(zhí)行x圈----voidpili(intx){ inti; for(i=0;i<x;i++) { left(1); right(1); }}/*

-----ch05.c-------*/

#include

<reg51.h>

#include

"myio.h"

sbit

PB1=P2^0;

sbit

PB2=P2^1;

sbit

PB3=P2^2;

sbit

PB4=P2^3;

main()

{

LED=0xff;

P2=0xff;

//

set

to

input

while(1)

{

if(PB1==0)

{

debouncer();

alter(3);

flash(3);

}

else

if(PB2==0)

{

debouncer();

left(3);

flash(3);

}

else

if(PB3==0)

{

debouncer();

right(3);

flash(3);

}

else

if(PB4==0)

{

debouncer();

pili(3);

flash(3);

}

}}

思考:

本程序中若同時按下多鍵會如何?若按住按鍵不放會如何?

前面程序中,PB1具有最高優(yōu)先級,若改成無優(yōu)先權(quán)的問題時,可用SWITCH語句。

/*

-----ch05.c-------*/

#include

<reg51.h>

#include

"myio.h"

#define

PB

P2

main()

{

LED=0xff;

P2=0xff;

/t

to

input

while(1)

{

switch(~PB)

{

case

0x01:

{

debouncer();

alter(3);

flash(3);

break;

}

case

0x02:

{

debouncer();

left(3);

flash(3);

break;

}

case

0x04:

{

debouncer();

right(3);

flash(3);

break;

}

case

0x08:

{

debouncer();

pili(3);

flash(3);

break;

}

}

}

}思考:

本程序中去抖動函數(shù)是否有必要?

若同時按下多鍵會產(chǎn)生什么結(jié)果?

若按住某鍵不放會有什么結(jié)果?

前面程序中,如何解決按鍵按住不放的問題。

/*

-----ch05.c-------*/

#include

<reg51.h>

#include

"myio.h"

#define

PB

P2

main()

{

LED=0xff;

P2=0xff;

/t

to

input

while(1)

{

switch(~PB)

{

case

0x01:

{

debouncer(); while(~PB==1); debouncer();

alter(3);

flash(3);

break;

}

case

0x02:

{

debouncer(); while(~PB==1); debouncer();

left(3);

flash(3);

break;

}

case

0x04:

{

debouncer(); while(~PB==1); debouncer();

right(3);

flash(3);

break;

}

case

0x08:

{

debouncer(); while(~PB==1); debouncer();

pili(3);

flash(3);

break;

}

}

}

}輸入端口的高級應(yīng)用1、鍵盤掃描

在計算機系統(tǒng)中,若需要多個按鈕,通常將這些按鈕組成陣列,如16個按鈕,則排成4×4陣列,稱之為鍵盤(Keyboard)。4×4是指4列(Column)與4行(Row)所構(gòu)成的鍵盤,如圖所示。在電路中可使用TackSwitch在PCB上制成鍵盤。當(dāng)然,象上面連接鍵盤還不夠,在每行上都必須接一個上拉電阻(10kΩ),這里使用一個4R5P視為排阻,如圖。鍵盤掃描原理

鍵盤電路如圖,進行鍵盤掃描時,將掃描信號送至X0-X3,再由Y0-Y3讀取鍵盤狀態(tài),判斷哪個按鍵被按下。鍵盤掃描方式有兩種,即低電平掃描與高電平掃描。a.低電平掃描

它是將COM端連接VCC,在沒有按鍵按下時,Y0-Y3保持為高電平(即1)。在x0-x3上送低電平,如果對應(yīng)的行有按鍵按下,則讀取Y0-Y3中會有低電平狀態(tài)。整個掃描分為4個階段:

第一個階段是判斷第一列的按鍵,在X0送低電平,X1-X3送高電平,讀取Y0-Y3的狀態(tài),若有低電平值,則第一列對應(yīng)的按鍵按下。

第二、三、四階段分別依次判斷第二、三、四列的按鍵,依次在X1、X2、X3上送低電平,分別讀取Y0-Y3。b.高電平掃描

它是將COM端連接GND,在沒有按鍵按下時,Y0-Y3保持為低電平(即0)。在x0-x3上送高電平,如果對應(yīng)的行有按鍵按下,則讀取Y0-Y3中會有高電平狀態(tài)。整個掃描分為和低電平掃描過程一樣。

兩種掃描的速度很快,每個掃描周期只需要幾個毫秒,通常以低電平掃描為主,本章以低電平掃描來介紹。4×4鍵盤程序分析

如圖,當(dāng)按下按鍵后,按鍵上的鍵值將顯示在DS1七段數(shù)碼管上。程序如下:

//-----keyscansub------#defineSEGP0#defineKEYPP2charcodeTAB[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,//0-40x83,0xf8,0x80,0x98,0xa0,0x83,//5-9 0xa7,0xa1,0x84,//a-e 0x8e,0xbf,0x7f};//f-.chardisp=0x7f;unsignedcharscan[]={0xef,0xdf,0xbf,0x7f};//---掃描4×4鍵盤及4個七段顯示器函數(shù)-----voidscanner(void){unsignedcharcol,row,dig;unsignedcharrowkey,kcode;for(col=0;col<4;col++){KEYP=scan[col];SEG=disp;rowkey=~KEYP&0x0f;if(rowkey!=0){ if(rowkey==0x01)row=0; elseif(rowkey==0x02)row=1; elseif(rowkey==0x04)row=2; elseif(rowkey==0x08)row=3; kcode=4*col+row; disp=TAB[kcode]; while(rowkey!=0) rowkey=~KEYP&0x0f;}delay1ms(4); }}認(rèn)識MM74C922/MM74C923

對于鍵盤的狀態(tài)檢測,除了利用鍵盤掃描軟件,還可以應(yīng)用鍵盤掃描IC,如NS公司的MM74C922/MM74C923,其中MM74C922為4×4鍵盤掃描IC,MM74C923為4×5鍵盤掃描IC,如圖。各引腳定義如下:DataA-DataE:輸出檢測鍵盤的結(jié)果,連接到處理器的輸入口。ColumnX0-ColumnX3:連接鍵盤的x0-x3。RowY0-RowY4:連接鍵盤的Y0-Y4行。Oscillator:振蕩引腳,接0.1μF電容到地。KeyboardMask:按鍵屏蔽引腳(KBM),功能是提供屏蔽按鍵抖動的周期,即硬件去抖動。當(dāng)按鍵按下時,進入屏蔽周期,首先將暫停IC內(nèi)部的計數(shù),同時DA引腳變?yōu)楦唠娖剑钡桨存I釋放才恢復(fù)低電平。DataAvailable:允許數(shù)據(jù)輸出(DA),無鍵時為低電平,有按鍵時為高電平,允許鍵盤狀態(tài)由DataA-DataE輸出。OutputEnable:輸出使能(OE),通過邏輯門或反相器設(shè)置數(shù)據(jù)輸出引腳DataA-DataE與微處理器之間的傳輸方式(同步交互式、同步數(shù)據(jù)傳輸及異步數(shù)據(jù)傳輸?shù)龋?,如圖所示。上圖C中,MM74C922的ABCD連接到89S51的P2.4到P2.7,DA腳連接89S51的P3.2,89S51的P2.0-P2.3連接7447,按下鍵盤的任意鍵其數(shù)值將顯示在數(shù)碼管上。程序如下://------MM74C922---------#include<reg51.h>SbitIRQ=P3^2;charcodedisp[]={8,0,5,1};unsignedcharscan;main(){P2=0xff;while(1){if(IRQ==1)P2=(P2>>4)|0xf0;}}2、七段LED數(shù)碼管掃描

前面討論了單個數(shù)碼管的顯示,如果有多個數(shù)碼管顯示時,若還是與單個數(shù)碼管一樣采用個別(獨立)的驅(qū)動方式就很沒效率,也將占用較多的硬件資源。在此將討論將多個七段LED數(shù)碼管封裝在一起的七段數(shù)碼管模塊,以及利用視覺暫留現(xiàn)象的快速掃描的驅(qū)動方式。七段LED數(shù)碼管模塊

多個數(shù)碼管同時使用時,首先將每個七段LED數(shù)碼管的a,b,…g引腳都連在一起,再使用晶體管分別驅(qū)動每個數(shù)碼管的com端。如圖:

這種數(shù)碼管模塊顯示時必須采用動態(tài)掃描的方式,但要求掃描時間第一個到最后一個不超過16ms,即60Hz,這樣才不會有閃爍的感覺。

以掃描方式驅(qū)動多個數(shù)碼管時,驅(qū)動信號包括顯示數(shù)據(jù)與掃描信號,“顯示數(shù)據(jù)”是所要顯示的驅(qū)動信號編碼,與驅(qū)動單個數(shù)碼管一樣;“掃描信號”就是開關(guān),以決定驅(qū)動哪一數(shù)碼管,它分為高電平與低電平兩種,與電路結(jié)構(gòu)有關(guān),上圖中的掃描就是低電平掃描。

數(shù)碼管模塊就是將多個位數(shù)的數(shù)碼管封裝在一起,其中各個數(shù)碼管的a,b…g是連接在一起的,而com端獨立。

對于掃描方式(動態(tài))驅(qū)動的數(shù)碼管,其亮度和穩(wěn)定性是一對矛盾。建議掃描頻率限制在60Hz以上,即在16ms之內(nèi)完成一次掃描不會閃爍。即對于4位模塊的掃描,其每位數(shù)的工作周期為固定式負(fù)載的1/4,其亮度約為固定式負(fù)載的1/4;對8位模塊,則為1/8,其亮度更低。如何提高亮度:a.降低限流電阻值4位數(shù)碼管使用50-100Ω;8位則25-50Ω。這個方法在在線仿真時要注意,程序停止或暫停時,其電流值會很大,容易燒數(shù)碼管。b.選用高亮度數(shù)碼管模塊7447/7448

對于BCD碼轉(zhuǎn)換成七段顯示的譯碼驅(qū)動IC,首推7447系列,包括7446、7447、7448與7449。其中7446/7447輸出低電平,用以驅(qū)動共陽極數(shù)碼管;7448/7449則驅(qū)動共陰極數(shù)碼管。其引腳說明如下:D、C、B、A:BCD碼輸入腳。a-g:七段數(shù)碼管段驅(qū)動引腳。LampTest(LT):測試引腳,輸入低電平時所

有的段亮。RBI:消隱(滅燈)輸入引腳。BI/RBO:消隱輸入或動態(tài)消隱輸出引腳。

消除前置0是指若數(shù)字整數(shù)部分靠左邊的數(shù)若為0,則不顯示該位數(shù)。若使用7446、7447、7448所提供的消除前置0功能,則可將整數(shù)部分最左邊位數(shù)的RBI引腳接地,BI/RBO引腳連接到其右邊位數(shù)的RBI引腳,個位的RBI不接前左邊的BI/RBO,以避免全部的整數(shù)不顯示;同時,將其dp引腳連接限流電阻后接地,以顯示小數(shù)點。如圖例輸入“000000010001”顯示“11.”。

消除尾端0若使用7446、7447、7448所提供的消除尾端0功能,則可將小數(shù)部分最右邊位數(shù)的RBI引腳接地,BI/RBO引腳連接到其左邊位數(shù)的RBI引腳,以此類推。如圖顯示“5”

74138/74139

鍵盤掃描和多個數(shù)碼管掃描,都需要掃描信號,可以利用微處理器程序產(chǎn)生,這樣需要占用微處理器的輸出端口,在本節(jié)利用2-4譯碼器或3-8譯碼器來產(chǎn)生4位或8位掃描信號,達到節(jié)省微處理器本身輸出口的目的。74139是具有雙2-4譯碼器的IC,74138則是3-8譯碼器IC。3、靜態(tài)顯示與動態(tài)顯示使用BCD碼譯碼器如圖:掃描信號通過P1.3-P1.0送至Q3-Q0的基極,以低電平驅(qū)動數(shù)碼管模塊的四位數(shù)碼。顯示信號由P1.7-P1.4輸出BCD碼至7447譯碼,7447的LT、BI/RBO及RBI引腳接VCC或懸空,對于TTL,輸入腳懸空等同于輸入高電平,到容易受到干擾,要養(yǎng)成習(xí)慣,不用的腳盡量不要懸空。程序如下:main(){while(1){P1=0x1e;//dig.0顯示1delay1ms(4);P1=0x5d;//dig.1顯示5delay1ms(4);P1=0x0b;//dig.2顯示0delay1ms(4);P1=0x87;//dig.3顯示8delay1ms(4);}}這種方式優(yōu)點是只要一個端口,程序設(shè)計簡單。但要改變顯示數(shù)字,程序設(shè)計靈活性差。

若把顯示信號與驅(qū)動信號分開由兩個端口輸出,則可利用數(shù)組存儲所要顯示的數(shù)據(jù),而以移位的方式產(chǎn)生掃描信號,如圖。程序如下:charcodedisp[]={8,0,5,1};unsignedcharscan;main(){while(1){scan=1;for(i=0;i<4;i++){P2=disp[i];P1=~scan;delay1ms(4);scan<<=1;}}}對于8個位的數(shù)碼管顯示,采用上述電路,對程序只做少量修改即可。直接驅(qū)動如圖:直接以P1輸出掃描信號、P2輸出顯示驅(qū)動信號,不使用其他IC。程序設(shè)計如下:charcodeTAB[]={0XC0,…};charcodedisp[]={8,0,5,1};unsignedcharscan;chari,j;main(){while(1){scan=1;for(i=0;i<4;i++){j=disp[3-i];P2=TAB[j];P1=~scan;delay1ms(4);scan<<=1;}}}

使用掃描譯碼器如圖:以P1輸出BCD信號經(jīng)74138輸出掃描信號,P2輸出顯示驅(qū)動信號。程序設(shè)計如下:charcodeTAB[]={0XC0,…};charcodedisp[]={2,0,0,8,1,2,2,5};unsignedcharscan;chari,j;main(){while(1){for(i=0;i<8;i++){j=disp[7-i];P2=TAB[j];P1=i;delay1ms(2);}}}

閃爍就是時亮?xí)r不亮,以直接驅(qū)動4位數(shù)碼管模塊為例,若要顯示“8051”,掃描一次16ms,希望這四個數(shù)字顯示約0.48s,熄滅0.48S,交替循環(huán)。程序如下:charcodeTAB[]={0XC0,…};charcodedisp[]={8,0,5,1};charscan;chari,j,k;main(){while(1){for(k=0;k<30;k++){scan=1for(i=0;i<4;i++){j=disp[3-i];P2=TAB[j];P1=~scan;delay1ms(4);scan<<=1;}}P2=0xff;delay1ms(48);}}

交替顯示就是多組數(shù)字切換顯示,以直接驅(qū)動4位數(shù)碼管模塊為例,若要顯示“2008”0.48S,然后顯示“1225”0.48s,交替循環(huán)。程序如下:charcodeTAB[]={0XC0,…};charcodedisp1[]={2,0,0,8};charcodedisp2[]={1,2,2,5};charscan,i,j,k;main(){while(1){for(k=0;k<30;k++){scan=1for(i=0;i<4;i++){j=disp1[3-i];P2=TAB[j];P1=~scan;delay1ms(4);scan<<=1;}}for(k=0;k<30;k++){scan=1for(i=0;i<4;i++){j=disp2[3-i];P2=TAB[j];P1=~scan;delay1ms(4);scan<<=1;}}}}

下面用函數(shù)調(diào)用的方式重寫程序,利用指針變量將數(shù)字傳入函數(shù)。charcodeTAB[]={0XC0,…};charcodedisp1[]={2,0,0,8};charcodedisp2[]={1,2,2,5};charscan,i,j,k;char*ptr;Voidscanner(char*);main(){while(1){ptr=&disp1[0];scanner(ptr);ptr=&disp2[0];scanner(ptr);}}//-------------------------------------------voidscanner(char*x){for(k=0;k<30;k++){scan=1for(i=0;i<4;i++){j=*(x+3-1);P2=TAB[j];P1=~scan;delay1ms(4);scan<<=1;}}}飛入相對“交替”和“閃爍”,“飛入”比較復(fù)雜,就是要顯示的內(nèi)容依次進入顯示,一個字符到位置停下后,下一個字符才進入。如要顯示“8051”由右邊飛入。程序如下:charcodeTAB[]={0XC0,0xf9,..,0x98,0xff};charcodedisp[10][4]={{10,10,10,8},{10,10,8,10},{10,8,10,10},{8,10,10,10},{8,10,10,0},{8,10,0,10},{8,0,10,10},{8,0,10,5},{8,0,5,10},{8,0,5,1}};voidscanner(char);main(){chari;while(1){for(i=0;i<10;i++)scanner(i);}}//--------------------------------------voidscanner(charx){chari,j,k;charscan;for(k=0;k<30;k++){scan=1;for(i=0;i<4;i++)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論