微处理器C51-5输出输入端口_第1页
微处理器C51-5输出输入端口_第2页
微处理器C51-5输出输入端口_第3页
微处理器C51-5输出输入端口_第4页
微处理器C51-5输出输入端口_第5页
已阅读5页,还剩65页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

输出/输入端口的应用如何申请免费样片输出端口的应用输入口的应用输入输出端口的高级应用输出端口的应用输出电路的设计89S51的输出端口可直接连接数字电路,也可驱动LED、蜂鸣器、继电器或固态继电器等负载。1、驱动LEDLED具有二极管的特点,其特性曲线如图,通过增加LED正向电流可以使其更亮,但会缩短其寿命或烧断,以10-20mA为宜。89S51的I/O端口都有类似漏极开路的输出,其中P1、P2与P3内部具有30KΩ上拉电阻,它们不能输出10-20mA电流,其电路如图。此电路中,当输出低电平时,输出端FET导通,输出电压接近0V;而LED正向导通电压为约1.7V,限流电阻R两端约3.3V(VCC=5.0V),此时限流电阻值为:R=(5-1.7)/0.01=330Ω

对于TTL电平的数字电流,LED所串接的限流电阻大多为470Ω。2、驱动蜂鸣器

蜂鸣器(buzzer)类似小型喇叭,一般用作电路板上的发声装置。它分为电压型与脉冲型两类,电压型送电即响,其频率固定;脉冲型必须加入脉冲信号,声音频率就是加入脉冲的频率。

在此使用脉冲型蜂鸣器。

89S51驱动蜂鸣器的信号为各种频率的脉冲,其驱动方式采用达林顿管,或以两个常用的小三极管(cs9013)连接成达林顿结构。如图,这两个驱动电路属高电平动作,即输出“1”蜂鸣器吸住。也可采用低电平动作,如图输出0时,蜂鸣器吸住;输出1时,蜂鸣器释放。在晶体管BE之间连接一个泄放电阻(3.3KΩ),其目的是让晶体管从饱和到截止时提供一个泄放BE间少数载流子的路径,以加快切换,放止拖音。3、驱动继电器

若要89S51控制不同电压或较大电流的负载时,则可以通过继电器(RELAY)来实现。

电路板上使用的继电器体积小,使用电压有DC12V、DC9V、DC6V和DC5V等,图中,c-b之间为常闭(NC)触点,c-a之间为常开(NO)触点,只有一组触点,称为1P。89S51驱动的继电器大多为DC6V或DC5V,尽管如此,89S51输出口的驱动能力还是不够的,而且,继电器线圈感性负载还需要保护。如图a为高电平驱动的继电器驱动电路。

如图b为低电平驱动继电器电路图。

对于微型计算机系统,采用低电平动作的继电器驱动电路属于较优的设计。

由于线圈是电感负载,续流二极管起到保护晶体管的损坏。

如果要同时驱动多个继电器。可使用集电极开路(OC)输出的反相门,如7405(驱动5V继电器)或7406(驱动较高电压继电器,最高30V)。4、驱动固态继电器

固态继电器(SSR)类似一般继电器,可用较小的控制信号来驱动,以控制较大的负载。SSR没有实际的触点,不会有触点动作的火花与机械动作。一般SSR是由光耦合器输入控制信号,而另一端则是较大容量的功率半导体器件(如SCR、TRIAC或IGBT)。

如图为常见的SSR,其输出端为AC250V/10A。SSR的输入端为LED,所以其驱动方法与LED一样,不过需要较大的电压和电流。

如图a为高电平驱动电路;图b为低电平驱动电路。5、驱动七段数码管

七段LED数码管是利用7个LED组合而成的显示装置,可以显示0-9数字和A-F字母。七段LED数码管有共阴极与共阳极两种。共阳极(CommonAnode)七段LED数码管

电路连接如图a,com接+5V,每个阴极引脚各接一个限流电阻。图b为不合理的接法。若a接8051输出端口的最低位(LSB),dp接8051的最高位(MSB),则0-9的驱动信号如表所示(小数点不亮)。共阴极(CommonCatchode)七段LED数码管

电路连接如图a,com接GND,每个阳极引脚各接一个限流电阻。图b为不合理的接法。若a接8051输出端口的最低位(LSB),dp接8051的最高位(MSB),则0-9的驱动信号如表所示(小数点不亮)。实例1、驱动蜂鸣器电路

蜂鸣器由P3.7经晶体管驱动。声音产生原理

声音是蜂鸣器簧片振动产生的,若要产生f的频率,需要在周期T时间内进行吸、放各一次,即通断时间各1/2T。程序设计

本程序将产生1KHz信号持续0.1s,停止0.5s,再产生1KHz信号持续0.1s停止0.5s,然后从头开始执行。/*ch01.c-----蜂鸣器程序-----*///*******声明区**********#include<reg51.h>sbitbuzzer=P3^7;voiddelay(int);voidpulse_BZ(int,int,int);//******主程序*********Main(){while(1){pulse_BZ(100,1,1);delay(1000);}}//****子程序*******/*延迟函数x×0.5ms*/voiddelay(intx){inti,j;for(i=0;i<x;i++)for(j=0;j<60;j++);}/*蜂鸣器发声函数count计数TH高电平时间TL低电平时间*/voidpulse_BZ(intcount,intTH,intTL){inti;for(i=0;i<count;i++){buzzer=1;delay(TH);buzzer=0;delay(TL);}}对程序进行仿真调试,如图高电平持续时间为0.000944-0.000422=0.000522s

同样,低电平持续时间也为0.5ms。

如果有目标板,可以将编译生成的2.HEX文件下载至目标器件,如图。思考:

若想产生1KHZ声音0.2S,暂停0.05S、600HZ声音0.1S、暂停0.2S。应如何修改程序。2、驱动继电器电路

蜂鸣器由P3.7经晶体管驱动,继电器由P3.6经晶体管驱动。继电器驱动原理

由电路图可知,P3.6输出1,则晶体管饱和导通,继电器线圈得电,继电器吸合;P3.6输出0,则晶体管截止,继电器释放。

继电器使用时,一定要看清楚它上面的标示,如“0.5A,120VACRES”,表示该继电器触点可以驱动0.5A,交流120V的电阻性负载。

本例子是由P3.6驱动继电器每秒钟开关一次,开关10次后,蜂鸣器响两声,然后从头开始执行。/*

-----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,周而复始,应如何修改程序。3、霹雳灯

霹雳灯是指在一排LED里(此处8个),任何一个时间只有一个LED亮,亮灯顺序为由左而右再由右而左,感觉上就像一个LED由左跑到右,再由右跑到左。

在程序设计中,采用计数循环的方式,首先左移7次,在右移7次,如此循环。左移采用LED<<1指令,右移采用LED>>1指令。LED的初始值为11111110,左移时,右边将移入0,必须将最右边的位变成1,采用OR运算,即LED=(LED<<1)|0X01。同理,右移时,LED=(LED)>>1|0X80。

移位完成判断可采用计数的方式,也可采用判断最高位为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数码管

电路如图,由P0驱动共阳极数码管。数码管上显示的数字从0开始,每隔0.5S增加1,直到9之后,再从0开始,如此循环。/*

-----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、修改程序,让数码管从9开始显示,递减到0循环。2、修改程序,让数码管从0开始显示,递增到9,再递减到0,循环。输入设备与输入电路的设计1、输入设备

对于数字电路,最基本的输入器件是开关,开关分为两类:按钮开关,具有自动恢复(弹回)功能,在电路板中,最典型的按钮开关是TackSwitch,如图a所示,也有以导电橡皮所组成的按钮组。闸刀开关(KnifeSwitch)不会自动恢复,电路板中最典型的是拨码开关(DIPSwitch),如图b所示。有2P、4P、8P等,通常会在一边标示ON。输入端口的应用面板用数字型拨码开关

是一种附有数字轮盘的拨码开关,嵌在控制面板上,如图所示。可分为下列两种类型:a.BCD拨码开关提供0-9的BCD编码输出。b.十六进制拨码开关提供0-F十六进制编码输出电路板用数字型拨码开关

如图所示。

2、输入电路设计

在设计数字电路或微处理器输入电路时,要避免不确定状态,即输入端不要空接。

对开关输入至数字电路,一般会接一个电阻到VCC或GND。3、抖动与去抖动抖动现象

开关动作并不是想象的那样工作很确定,在操作的时候,由于触点的弹性,会出现触点反复动作而使输入的电平出现波动的不稳定现象,这个现象称为按键的抖动。

抖动一般是一个过渡过程,出现在按键按下和松开的过程中,一般持续10-20毫秒的时间。硬件去抖动

如图为与非门组成的去抖动电路(debouncer),这个电路需要的元件多,占用电路面积大,使用较少。

利用RC去抖动电路较多,如图所示,电路中只需要增加一个电容。

应用实例1、拨码开关设计一个由拨码开关控制LED的系统,拨码开关输入到P2,对应的LED灯由P1输出控制,电路如图。

/*

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

#include

<reg51.h>

#define

SW

P2

#define

LED

P1

main()

{

SW=0xff;

while(1)

{

LED=SW;

}

}

思考:1、本程序中,有没有抖动的困扰。2、若希望拨码开关的S1、S3、S5三个都合上时,前4个LED亮;S2或S4或S6合上时,后4个LED亮;S7及S8合上时,所有LED亮,编写程序。2、按钮开关如图,若按下PB1,则P1.0所连接的LED亮;若按下PB2,则关闭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、按钮开关切换如图,若初始P1.0接的LED不亮,按下PB1,则LED亮,再按一次PB1,则LED熄灭,以此类推;当按住不放时,不会改变。/*

-----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、按钮开关控制数码管如图,P0接数码管,P2.0接按钮PB1,P2.1接按钮PB2,其中PB1控制数码显示递增,PB2控制递减。程序开始数码管显示0,当按钮按住不放时,数码管显示不变。/*

-----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拨码开关如图,P0接数码管,P2的低4位连接到BCD型数字型拨码开关,数码管显示拨码开关的值。/*

-----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、多开关如图,P1接8个LED,P2的低4位连接4个按钮开关,程序功能要求如下。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次。本例子目的是了解模块化和按钮优先等级。/*----自己写的链接----*/#defineLEDP1voiddebouncer(void);//去抖voiddelay10ms(int);//10ms延时voidalter(int);//交替闪烁voidleft(int);//单灯左移voidright(int);//单灯右移voidpili(int);//霹雳灯voidflash(int);//闪烁//---去抖函数,延时约20ms-----voiddebouncer(void){ delay10ms(2);}//---延时函数,延时=x*10ms-----voiddelay10ms(intx){inti,j;for(i=0;i<x;i++)for(j=0;j<1200;j++);}//----高低电平交替闪烁,执行x次voidalter(intx){ inti; LED=0x0f; for(i=0;i<2*x-1;i++) { delay10ms(50); LED=~LED; } delay10ms(50);}//---全灯闪烁,执行x次---voidflash(intx){ inti; LED=0x00; for(i=0;i<2*x-1;i++) { delay10ms(50); LED=~LED; } delay10ms(50);}//---单灯左移,执行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); }}//---单灯右移,执行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);}}//---霹雳灯,执行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具有最高优先级,若改成无优先权的问题时,可用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;

}

}

}

}思考:

本程序中去抖动函数是否有必要?

若同时按下多键会产生什么结果?

若按住某键不放会有什么结果?

前面程序中,如何解决按键按住不放的问题。

/*

-----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;

}

}

}

}输入端口的高级应用1、键盘扫描

在计算机系统中,若需要多个按钮,通常将这些按钮组成阵列,如16个按钮,则排成4×4阵列,称之为键盘(Keyboard)。4×4是指4列(Column)与4行(Row)所构成的键盘,如图所示。在电路中可使用TackSwitch在PCB上制成键盘。当然,象上面连接键盘还不够,在每行上都必须接一个上拉电阻(10kΩ),这里使用一个4R5P视为排阻,如图。键盘扫描原理

键盘电路如图,进行键盘扫描时,将扫描信号送至X0-X3,再由Y0-Y3读取键盘状态,判断哪个按键被按下。键盘扫描方式有两种,即低电平扫描与高电平扫描。a.低电平扫描

它是将COM端连接VCC,在没有按键按下时,Y0-Y3保持为高电平(即1)。在x0-x3上送低电平,如果对应的行有按键按下,则读取Y0-Y3中会有低电平状态。整个扫描分为4个阶段:

第一个阶段是判断第一列的按键,在X0送低电平,X1-X3送高电平,读取Y0-Y3的状态,若有低电平值,则第一列对应的按键按下。

第二、三、四阶段分别依次判断第二、三、四列的按键,依次在X1、X2、X3上送低电平,分别读取Y0-Y3。b.高电平扫描

它是将COM端连接GND,在没有按键按下时,Y0-Y3保持为低电平(即0)。在x0-x3上送高电平,如果对应的行有按键按下,则读取Y0-Y3中会有高电平状态。整个扫描分为和低电平扫描过程一样。

两种扫描的速度很快,每个扫描周期只需要几个毫秒,通常以低电平扫描为主,本章以低电平扫描来介绍。4×4键盘程序分析

如图,当按下按键后,按键上的键值将显示在DS1七段数码管上。程序如下:

//-----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个七段显示器函数-----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); }}认识MM74C922/MM74C923

对于键盘的状态检测,除了利用键盘扫描软件,还可以应用键盘扫描IC,如NS公司的MM74C922/MM74C923,其中MM74C922为4×4键盘扫描IC,MM74C923为4×5键盘扫描IC,如图。各引脚定义如下:DataA-DataE:输出检测键盘的结果,连接到处理器的输入口。ColumnX0-ColumnX3:连接键盘的x0-x3。RowY0-RowY4:连接键盘的Y0-Y4行。Oscillator:振荡引脚,接0.1μF电容到地。KeyboardMask:按键屏蔽引脚(KBM),功能是提供屏蔽按键抖动的周期,即硬件去抖动。当按键按下时,进入屏蔽周期,首先将暂停IC内部的计数,同时DA引脚变为高电平,直到按键释放才恢复低电平。DataAvailable:允许数据输出(DA),无键时为低电平,有按键时为高电平,允许键盘状态由DataA-DataE输出。OutputEnable:输出使能(OE),通过逻辑门或反相器设置数据输出引脚DataA-DataE与微处理器之间的传输方式(同步交互式、同步数据传输及异步数据传输等),如图所示。上图C中,MM74C922的ABCD连接到89S51的P2.4到P2.7,DA脚连接89S51的P3.2,89S51的P2.0-P2.3连接7447,按下键盘的任意键其数值将显示在数码管上。程序如下://------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数码管扫描

前面讨论了单个数码管的显示,如果有多个数码管显示时,若还是与单个数码管一样采用个别(独立)的驱动方式就很没效率,也将占用较多的硬件资源。在此将讨论将多个七段LED数码管封装在一起的七段数码管模块,以及利用视觉暂留现象的快速扫描的驱动方式。七段LED数码管模块

多个数码管同时使用时,首先将每个七段LED数码管的a,b,…g引脚都连在一起,再使用晶体管分别驱动每个数码管的com端。如图:

这种数码管模块显示时必须采用动态扫描的方式,但要求扫描时间第一个到最后一个不超过16ms,即60Hz,这样才不会有闪烁的感觉。

以扫描方式驱动多个数码管时,驱动信号包括显示数据与扫描信号,“显示数据”是所要显示的驱动信号编码,与驱动单个数码管一样;“扫描信号”就是开关,以决定驱动哪一数码管,它分为高电平与低电平两种,与电路结构有关,上图中的扫描就是低电平扫描。

数码管模块就是将多个位数的数码管封装在一起,其中各个数码管的a,b…g是连接在一起的,而com端独立。

对于扫描方式(动态)驱动的数码管,其亮度和稳定性是一对矛盾。建议扫描频率限制在60Hz以上,即在16ms之内完成一次扫描不会闪烁。即对于4位模块的扫描,其每位数的工作周期为固定式负载的1/4,其亮度约为固定式负载的1/4;对8位模块,则为1/8,其亮度更低。如何提高亮度:a.降低限流电阻值4位数码管使用50-100Ω;8位则25-50Ω。这个方法在在线仿真时要注意,程序停止或暂停时,其电流值会很大,容易烧数码管。b.选用高亮度数码管模块7447/7448

对于BCD码转换成七段显示的译码驱动IC,首推7447系列,包括7446、7447、7448与7449。其中7446/7447输出低电平,用以驱动共阳极数码管;7448/7449则驱动共阴极数码管。其引脚说明如下:D、C、B、A:BCD码输入脚。a-g:七段数码管段驱动引脚。LampTest(LT):测试引脚,输入低电平时所

有的段亮。RBI:消隐(灭灯)输入引脚。BI/RBO:消隐输入或动态消隐输出引脚。

消除前置0是指若数字整数部分靠左边的数若为0,则不显示该位数。若使用7446、7447、7448所提供的消除前置0功能,则可将整数部分最左边位数的RBI引脚接地,BI/RBO引脚连接到其右边位数的RBI引脚,个位的RBI不接前左边的BI/RBO,以避免全部的整数不显示;同时,将其dp引脚连接限流电阻后接地,以显示小数点。如图例输入“000000010001”显示“11.”。

消除尾端0若使用7446、7447、7448所提供的消除尾端0功能,则可将小数部分最右边位数的RBI引脚接地,BI/RBO引脚连接到其左边位数的RBI引脚,以此类推。如图显示“5”

74138/74139

键盘扫描和多个数码管扫描,都需要扫描信号,可以利用微处理器程序产生,这样需要占用微处理器的输出端口,在本节利用2-4译码器或3-8译码器来产生4位或8位扫描信号,达到节省微处理器本身输出口的目的。74139是具有双2-4译码器的IC,74138则是3-8译码器IC。3、静态显示与动态显示使用BCD码译码器如图:扫描信号通过P1.3-P1.0送至Q3-Q0的基极,以低电平驱动数码管模块的四位数码。显示信号由P1.7-P1.4输出BCD码至7447译码,7447的LT、BI/RBO及RBI引脚接VCC或悬空,对于TTL,输入脚悬空等同于输入高电平,到容易受到干扰,要养成习惯,不用的脚尽量不要悬空。程序如下: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);}}这种方式优点是只要一个端口,程序设计简单。但要改变显示数字,程序设计灵活性差。

若把显示信号与驱动信号分开由两个端口输出,则可利用数组存储所要显示的数据,而以移位的方式产生扫描信号,如图。程序如下: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个位的数码管显示,采用上述电路,对程序只做少量修改即可。直接驱动如图:直接以P1输出扫描信号、P2输出显示驱动信号,不使用其他IC。程序设计如下: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信号经74138输出扫描信号,P2输出显示驱动信号。程序设计如下: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);}}}

闪烁就是时亮时不亮,以直接驱动4位数码管模块为例,若要显示“8051”,扫描一次16ms,希望这四个数字显示约0.48s,熄灭0.48S,交替循环。程序如下: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);}}

交替显示就是多组数字切换显示,以直接驱动4位数码管模块为例,若要显示“2008”0.48S,然后显示“1225”0.48s,交替循环。程序如下: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;}}}}

下面用函数调用的方式重写程序,利用指针变量将数字传入函数。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;}}}飞入相对“交替”和“闪烁”,“飞入”比较复杂,就是要显示的内容依次进入显示,一个字符到位置停下后,下一个字符才进入。如要显示“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. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论