当前位置:首页 >> 电子/电路 >>

单片机原理及应用实验六 按键识别数码管显示实验_图文

电子信息学院 实验报告书

课 程 名: 题 目:

《单片机原理及应用实验》 实验六 按键识别数码管显示实验

软件+硬件实验

实验类别: 班 级: 学 号: 姓 名:

【设计】 电子 1313
26 吴限

评语:

(1)电路连接调试: □正确 □基本正确 (2)实验程序编写: □正确 □基本正确 (3)数据测量分析: □准确 □基本准确

□不正确 □不正确 □不准确

成绩:□A □B □C □D ,指导教师: 王英赫 批阅时间:2016 年 月 日

1

1、实验内容或题目
1)题目:按键识别数码管显示实验
2)实验内容:数码管显示矩阵按键号。

2、实验目的与要求
1)实验目的: 掌握按键识别及数码管显示的实现方法。
2)实验要求:
通过 XL2000 的 16 位矩阵按键,在数码管上分别显示 0~9,A,B,C,D,E,F。用 Keil 编译、Proteus 仿真,代码下载到单片机实验箱上验证。

3、实验仪器
(1)PC 微机 (2)实验箱
4、实验程序流程图

1台 1台
开始

初始化程序
N 有键按下 Y 延时去抖动
N 有键按下 Y
判断哪个键按下

显示相应的数字

结束

2
5、实验程序
(实验程序清单作为附件放在最后)
6、实验步骤
1)keil 中 C 语言程序实现。
2)在 proteus 中完成电路图设计,并实现仿真。
3)硬件实验部分:
用一条 8PIN 数据排线,把矩阵按键部份的 JP50,接到 CPU 部份的 P1 口 JP44; 接 8 位数码管的数据线。将数码管部份的数据口 JP5 接到 CPU 部份的 P0 口 JP51;接 8 位数码管的显示位线。将数码管部份的显示位口 JP8 接到 CPU 部份 的 P2 口 JP52.
7、实验数据及结果

3

8、思考题

采用 P3 口控制矩阵按键输入,程序应该如何修改?

答:本实验的程序中可以不用蜂鸣器驱动线,把以下程序的 sbit BEEP = P3 ^ 7;及函数 void beep() 等删掉后;需要把扫描键值的函数改一下:unsigned char keyscan()

{

unsigned char scan1, scan2, keycode,j;

P13= 0xf0;

scan1 = P3;

if (scan1 != 0xf0)

//判键是否按下

{

delayms(10);

scan1 = P3;

if (scan1 != 0xf0)

//二次判键是否按下

{

P1 = 0x0f;

scan2 = P3;

keycode = scan1 | scan2; //组合成键扫描编码

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

{

if (keycode == key_code[j])

//查表得键值

{

key = j;

return (key); //返回有效键值

}

}

}

}

else

P3 = 0xff;

return (key = 16); //返回无效码

4
} 即 P1 口换成 P3 口,而键编码数组是固定的,可以不变; 此外主函数中的 P1 口也要改为 P3 口:void main(void) {
P0 = 0xf7; //数码管初始显示"-" P2 = 0xfd;//数码管显示在第二位 P3 = 0xff; while (1) {
keyscan(); if (key < 16) //有效键值
{ P0 = disp_code[key]; //显示键值 } } }

<附件> 实验程序清单

#include <reg52.h>

#include <intrins.h> sbit BEEP = P3 ^ 7;

//蜂鸣器驱动线

unsigned char key;

unsigned char code disp_code[] =

{

0xf9,0xa4,0xb0,0x99,

0x92,0x82,0xf8,0x80,

0x90,0x88,0x83,0xc6,

0xc0,0x86,0x8e,0xc0};

unsigned char code key_code[] =

{

5

0xee, 0xed, 0xeb, 0xe7, 0xde, 0xdd, 0xdb, 0xd7, 0xbe, 0xbd, 0xbb,

0xb7, 0x7e, 0x7d, 0x7b, 0x77

//键编码数组

}; char code SST516[3] _at_ 0x003b; //保留仿真器 /********************延时子函数***************/

void delayms(unsigned int ms)

{

unsigned char t;

while (ms--)

{

for (t = 0; t < 114; t++);

}

} /*************x*0.14MS 延时子函数****************/

void delayus(unsigned char x)

{

unsigned char i;

while (x--)

{

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

{;

}

}

} /******************蜂鸣器驱动子函数*****************/

void beep()

{

unsigned char i;

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

{

delayus(6);

6

BEEP = !BEEP; //BEEP 取反

} BEEP = 1; delayms(150);

//关闭蜂鸣器 //延时

} /******************键盘扫描子函数*********************/

unsigned char keyscan()

{

unsigned char scan1, scan2, keycode, j;

P1 = 0xf0;

scan1 = P1; if (scan1 != 0xf0) //判键是否按下

{ delayms(10);

//延时 10ms

scan1 = P1; if (scan1 != 0xf0) //二次判键是否按下

{

P1 = 0x0f;

scan2 = P1; keycode = scan1 | scan2; //组合成键扫描编码

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

{ if (keycode == key_code[ j]) //查表得键值

{

key = j; return (key); //返回有效键值

}

}

}

}

else

7
P1 = 0xff; return (key = 16); //返回无效码 } /*************************主函数***********************/ void main(void) { P0 = 0xf7; //数码管初始显示"-" P2 = 0xfd;//数码管显示在第二位 P1 = 0xff; while (1) {
keyscan(); if (key < 16) //有效键值
{ P0 = disp_code[key]; //显示键值 beep(); //蜂鸣器响一声 } } }