键盘显示程序设计实验

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验四键盘显示程序设计
实验目的
1、理解串行接口键盘单片机汇编语言程序的基本结构
2、了解单片机汇编语言程序的设计和调试方法
3、掌握几个的基本的传送类、控制类指令的使用方法
实验仪器
单片机开发板、万利仿真机、稳压电源、计算机
实验原理
1、键盘接口电路工作原理
串行接口键盘盘电路如图4-15所示。

键盘扫描线与显示位选扫描信号共用。

键盘输入只需要一根线,电路简单。

键盘扫描信号从74LS164输出,低电平有效。

当扫描到某个键时,若按键按下,在KEY端得到低电平,否则得到高电平。

通过判断KEY的电平就可以知道相应键盘是否按下。

图4-15 键盘接口电路图
2、读键盘程序设计
从上面工作原理分析可知,读键程序可以和显示程序结合在一起,也可以单独设计。

这种结构的键盘同样存在抖动问题。

为了减少程序误动作,程序设计时也要考虑去抖动问题。

这里设计一个把键值显示在LED上的程序。

为了简化问题,把读键程序与显示结合起来。

程序流程图如图4-16所示。

图4-16 键盘扫描程序流程图
实验内容
1、设计程序把键值显示在数码管。

#include<reg52.h>
#include"display.h"
extern uchar point;
extern uchar table[8];
uchar t,temp,time;
char num;
bit flag1;
/*void main()
{
uchar i;
table[0]=0x0;
for(i=1;i<8;i++)
table[i]=0x11;
while(1)
{
num=dispkey();
if(flag==1)
table[0]=num;
delay_1ms(2);
}
}*/
/************************************************************
2、设计程序按不同键时实现不同功能。

功能:按向上键:最右边一位数码管数值加1(0-9),到9时加1回到0 按向下键:最右边一位数码管数值减加1(9-0),到0时减1回到9
按向左键:显示数字左移一位
按向右键:显示数字右移一位
keypointr:短按小数点右移,长按显示学号;
接口:上



keypointr
keypointl
**************************************************************/ void main()
{
uchar i,j=7,k=0;
for(i=0;i<8;i++)
table[i]=0x11;
TMOD=0x01;
EA=1;
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
ET0=1;
TR0=1;
table[7]=0x1;
while(1)
{
delay_1ms(5);
temp=dispkey();
switch(temp)
{
case 5: if ( flag==0)
{
num=++table[j];//加1
if(num==10)
num=0;
table[j]=num;
delay_1ms(1);
}; flag=1; break;
case 4:if ( flag==0)
{
num=--table[j];//减1
if(num==-1)
num=9;
table[j]=num;
delay_1ms(1);
};flag=1;break;
case 2: if ( flag==0) //右移
{
if(j==7)
{
table[0]=table[7];
table[7]=0x11;
j=0;continue;
}
table[j+1]=table[j];//左边赋给右边
j++;
table[j-1]=0x11;
delay_1ms(1);//关闭左一位
};flag=1;break;
case 8:if ( flag==0)
{ //左移
if(j==0)
{
table[7]=table[0];
table[0]=0x11;
j=7;continue;
}
table[j-1]=table[j];//右边赋给左边
j--;
table[j+1]=0x11;
delay_1ms(1);//关闭右一位
};flag=1;break;
case 1:if ( flag==0) //小数点右移
{
if(flag1==1)
{
table[0]=0x9;
table[1]=0x4;
table[2]=0x0;
table[3]=0x8;
table[4]=0x1;
table[5]=0x0;
table[6]=0x3;
table[7]=0x1;
}
else
{
if(k==7)
{ point=tablepoint[7];
k=0;continue;
}
point=tablepoint[k];
k++;
delay_1ms(1);
}
};flag=1;break;
default:flag=0; break;
}
}
}
void timer0() interrupt 1
{
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
t++;
time++;
if(temp==1)
{
if(time==50)
{
if(temp==1)
flag1=1;
time=0;
}
}
}
/*******************************************************
显示函数
*******************************************************/
//#define __DISPLAY_H__
#include"display.h"
uchar code disptable[]={0x03,0x9F,0x25,0x0D,0x99,0x49,
0x41,0x1F,0x01,0x09,0x11,
0xC1,0x63,0x85,0x61,0x71,0xfe,0xff};//0~F数码代码
uchar code tablepoint[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 }; uchar point;
uchar table[8];
void delay_1ms(uchar z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=123;y>0;y--);
}
uchar dispkey(void)
{
uchar i,keynum=0;
i=8;
DA T=disptable[table[i-1]];
if(point&tablepoint[i-1])
DA T=DA T&0xfe; //加入小数点
DISPDIN =0;
DISPCLK =0;
DISPCLK =1;
DISPDIN =1;
delay_1ms(1);
if(!key)
{
delay_1ms(5);
if(!key) keynum=i;
}
for (i=7;i>0;i--)
{
DA T =0xff;
DA T =disptable[table[i-1]];
if(point&tablepoint[i-1])
DA T=DA T&0xfe; //加入小数点
DISPCLK =0;
DISPCLK =1;
delay_1ms(1);
if(!key)
{
delay_1ms(5);
if(!key) keynum=i;
}
}
DA T=0xff;
return keynum;
}
思考题
1、当按加1键时,每按一次数码管值变化可能超过1,是什么原因?
答:原因是机械按键会有抖动现象,所以每按一次数码管值变化可能超过1。

2、如何实现长按键处理。

当长按最左键时(约2秒),显示学号后8位。

答:显示函数与主函数为:
uchar dispkey(void)
{
uchar i;
i=8;
next=0;
DA T=disptable[table[i-1]];
//if(point&tablepoint[i-1])
//DA T=DA T&0xfe; //加入小数点
DISPDIN =0;
DISPCLK =0;
DISPCLK =1;
DISPDIN =1;
delay_1ms(1);
if(!key) //左键
{
delay_1ms(10;
if(!key)
{
delay_1ms(400);
if(!key)
{
delay_1ms(400);if(!key)flag1=1;
}
}
else {falg1=0;next=i;}
}
for (i=7;i>0;i--)
{
DA T =0xff;
DA T =disptable[table[i-1]];
// if(point&tablepoint[i-1])
// DA T=DA T&0xfe; //加入小数点
DISPCLK =0;
DISPCLK =1;
delay_1ms(1);
if(!key)
{
delay_1ms(5);
if(!key) next=i;
}
}
DA T=0xff;
if(before==0&&next!=0) {flag=1;return 0;}
if(before!=0&&next==0) return before;
}
void main()
{
uchar i,j=7,k=0;
for(i=0;i<8;i++)
table[i]=0x11;
table[7]=0x1;
while(1)
{
temp=dispkey();
if(flag==1&&temp!=0)
{
if(flag1==1)
{
table[0]=0x9;
table[1]=0x4;
table[2]=0x0;
table[3]=0x8;
table[4]=0x1;
table[5]=0x0;
table[6]=0x3;
table[7]=0x1;
}
if(flag1==0)
{
if(k==7)
{ point=tablepoint[7];
k=0;continue;
}
point=tablepoint[k];
k++;
delay_1ms(1);
}
}
before=next;
}
}。

相关文档
最新文档