实验四 综合应用设计——数码管动态显示与矩阵键盘的编程
一、实验目的:
1、掌握单片机I/O技术和程序设计等综合知识。
2、了解矩阵式键盘的内部结构和数码管显示的基本原理,掌握至少一种常用的按键识别方法。
3、熟练掌握数码管动态显示和矩阵键盘识别的综合应用。
二、实验内容:
设计一个矩阵键盘的识别和动态显示综合的系统,控制8个8段数码管动态扫描显示4*4矩阵键盘上按下的按键所对应的值。
三、实验要求:
给定一个4*4的矩阵键盘,16个按键对应显示0123456789ABCDE,第1次按下某按键在第一个8段数码管上显示对应的值,第2次在第二个数码管上显示,以此类推,第9次又在第一个数码管上显示,以此循环下去。其中ABCDE在数码管上无法表达,可以用其它代替,例如:B用8表示,D用0表示,E用H表示等。
四、实验设备及实验耗材:
计算机一台,WAVE6000软件模拟器,完成ISP下载的XLISP软件,XL1000单片机综合仿真实验仪一台(8个8段数码管,4*4矩阵键盘一个,89C51一片,9针对9针的串口线一条,USB电缆一条)
五、实验基本原理与方法:
查阅相关资料掌握矩阵式键盘的内部结构,8段数码管动态显示原理和常用的按键识别方法,建议使用按键识别方法中最常用的“行扫描法”编写程序。结合动态显示技术和矩阵键盘识别技术。
六、实验方案设计:
1、 采用哪些I/O口完成通信,采用何种按键识别的方法,如何综合动态显示技术和矩阵键盘识别技术。
2、 说明该程序的功能。
3、 硬件连接原理图。
七、实验步骤:
1. 弄清实验内容和实验要求。
2. 学习相关理论知识,提出实验方案,画出程序流程图。
软件流程图
3. 编写软件程序,作相关的程序注释,便于查看和调试。
4. 编译和调试。
伟福软件:
1. 打开伟福WAVE V3.20软件,采用伟福默认的仿真器就可以了。文件——新建文件,在弹出的窗口中输入实验程序,保存为“文件名.asm”文件,若窗口内的部分程序字体颜色发生改变,表示保存成功。
2. 文件——新建项目
加入模块文件:打开刚才已经保存的文件“文件名.asm”
加入包含文件:取消
保存项目“文件名.PRJ”,在项目窗口里可以看到。
3. 确保仿真器——仿真器设置——目标文件里“生成HEX文件”和“生成BIN文件”被勾选上。
4. 项目——编译,调试,编译成功后就会生成“文件名.HEX”文件。
5. 软件调试成功后,完成硬件连接。
接线方法:
1、 用一条8PIN数据排线,把矩阵按键部份的JP50,接到CPU部份的P1口JP44。
2、接8位数码管的数据线。将数码管部份的数据口 JP5接到CPU部份的P0口JP51。
3、接8位数码管的显示位线。将数码管部份的显示位口 JP8接到CPU部份的P2口JP52。
键盘口P1,数码管显示p2, 数码管段位p0口
6. 将程序烧写到单片机上,试运行。若出现问题,修改程序,重新编译和调试,直至运行成功。
ISP下载烧写程序:
确保试验仪与计算机的串口和USB口都连接上后,打开软件XLISP,注意串口设置,计算机和试验仪采用的是哪个串口连接,不同的计算机可能会不同,有的是COM1,有的是COM3等,可以采用自动检测功能查找。也可以在打开软件后,选项—串口,更改串口设置。如果串口选择错误,实验将无法进行。
打开(打开生成的HEX文件)——智能一键通。即可看到运行结果。重新烧写程序时应该先擦除上一个的再烧写。
实验结果: 在4*4键盘上第一次按下任一个键,在第一个数码管上显示对应的键值,显示后该数码管熄灭,若希望能显示时间稍微长一点,可以在每一个撤销选中关显示(SETB P2.x)的后面加入一个延时程序。第二次按下的,在第二个数码管上显示,依次类推,第八次按下在第八个数码管上显示。第九次按下又重新在第一个数码管上显示。
K00:0 K01:1 K02:2 K03:3 K04:4 K05:5
K06:6 K07:7 K08:8 K09:9
K0A: K0B: K0C: K0D: K0E: K0F:
八、实验报告要求:
1.分析程序,说出程序的功能,画出软件流程图。
2.源程序加注释。
3.画出硬件接口原理电路图。
4. 实验小结(包括理论知识的总结和实验结果的分析)
第二篇:键盘显示程序设计实验
实验四 键盘显示程序设计
实验目的
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;
DAT=disptable[table[i-1]];
if(point&tablepoint[i-1])
DAT=DAT&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--)
{
DAT =0xff;
DAT =disptable[table[i-1]];
if(point&tablepoint[i-1])
DAT=DAT&0xfe; //加入小数点
DISPCLK =0;
DISPCLK =1;
delay_1ms(1);
if(!key)
{
delay_1ms(5);
if(!key) keynum=i;
}
}
DAT=0xff;
return keynum;
}
思考题
1、 当按加1键时,每按一次数码管值变化可能超过1,是什么原因?
答:原因是机械按键会有抖动现象,所以每按一次数码管值变化可能超过1。
2、如何实现长按键处理。当长按最左键时(约2秒),显示学号后8位。
答:显示函数与主函数为:
uchar dispkey(void)
{
uchar i;
i=8;
next=0;
DAT=disptable[table[i-1]];
//if(point&tablepoint[i-1])
//DAT=DAT&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--)
{
DAT =0xff;
DAT =disptable[table[i-1]];
// if(point&tablepoint[i-1])
// DAT=DAT&0xfe; //加入小数点
DISPCLK =0;
DISPCLK =1;
delay_1ms(1);
if(!key)
{
delay_1ms(5);
if(!key) next=i;
}
}
DAT=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;
}
}