实验四 动态显示与矩阵式键盘实验 计科173BJ 李浩葳Word文档格式.docx
- 文档编号:5875913
- 上传时间:2023-05-05
- 格式:DOCX
- 页数:22
- 大小:3.29MB
实验四 动态显示与矩阵式键盘实验 计科173BJ 李浩葳Word文档格式.docx
《实验四 动态显示与矩阵式键盘实验 计科173BJ 李浩葳Word文档格式.docx》由会员分享,可在线阅读,更多相关《实验四 动态显示与矩阵式键盘实验 计科173BJ 李浩葳Word文档格式.docx(22页珍藏版)》请在冰点文库上搜索。
。
软件设计:
本实验采用外部中断和矩阵键盘合为同一个程序的方式,但不能同时使用。
1、动态显示
采用中断处理按键,利用全局变量strKey控制要显示的数字串,数字串保存在二维数组str[][]中,按下K1置strKey为0利用数码管显示第0行的数字串,按下K2置strKey为1利用数码管显示第1行的数字串。
数码管的显示:
T0每500us中断1次,在T0中断中点亮一个数码管。
在T0中断函数中,①P1.3(OE)=1,U3、U4输出高阻;
②P1.4(LE1)=1,P0口输出段码,P1.4=0,U3锁存输入的段码;
③P1.5(LE2)=1,P0口输出位选码,P1.5=0,U4锁存输入的位选码;
④P1.3=0,U3、U4同时输出段码和位选码,进行显示。
2、矩阵式键盘按键识别
采取行列扫描方式判断按键,利用数组N[]储存矩阵键盘的十六个按键值。
以备方便使用。
在判断为相应的键值后,要利用while(P2==键值)来等待键抬起(消抖),否则可能会出现一次按键发生多次事件的情况(本次按键在按键扫描循环里再次执行到了该按键判断语句,造成错误)。
主要算法1:
1、全局变量的定义:
ucharN[17]={0x00,0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,
0xe7,0xd7,0xb7,0x77};
//矩阵键盘
ucharnumCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
//共阴极数码段码
ucharmark[]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//共阴极位选码
ucharint_mark;
//定义位选中断次数计数变量
ucharkey_mark=16;
//定义按键标志
ucharstr[2][8]={{2,0,1,9,1,2,0,2},{1,9,4,9,1,0,0,1}};
//定义显示的两串数字
ucharstrKey=2;
//定义显示数字串标志
ucharcount=0;
//定义已显示的数字个数
ucharnumStr[9]={16,16,16,16,16,16,16,16,16};
//记录矩阵键盘按下的数字
count用来记录当前输入了几个数字,当为8时禁止键盘输入数字,numStr用来记录已输入的数字。
int_mark用来控制位选。
2、定时器T0中断函数:
//定时器T0中断,刷新数码管
voidrefresh()interrupt1{
if(int_mark==9){//位选计数溢出清零
int_mark=1;
}
//外部中断0模式:
动态显示
if(EX0&
&
strKey!
=2){
display(str[strKey][int_mark-1],int_mark);
//矩阵键盘模式:
可控动态显示与按键识别
elseif(!
EX0){
display(numStr[int_mark],int_mark);
int_mark++;
TH0=TH(500);
//给定时器T1高8位赋值
TL0=TL(500);
//给定时器T1低8位赋值
}
3、显示单个数码管函数:
voiddisplay(ucharn,ucharm){
OE=1;
LE1=1;
out=numCode[n];
LE1=0;
LE2=1;
out=mark[m];
LE2=0;
OE=0;
4、主函数初始化及矩阵键盘行列扫描函数局部:
voidmain(){
uchartemp;
uchari;
TMOD=0x01;
//设置定时器T0为方式1定时
IE=0x83;
//总中断开,允许定时器T0、外部中断0中断
IT0=1;
//选择外部中断0为跳沿触发方式
//给定时器T0高8位赋值
//给定时器T0低8位赋值
int_mark=0;
//位选中断次数清零
TR0=1;
//启动定时器T0
while
(1){
if(count<
9&
!
P2=0xef;
for(i=0;
i<
=3;
i++){
if(L1==0&
count<
8){//第一行
key_mark=i+0;
if(P2==N[1]){//数字7N1
inputNum(7);
while(P2==N[1]);
}
if(P2==N[2]){//数字8N2
inputNum(8);
while(P2==N[2]);
if(P2==N[3]){//数字9N3
inputNum(9);
while(P2==N[3]);
if(P2==N[4]){//无效键N4
//inputNum(key_mark);
while(P2==N[4]);
}
5、数字串数组的操作:
//设置全部数字
voidsetAllNum(ucharnum){
uinti;
for(i=0;
9;
i++){numStr[i]=num;
count=8;
//清零已有数字
voidsetNumZero(){
i++){numStr[i]=numStr[i]==16?
16:
0;
//键盘输入数字
voidinputNum(ucharnum){
//数字数组左移
8;
i++){numStr[i]=numStr[i+1];
numStr[8]=num;
count++;
2、实验原理图
图2-1实验原理图
3、程序流程图
图2-2程序流程图
三、源程序
#include"
reg51.h"
#defineucharunsignedchar
#defineuintunsignedint
#defineTH(a)(65536-a)/256//定义装入定时器高8位的时间常数
#defineTL(a)(65536-a)%256//定义装入定时器低8位的时间常数
#defineoutP0
//锁存器开关
sbitOE=P1^3;
sbitLE1=P1^4;
sbitLE2=P1^5;
//外部中断按键
sbitK1=P2^0;
sbitK2=P2^1;
sbitK3=P2^2;
sbitK4=P2^3;
//行扫描标志
sbitL1=P2^0;
sbitL2=P2^1;
sbitL3=P2^2;
sbitL4=P2^3;
//延时函数
voiddelay(time){
uintj;
for(j=0;
j<
time;
j++){}
voidsetAllNum(ucharnum){
numStr[i]=num;
voidsetNumZero(){
numStr[i]=numStr[i]==16?
voidinputNum(ucharnum){
numStr[i]=numStr[i+1];
//判断是否是正常按键
uintisNormalKey(ucharkey){
if(key==0xee||key==0xde||key==0xbe||key==0x7e||
key==0xed||key==0xdd||key==0xbd||key==0x7d||
key==0xeb||key==0xdb||key==0xbb||key==0x7b||
key==0xe7||key==0xd7||key==0xb7||key==0x77){
return1;
}else{
return0;
if(L2==0&
8){//第二行
key_mark=i+4;
if(P2==N[5]){//数字4N5
inputNum(4);
while(P2==N[5]);
if(P2==N[6]){//数字5N6
inputNum(5);
while(P2==N[6]);
if(P2==N[7]){//数字6N7
inputNum(6);
while(P2==N[7]);
if(P2==N[8]){//无效键N8
while(P2==N[8]);
if(L3==0&
8){//第三行
key_mark=i+8;
if(P2==N[9]){//数字1N9
inputNum
(1);
while(P2==N[9]);
if(P2==N[10]){//数字2N10
inputNum
(2);
while(P2==N[10]);
if(P2==N[11]){//数字3N11
inputNum(3);
while(P2==N[11]);
if(P2==N[12]){//切换到外部中断N12
while(P2==N[12]);
strKey=2;
EX0=1;
//打开外部中断0
if(L4==0){//第四行
key_mark=i+12;
if(P2==N[13]){//全部清零N13
setAllNum(0);
while(P2==N[13]);
if(P2==N[14]){//数字0N14
inputNum(0);
while(P2==N[14]);
if(P2==N[15]){//局部清零N15
setNumZero();
while(P2==N[15]);
if(P2==N[16]){//回车键N16
setAllNum(16);
count=0;
while(P2==N[16]);
delay(500);
temp=P2;
temp=temp|0x0f;
temp=temp<
<
1;
P2=temp;
}
}
//显示单个数码管
//外部中断0,按键控制
voidkeyControl()interrupt0{
if(INT0==0){
//K1键按下,动态显示"
20191202"
if(K1==0){
strKey=0;
//K2键按下,动态显示"
19491001"
if(K2==0){
strKey=1;
//K3键按下,关闭外部中断0
if(K3==0){
while(!
K3);
EX0=0;
//K4键按下,
if(K4==0){
四、实验结果
动态显示:
1、开机即等待外部中断键盘按下,K1键按下动态显示"
(如图4-1)
图41K1键按下动态显示“20191202”
2、K1键按下动态显示"
(如图4-2)
图42K2键按下动态显示“19491001”
可控动态显示与按键识别:
1、N1~N3或N5~N7或N9~N11或N14键按下,给数码管从末位添加数字,N1~N3对应7~8,N5~N7对应4~6,N9~N11对应1~3,N14对应0输入满8位时禁止再次输入(如图4-3)
图43输入数字“12137”
2、N13、N15或N16键按下,N13键:
8位数字全部清零(如图4-6),N15键:
已显示数字清零(如图4-4),N16键:
8位数字全部清空(如图4-7)
图44N15键按下局部清零
图45继续输入数字通过数码管显示
图46N13键按下所有数字清零
图47N16键按下清空数码管
五、实验思考题
1、电路中为什么要用74LS573,不用74LS573,可用什么器件代替?
如果U1、U2的
都直接接地,应如何编程?
电路中需要2片74HC573来驱动数码管,所以不能用74LS573,可用74LS373代替。
都直接接地,即
一直为0,74HC573总是输出锁存数据,所以应空值数据输入锁存端LE,使之在需要锁存时置1.
2、为什么要等键弹起,才进行键值分析?
因为在按键前后都有一个过渡期,在这个阶段电平忽高忽低,最好等这个时期过去再怕那段是否按键,同样,最好等键弹起,才进行键值分析,这样才能分析准确。
3、如果用简单按键与矩阵式键盘构成组合按键,组合按键如何编程得到键值?
采用线反转法,将行和列得到的键值相或来得到键值。
六、总结
通过本次实验,让我对单片机的编程的思考问题的方法有了改善。
在做实验之前,对于书本上的理论知识还理解得不够透彻,但在老师的讲解中,以及实践中对这些知识的理解有了很大一步的掌握。
对单片机编程有了更深刻的认识。
实验要认真分析问题,然后针对要求编写相应程序,在发现问题然后解决问题最后做好实验的过程中提高自己的能力。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验四 动态显示与矩阵式键盘实验 计科173BJ 李浩葳 实验 动态 显示 矩阵 键盘 173 BJ