单片机实验4报告

单片机实验4报告
单片机实验4报告

学号14142200277 序号19

单片机原理与接口技术

实验报告

实验项目序号实验四

实验项目名称动态显示与矩阵式键盘实验

姓名卢志雄专业电子信息工程班级电信14-2BF 完成时间 2016-05-10

一、实验目的

1、 进一步理解数码管与单片机的接口原理与动态显示原理,理解单片机矩

阵式键盘按键识别的原理;

2、 掌握单片机动态显示应用和编程方法;

3、 掌握单片机矩阵式键盘按键识别的方法。 二、实验内容

实验内容为3项,其中第1、2项必做。 1、动态显示。

未按键不显示,按K1键,动态显示 “19491001”;按K2键,动态显示 “20141210”。

2、动态显示与按键识别。

矩阵式键盘键值分别是0-F ,未按键不显示。每按键一次,键值在最低位显示,原键值向高位移一位。

3、可控动态显示与按键识别。

矩阵式键盘键值分别是0-9,最下面一排键位功能键,左右两个键分别为“清0键”“C ”,和”“回车键”“ ”,其它键无效。未按键不显示,每按键

一次,键值在最低位显示,原键值向高位移一位。按8个键后,再按键无效。

按清0键全显示“0”。按“ ”后全部熄灭,再按键重新开始。

三、实验原理图

XTAL2

18

XTAL1

19

ALE 30EA

31

PSEN 29RST

9

P0.0/AD039P0.1/AD138P0.2/AD237P0.3/AD336P0.4/AD435P0.5/AD534P0.6/AD633P0.7/AD732

P1.01P1.12P1.23P1.34P1.45P1.56P1.67P1.78

P3.0/RXD 10P3.1/TXD 11P3.2/INT012P3.3/INT113P3.4/T014P3.7/RD

17

P3.6/WR 16P3.5/T115P2.7/A1528P2.0/A821P2.1/A922P2.2/A1023P2.3/A1124P2.4/A1225P2.5/A1326P2.6/A1427U1

AT89C51

D 02D 13D 24D 35D 46D 57D 68D 7

9

Q 019

Q 118Q 217Q 316Q 415Q 514Q 613Q 7

12

L E 11O E

1

U2

74HC573

D 02D 13D 24D 35D 46D 57D 68D 7

9

Q 019Q 118Q 217Q 316Q 415Q 514Q 613Q 7

12

L E 11O E 1

U3

74HC573

1

2

345678910RP8

1k

K1

K2K3K4

U4

AND_4

图3.4 动态显示与矩阵式键盘实验电路原理图

动态显示共8个共阴极数码管,采用两片74LS573进行驱动,74LS573与74LS373都是8D锁存器,只是573引脚排列更易于布线。其引脚功能为:D1-D8为数据输入端;Q1-Q8为数据输出端;LE为数据输入锁存端,LE=1数据输入D锁存器,LE=0数据不能输入D锁存器,即LE下降沿锁存当前输入数据;OE地址输出允许端,OE=0输出锁存数据,OE=1输出高阻。

电路中,U1输出段码a b c d e f g db,控制显示的字形与小数点,U2输出位选码,控制第几个数码管显示。单片机P14、P15分别连接到U1、U2的LE,连接U1、U2的OE。

四、源程序

第一项:

#include

#define uchar unsigned char

data uchar f[8];

data uchar a,b,num,y,k,g;

data uchar c=0;

table[18]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77, 0x7c,0x39,0x5e,0x79,0x71,0x00}; //共阴极数码管显示段码(0-F)

void delay( j )//延时函数

data uchar j;

{ data uchar i;

while(j--)

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

}

uchar code sled_bit[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //定义点亮数码管位选码

data uchar d[]={1,9,4,9,1,0,0,1};

data uchar e[]={2,0,1,4,1,2,1,0};

sbit oe=P1^3; //2个573的三态使能端

sbit dula=P1^4; //段码573控制信号

sbit wela=P1^5; //位码573控制信号

//延时函数

void main(void)

{

TMOD=0x01; // 设置定时器T0为方式1定时TH0=(65536-500)/256; // 给T0装入初值

TL0=(65536-500)%256; // 给T0装入初值

ET0=1; // 允许T0中断

EA=1;

EX0=1;

IT0=1;

g=0;

P0=0X00;

while(1); //CPU开中断

}

void EX0_int(void) interrupt 0

{ TR0=1;

y=P2;

y=~y;

if(y==1){for(g=0;g<8;g++)f[g]=d[g];}

if(y==2){for(g=0;g<8;g++)f[g]=e[g];}

}

void T0_int(void) interrupt 1 //T0中断函数

{ TH0=(65536-500)/256;

TL0=(65536-500)%256;

oe=1; // 关闭2个573输出,防止送数据时相互影响

k = f[g]; // 每次显示disp[j]的数据

P0= table[k]; // 相应显示数字段码

dula=1;

dula=0; // 锁存段码

P0=~sled_bit[g]; // 选择相应数码管位选

wela=1;

wela=0; // 锁存位码

oe=0;

g++;

if(g>=8)g=0; // 打开2个573三态门,输出段码和位码

}

第二项

#include

#define uchar unsigned char

#define uint unsigned int

sbit oe=P1^3; //数码管段选、位选锁存器输出控制信号sbit dula=P1^4; //数码管段选锁存器控制信号

sbit wela=P1^5; //数码管位选锁存器控制信号

uchar j=0;

uchar code sled_bit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定义点亮数码管位选码

data uchar disp[8]={16,16,16,16,16,16,16,16};

uchar code table[18]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77, 0x7c,0x39,0x5e,0x79,0x71,0x00}; //共阴极数码管显示段码(0-F)

void delay( n ) //延时函数

data uchar n;

{ data uchar m;

while(n--)

for(m=0;m<1;m++);

}

void main(void)

{

uchar a,b,c,i,num;

TMOD=0x01; // 设置定时器T0为方式1定时

TH0=(65536-500)/256; // 给T0装入初值

TL0=(65536-500)%256; // 给T0装入初值

ET0=1; // 允许T0中断

EA=1; // CPU开中断

TR0=1; // 启动T0

oe=0;

P2=0xff;

while(1)

{ P2=0xf0;

delay(5);

P2=0xf0;

a=P2;

P2=0x0f;

delay(5);

P2=0x0f;

b=P2;

a=a|b;

if(a!=0xff)

{while(P2!=0x0f);

switch(a)

{

case 0xee: num=0; break;

case 0xde: num=1; break;

case 0xbe: num=2; break;

case 0x7e: num=3; break;

case 0xed: num=4; break;

case 0xdd: num=5; break;

case 0xbd: num=6; break;

case 0x7d: num=7; break;

case 0xeb: num=8; break;

case 0xdb: num=9; break;

case 0xbb: num=10; break;

case 0x7b: num=11; break;

case 0xe7: num=12; break;

case 0xd7: num=13; break;

case 0xb7: num=14; break;

case 0x77: num=15;

}

for(i=0;i<7;i++) disp[i]=disp[i+1];

disp[7]=num;

}

delay(255);

}

}

void T0_int(void) interrupt 1

{ data uchar k;

TH0=(65536-1000)/256;

TL0=(65536-1000)%256;

oe=1; // 关闭2个573输出,防止在送数据时相互影响

k = disp[j]; // 每次显示ar[j]的数据

P0 = table[k]; // 相应显示数字段码

dula=1;

dula=0; // 锁存段码

P0=sled_bit[j]; // 选择相应数码管位选

wela=1;

wela=0; // 锁存位码

oe=0; // 打开2个573三态门,输出段码和位码

j++; // 为下一个显示做准备

if(j>=8)j=0;

}

五、实验结果

第一项:给单片机上电,未按键不显示,按K1键,动态显示“19491001”;按K2键,动态显示“20141210”。

第二项:给单片机上电,未按键不显示,按矩阵式键盘键值从小到大依次按键,依次显示为:

0,01,012,0123,01234,012345,0123456,01234567,12345678,234 56789,3456789A,456789Ab,56789AbC,6789AbCd,789AbCdE,89AbCdEF。

六、实验思考题

1、电路中为什么要用74LS573,不用74LS573,可用什么器件代替?

如果U1、U2的OE都直接接地,应如何编程?

答:电路中需要2片74LS573来驱动8个共阴极数码管,所以不能

用74LS573,可用74LS373代替。如果U1、U2的OE都直接接地,

即OE一直为0,74LS573总是输出锁存数据,所以应控制数据输入

锁存端LE,使之在需要锁存时置1。

2、为什么要等键弹起,才进行键值分析?

答:因为在按键前后都有一个过渡期,在这个阶段电平忽高忽低,最

好等这个时期过去再判断是否按键,同样,最好等键弹起,才进行键

值分析,这样才能分析准确。

3、如果用简单按键与矩阵式键盘构成组合按键,组合按键如何编程得

到键值?

答:采用线反转法,将行和列得到的键值相或来得到键值。

七、实验心得

通过这次实验,使我学到了不少实用的知识,更重要的是做实验的过程,思考问题的方法,这与其他的实验师通用的,真正使我受益匪浅。在做实验之前,我没有完全将课本上的理论知识掌握透彻,但在老师的讲解中,以及实践中对这些知识的理解有了很大一步的掌握。对单片机编程有了比较深刻的认识,希望在以后的学习以及实验中可以更加得心应手!

实验要认真分析问题,然后针对要求编写相应程序,对程序应该尽量简单化,符合要求的同时要简单有效,只有这样才能一步一步的进步,提高!

相关主题
相关文档
最新文档