实验四 键盘接口设计

合集下载

实验四 键盘实验

实验四  键盘实验

实验四矩阵键盘控制接口设计实验一、实验目的1、掌握MAX+plus 软件的使用方法。

2、掌握层次化设计方法:底层为文本文件,顶层为图形文件。

3、了解用12 位按健输入开关来设计并实现一个3 x 4 矩阵键盘接口控制器。

了解弹跳消除电路的工作原理。

二、实验设备1、计算机2、MAX+plus II软件及实验箱三、实验原理该实验系统中没有矩阵键盘,可以用12 位按键开关来实现矩阵键盘的功能。

当按键被按下时改按键的节点会呈现‘0’状态,反之为‘1’。

将12 个键进行编码后就可以实现距阵键盘的功能。

键盘编码电路:由于每个按键开关都是独立的,故有12 路输入,3X4 键盘有12 个键值,4位二进制数即可表示全部状态。

因此,键盘编码电路为12 输入4 输出编码器。

12 个按键可分为10 个数字键和2 个功能键。

数字键主要用来输入数字,功能键一般实现一些特殊用途(如确认、清除等)。

4 位输出从0~9 表示10 个数字键,11 和12 表示两个功能键。

弹跳消除电路:因为按键开关是机械式结构,在开关切换的瞬间会在接触点出现来回弹跳的现象,对于激活关闭一般电器并不会有何影响,但对于灵敏度较高的电路,却有可能产生误动作而出错。

跳现象产生的原因可从下图说明。

虽然只是按下按键一次然后放开,然而实际产生的按键信号却不只跳动一次,经过取样的检查后将会造成误判,以为按键两次。

弹跳现象产生错误的抽样结果如果调整抽样频率可以发现弹跳现象获得了改善。

因此在开关输入信号处必须加上弹跳消除电路,避免误操作信号的发生。

注意:弹跳消除电路所使用脉冲信号的频率必须要选用合适,频率太低则按键反应痴动,频率太高则起不到消除弹跳的作用,而且消除弹跳电路设计的不同对频率也有不同的要求。

数码管采用共阴极:段码表四、实验内容1、用12 个按键开关实现矩阵键盘,当按下某一键时在数码管上显示对应的键值。

2、分析仿真示例程序理解弹跳消除的实现原理。

3、通过改变CLK 信号,理解时钟信号对弹跳消除的影响。

键盘接口实验

键盘接口实验

实验六键盘接口实验一、实验目的1、掌握Keil C51软件与Protues软件联合仿真调试的方法;2、掌握单片机的键盘接口电路;3、掌握单片机的键盘扫描原理;4、掌握键盘的去抖原理及处理方法。

二、实验仪器与设备1、微机一台2、Keil C51集成开发环境3、Protues仿真软件三、实验内容1、用Protues设计一矩阵键盘接口电路。

要求利用P1口接一4×4矩阵键盘。

串行口通过一74LS164接一共阴极数码管。

2. 用线反转法编写矩阵键盘识别程序,用中断方式(列线通过4输入与门74LS21接/INT0),无按键按下时数码管循环画8;有按键按下时产生中断并将按键的键值0~F通过串行口输出,在数码管上显示3秒后返回;返回后,数码管继续循环画“8”。

3.将P1口矩阵键盘改为8个独立按键(用中断方式设计),用定式扫描方式,每10ms扫描一次,其中key7每按动一次数码管显示的数字加1(从0开始),其他按键显示按键编号。

四、实验说明矩阵键盘识别一般包括以下内容:⑴判别有无键按下。

⑵键盘扫描取得闭合键的行、列号。

⑶用计算法或查表发的到键值;⑷判断闭合键是否释放,如没释放则继续等待。

⑸将闭合键的键值保存,同时转去执行该闭合键的功能。

五、实验步骤1、用Protues设计键盘接口电路;2、在Keil C51中编写键盘识别程序,编译通过后,与Protues联合调试;3、按动任意键,观察键值是否能正确显示。

六、实验电路仿真图矩阵键盘独立按键七、实验程序矩阵键盘#include<reg51.h>#define uchar unsigned char#define uint unsigned intuint m=0;count=0;bit flag=0;uchar code key_table[]={0xee,0xde,0xbe,0x7e ,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0 xbb,0x7b,0xe7,0xd7,0xb7,0x77}; uchar code table0[]={0x3f,0x06,0x5b,0x4f,0x 66,0x6d,0x7d,0x07,0x7f,0x6f,0x77 ,0x7c,0x39,0x5e,0x79,0x71};uchar code table[]={0x00,0x01,0x21,0x61,0x6 5,0x6d,0x7d,0x7d,0x7f};void delay(uchar c){uchar a,b;for(;c>0;c--)for(a=142;a>0;a--)for(b=2;b>0;b--);}void main(){ P1=0xf0;TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;EX0=1;IT0=1;ET0=1;TR0=1;SCON=0x00;IP=0x02;for(m=0;m<9;m++){SBUF=table[m];delay(200);while(TI==0);TI=0;}}void INT_0() interrupt 0 {uchar t,n,i,j;P1=0xf0;if(P1!=0xf0){delay(20);if(P1!=0xf0){t=P1;P1=0x0f;j=t|P1;for(i=0;i<16;i++)if(j==key_table[i]){n=i;break;}SBUF=table0[n];while(TI==0);TI=0;}while(flag==0);P1=0xf0;}}void time0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;count++;if(count>=60){count=0;flag=1;}}2.独立按键#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code table[]={0x00,0x01,0x21,0x61,0x6 5,0x6d,0x7d,0x7d,0x7f};uchar code table0[]={0x3f,0x06,0x5b,0x4f,0x 66,0x6d,0x7d,0x07,0x7f,0x6f,0x77 ,0x7c,0x39,0x5e,0x79,0x71};uint i=0,k=0,temp,m;bit flag=0;void delay(uint c){uint a,b;for(;c>0;c--)for(a=30;a>0;a--)for(b=2;b>0;b--);}void main(){ uint j;ET0=1;TR0=1;TMOD=0X01;TH0=(65536-10000)/256;TL0=(65536-10000)%256;for(m=0;m<9;m++){SBUF=table[m];delay(200);while(TI==0);TI=0;}for(j=0;j<100;j++){if(TF0==1){TH0=(65536-10000)/256;TL0=(65536-10000)%256;TF0=0;if(P1!=0xff&&(flag==0)){temp=P1;flag=1;switch(temp){case 0xfe: SBUF=table0[0];while(TI==0);TI=0;delay(500);break;case 0xfd: SBUF=table0[1];while(TI==0);TI=0;delay(500);break;case 0xfb: SBUF=table0[2];while(TI==0);TI=0;delay(500);break;case 0xf7:SBUF=table0[3];while(TI==0);TI=0;delay(500);break;case 0xef:SBUF=table0[4];while(TI==0);TI=0;delay(500);break;case 0xdf:SBUF=table0[5];while(TI==0);TI=0;delay(500);break;case 0xbf:SBUF=table0[6];while(TI==0);TI=0;delay(500);break;case0x7f:SBUF=table0[i++];while(!TI==0)TI=0;delay(500);break;}}else if(P1==0xff) flag=0;}delay(10);}}八、实验总结1、由于对定时器扫描方式不熟悉,一开始把定时器扫描方式写成了查询方式。

编码式键盘接口设计实验

编码式键盘接口设计实验

一、实验目的和要求①目的:加深对VHDL语言的理解,提高对VHDL语言的应用能力,能够分析设计目标的电路特性,根据其设计合理的VHDL程序,并能在实验箱上实际操作所设计的电路,能够设计较为复杂的数字系统。

②要求:(1)在FPGA内部设计4X4编码式键盘接口,其功能是将16个按键转化为4位二进制编码(如按K0键输出0000,K1键输出0001,····,K15键输出1111),同时给出键键有效信息,每次键有效时,产生由高到低的跳变。

(2)将键值和键有效次数通过LED数码管显示。

③实验条件:(1)实验箱型号:伟福公司EDA6000实验箱(2)CPLD型号:Altera公司的EPM7128SLC84-15(3)开发环境: Quartus II +WAV2000二、基本原理三、程序流程(1)分频电路FREDIV的设计实际上是一个位二进制计数器(n的具体值由输入时钟频率确定),clk为时钟输入信号,计数器的最高位作为分频输出信号co,使其占空比为50%,本次实验分频系数为1024。

(2)列扫描计数器CNT4A的设计是一个具有使能控制的4位二进制加法计数器(3)2-4译码器DECODE的设计(4)优先编码器ENCODE的设计设I0~I3为键输入信号,低电平有效,设优先级次序I0最高,I3最低。

Y1~Y0为编辑输出,KA为键值检测信号。

(5)具有清零和保持功能的十六进制加法计数器CNT16A的设计(6)寄存器REG4的设计(7)三态缓冲器TS4的设计(8)计数器CNT4B的设计(9)LED数码管显示译码DECODERS的设计四、仿真与调试分频电路FREDIV:将发生器封装成一个元件,以便在更高层设计中调用。

列扫描计数器CNT4A:将发生器封装成一个元件,以便在更高层设计中调用。

程序代码见附页。

2-4译码器DECODE:将发生器封装成一个元件,以便在更高层设计中调用。

程序代码见附页。

实验四 8255键盘及显示接口实验

实验四  8255键盘及显示接口实验

实验四 8255键盘及显示接口实验一、实验目的了解键盘扫描及数码显示的基本原理,熟悉8255的编程/二、实验设备PC机一台,TD-PITE实验装置一套。

三、实验内容将8255单元与键盘及数码管显示单元连接,编写实验程序,扫描键盘输入,并将扫描结果送数码管显示。

键盘采用4×4键盘,每个数码管显示值可为0-F共16个数,。

实验具体内容如下:将键盘进行编号,记作0—F,当按下一个键时,将该键对应的编号在下一个数码管上显示出来,再按下一个按键时,便将这个按键的编号在下一个数码管上显示出来,数码管上可以显示最近4次按下的按键编号。

实验内容:将8255单元与键盘及数码管显示单元连接,编写实验程序,扫描键盘输入,并将扫描结果送数码管显示。

键盘采用4×4键盘,每个数码管显示值可为0~F共16个数。

实验具体内容如下:将键盘进行编号,记作0~F,当按下其中一个按键时,将该按键对应的编号在一个数码管上显示出来,当再按下一个按键时,便将这个按键的编号在下一个数码管上显示出来,数码管上可以显示最近4次按下的按键编号。

8255键盘及显示实验参考接线图如图1所示。

键盘及数码管显示单元电路图如图4-1 所示。

图4-2 8255 键盘扫描及数码管显示实验线路图功能描述: 键盘及数码管显示实验,通过8255控制。

8255的B口控制数码管的段显示,A口控制键盘列扫描及数码管的位驱动,C口控制键盘的行扫描。

按下按键,该按键对应的位置将按顺序显示在数码管上。

实验程序:MY8255_A EQU 0600HMY8255_B EQU 0602HMY8255_C EQU 0604HMY8255_CON EQU 0606HSSTACK SEGMENT STACKDW 16 DUP(?)SSTACK ENDSDATA SEGMENTDTABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07HDB 7FH,6FH,77H,7CH,39H,5EH,79H,71HDATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATAMOV DS,AXMOV SI,3000HMOV AL,00HMOV [SI],AL ;清显示缓冲MOV [SI+1],ALMOV [SI+2],ALMOV [SI+3],ALMOV [SI+4],ALMOV [SI+5],ALMOV DI,3005HMOV DX,MY8255_CON ;写8255控制字MOV AL,81HOUT DX,ALBEGIN: CALL DIS ;调用显示子程序CALL CLEAR ;清屏CALL CCSCAN ;扫描JNZ INK1JMP BEGININK1: CALL DISCALL DALLYCALL DALLYCALL CLEARCALL CCSCANJNZ INK2 ;有键按下,转到INK2JMP BEGININK2: MOV CH,0FEHMOV CL,00HCOLUM: MOV AL,CHMOV DX,MY8255_AOUT DX,ALMOV DX,MY8255_CIN AL,DXL1: TEST AL,01H ;is L1?JNZ L2MOV AL,00H ;L1JMP KCODEL2: TEST AL,02H ;is L2?JNZ L3MOV AL,04H ;L2JMP KCODEL3: TEST AL,04H ;is L3?JNZ L4MOV AL,08H ;L3JMP KCODEL4: TEST AL,08H ;is L4?JNZ NEXTMOV AL,0CH ;L4KCODE: ADD AL,CLCALL PUTBUFPUSH AXKON: CALL DISCALL CLEARCALL CCSCANJNZ KONPOP AXNEXT: INC CLMOV AL,CHTEST AL,08HJZ KERRROL AL,1MOV CH,ALJMP COLUMKERR: JMP BEGIN CCSCAN: MOV AL,00HMOV DX,MY8255_AOUT DX,ALMOV DX,MY8255_CIN AL,DXNOT ALAND AL,0FHRETCLEAR: MOV DX,MY8255_BMOV AL,00HOUT DX,ALRETDIS: PUSH AXMOV SI,3000HMOV DL,0DFHMOV AL,DLAGAIN: PUSH DXMOV DX,MY8255_AOUT DX,ALMOV AL,[SI]MOV BX,OFFSET DTABLEAND AX,00FFHADD BX,AXMOV AL,[BX]MOV DX,MY8255_BOUT DX,ALCALL DALLYINC SIPOP DXMOV AL,DLTEST AL,01HJZ OUT1ROR AL,1MOV DL,ALJMP AGAINOUT1: POP AXRETDALLY: PUSH CXMOV CX,0006HT1: MOV AX,009FHT2: DEC AXJNZ T2LOOP T1POP CXRETPUTBUF: MOV SI,DIMOV [SI],ALDEC DICMP DI,2FFFHJNZ GOBACKMOV DI,3005HGOBACK: RETCODE ENDSEND START实验步骤:1. 按图4-1连接线路图;2. 编写实验程序,检查无误后编译、连接并装入系统;3. 运行程序,按下按键,观察数码管的显示,验证程序功能。

键盘接口实验

键盘接口实验
① CPU判断是否有键按下; CPU判断是否有键按下 判断是否有键按下; ② 确定按下的是哪一个键; 确定按下的是哪一个键; ③ 将信息转换为计算机能识别的代码
一般单片机系统中采用非编码键盘, 一般单片机系统中采用非编码键盘,非编码键盘是由软件 来识别键盘上的闭合键(包括键代码的产生、去抖等) 来识别键盘上的闭合键(包括键代码的产生、去抖等), 它具有结构简单,使用灵活等特点, 它具有结构简单,使用灵活等特点,因此被广泛应用于单 片机系统。 片机系统。
二、键盘工作原理 概念
键盘是由若干按键组成的开关矩阵, 键盘是由若干按键组成的开关矩阵,它是微型计算机最常用的输 入设备,用户可以通过键盘向计算机输入指令、地址和数据。 入设备,用户可以通过键盘向计算机输入指令、地址和数据。
按键的分类
编码键盘 非编码键盘
键盘输入信息的主要过程: 键盘输入信息的主要过程:
有按键信号? 有按键信号? Y 延时等待10ms 延时等待
N
仍有按键信号? N 仍有按键信号? Y 键盘处理 按键释放? 按键释放? Y N
消除抖动的程序设计流程图
三、矩阵式键盘的结构及原理 1、矩阵式键盘的结构
矩阵式键盘由行线和列线组成,按键位于行、 矩阵式键盘由行线和列线组成,按键位于行、列线的交 叉点上, DP-51S 叉点上 , 在 DP-51S 中 , 是由 8 列一行组成的 8×1 的 8 是由8 列一行组成的8 个键的行列式键盘, 个键的行列式键盘 , 即 1 根行线 KEY_REC 和 8 根列线 根行线KEY_REC KEY_REC和 KD_Q0~KD_Q7组成的8键键盘。 KD_Q0~KD_Q7组成的8键键盘。
键盘接口功能 判断有无键按下; 判断有无键按下; 消除键的抖动; 消除键的抖动; 求按下键的键号。 求按下键的键号。 非编码键盘

实验四 键盘显示程序设计

实验四 键盘显示程序设计

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

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

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

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

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

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

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

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

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

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

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

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

图4-16 键盘扫描程序流程图主程序 初值化,显示缓冲区,键值暂存,键盘缓存调用键盘显示程序键值相同 N显示计数为0 …… 键盘显示程序 N显示程序 延时程序执行后 读当前扫描的键状态,并存入键值暂存寄存器实验内容1、设计程序把键值显示在数码管。

2、设计程序按不同键时实现不同功能。

按最左边按键:小数点循环移位按向上键:最右边一位数码管数值加1(0-9),到9时加1回到0按向下键:最右边一位数码管数值减1(9-0),到0时减1回到9按向左键:显示数字左移一位按向右键:显示数字右移一位实验步骤及调试过程1、连接单片机开发板、万利仿真机2、连接仿真调试电缆(并口JTAG)3、打开ARM集成开发环境ADS,进行程序加载。

实验程序:#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit CLK=P3^4;sbit DIN=P2^3;sbit key=P1^0;char num1=0;num=1;num2;char k;uchar code table[]={0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,0x11,0xC1,0x63,0x85,0x61,0x71,0xFE};//0到F及off的代码void wei(uchar x); //声明函数void delay(uchar ms);void display(char wei,char shu);void clear164();uchar keyscan();void main(){clear164();wei(1);P0=0x03; //初始化显示的数为0,位数为第一位while(1){k=keyscan();switch(k){case 8:{++num2;if(num2>7) num2=0; }break; //最左边按键(原理图中的第七个):小数点循环移位case 1:{++num;if(num>7) num=0; };break; //按向右键(原理图中的第六个):显示数字右移一位case 5:{num1--;if(num1<0) num1=9;}break; //按向下键:最右边一位数码管数值减加1(9-0),到0时减1回到9case 4:{num1++;if(num1>9) num1=0;}break; //按向上键:最右边一位数码管数值加1(0-9),到9时加1回到0case 7:{--num;if(num<0) num=7;};break; //按向左键:显示数字左移一位}display(num2,16);display(num,num1);delay(2);}}void wei(char x) //数码管第X位显示{ char j;for (j=1;j<9;j++){if (x==j){ DIN=0;CLK=0;CLK=1;}else{DIN=1;CLK=0;CLK=1;}}P0=0xFE;}void delay(uchar ms) // 延时子程序(晶振12M){uchar i;while(ms--){for(i = 0; i < 120; i++);}}uchar keyscan(){char i,j;j=0;clear164();P0=0xff; //清除没有用到的位显示DIN=0;for(i=0;i<8;i++){CLK=0;CLK=1;DIN=1;if(key==0) //判断检测端口是否为0,若是就为按键值{delay(10);if(key==0){while(!key); //松手检测j=i+1;}}}return j;}void clear164()//将164输出所以清零{char k;for(k=0;k<8;k++){DIN=1;CLK=0;CLK=1;}}void display(char wei,char shu){uchar m,n;clear164();DIN=0;for(n=wei;n>0;n--)//去掉没有显示的位数{CLK=0;CLK=1;DIN=1;}CLK=0;CLK=1;P0=table[shu]; //显示号码的位数delay(5);for(m=8-wei;m>0;m--)//去掉剩下的位数{DIN=1;CLK=0;CLK=1;}}实验思考题1、当按加1键时,每按一次数码管值变化可能超过1,是什么原因?答:1)因为,按键在闭合和断开过程中出现一段抖动期,由于按键的不稳定性引起的,这是会呈现一串脉冲,可能是在松手时没去抖动。

数码管显示4×4键盘矩阵按键实验

数码管显示4×4键盘矩阵按键实验

5、4×4键盘矩阵按键实验一、实验目的及要求键盘实质上是一组按键开关的集合。

通常,键盘开关利用了机械触点的合、断作用。

键的闭合与否,反映在行线输出电压上就是呈高电平或低电平,如果高电平表示键断开,低电平则表示键闭合,反之也可。

通过对行线电平高低状态的检测,便可确认按键按下与否。

为了确保CPU对一次按键动作只确认一次按键有效,还必须消除抖动。

当按键较多时会占用更多的控制器端口,为减少对端口的占用,可以使用行列式键盘接口,本实验中采用的4×4键盘矩阵可以大大减少对单片机的端口占用,但识别按键的代码比独立按键的代码要复杂一些。

在识别按键时使用了不同的扫描程序代码,程序运行时LED灯组会显示相应按键的键值0~15的二进制数。

本实验中P2端口低4位连接是列线,高4位连接的是行线。

二、实验原理(图)三、实验设备(环境):1、电脑一台2、STC-ISP(V6.85I)烧写应用程序3、Keil应用程序四、实验内容(算法、程序、步骤和方法):#include<STC15F2K60S2.h> //此文件中定义了STC15系列的一些特殊功能寄存器#include"intrins.h"#define uint unsigned int#define uchar unsigned charuchar code dsy_code[]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0 F,0xff};uchar Pre_keyno=16,keyno=16;void delayMS(char x){uchar i;while(x--)for(i=0;i<120;i++) ;}void keys_scan(){uchar tmp;P2=0x0f;delayMS(5);tmp=P2^0x0f;switch(tmp){case 1:keyno=0;break;case 2:keyno=1;break;case 4:keyno=2;break;case 8:keyno=3;break;default:keyno=16;}P2=0xf0;delayMS(5);tmp=P2>>4^0x0f;switch(tmp){case 1:keyno+=0;break;case 2:keyno+=4;break;case 4:keyno+=8;break;case 8:keyno+=12;break;}}main(){P0=0x00;while(1){P2=0xf0;if(P2!=0xf0)keys_scan();if(Pre_keyno!=keyno){P0=~dsy_code[keyno];Pre_keyno=keyno;}delayMS(50);}}五、实验结论(结果):本实验实现了XXX功能,核心算法采用了XXX的方式,达到了预期目的。

实验四 键盘及显示实验

实验四    键盘及显示实验

实验四键盘及显示实验一、实验目的1、学习自制键盘与单片机的接口及程序处理方法;2、掌握数码管显示电路的构成及程序编制方法。

二、实验仪器设备THGZ—1型单片机·CPLD/FPGA开发综合实验装置1台。

三、实验内容与要求通过键盘输入数据和操作指令,并由LED显示器显示相关数据。

1、独立式键盘与动态LED显示起初显示器全黑,当按KEY1~KEY8任意键后,显示器显示与键号对应的字符(“1”~“8”),每次按键对应字符显示在最右边,前一次的左移一位。

图2-4.1 独立式键盘与动态LED显示实验电路2、矩阵式键盘与动态LED显示①单字符的循环显示起初显示器显示“In ”,按键盘上的“0”~“9”任意键后再按“开始”键,6位LED 显示器马上左循环显示(左移速度0.5s/字符)键入的字符,按“停止”键可以重复以上过程。

图2-4.2 单字符的循环显示实验电路②延时函数的时间测量用定时器/计数器0测量如下延时函数的延时时间。

delaytest(unsigned int time){ unsigned int i,j;for (i=0;i<time;i++)for (j=0;j<65535;j++);}开机显示“good”;按“测量”键后显示“InPArA”表明要通过键盘输入延时函数的实参值,输入实参值并显示该值;按“测量”键后以ms为单位显示测量结果;再按“测量”键将重复以上过程。

图2-4.3 延时函数的时间测量实验电路四、思考题1、比较独立式键盘与矩阵式键盘的异同。

2、键盘处理程序包括哪些过程?2、如何识别键盘上的各键?键值有何意义?3、何为消抖?有何意义?如何实现?实验四源程序清单TEST4-1.C#include <reg51.h>#define KeyISegCodeO P1 /*定义键盘输入口/动态LED显示器段码输出口*/#define BitCtrO P2 /*定义动态LED显示器位控码输出口*/unsigned char DispBuf[6]={10,10,10,10,10,10}; /*显示数组,初始化为不显示*/void delay(unsigned char time) /*延时函数*/{ unsigned char i,j;for (i=0;i<time;i++)for (j=0;j<255;j++);}unsigned char KeyBoardScan() /*键盘扫描函数*/{ unsigned char KeyV alue=0; /*键值,无键按下为0*/BitCtrO=0; /*关闭显示*/KeyISegCodeO=0xff; /*由输出转为输入*/if (KeyISegCodeO!=0xff){ delay(12); /*消抖延时约10ms(fosc=12MHz)*/if (KeyISegCodeO!=0xff){ switch (KeyISegCodeO){ case 0xfe: KeyV alue=1;break; /*KEY1按下,键值为1*/case 0xfd: KeyV alue=2;break; /*KEY2按下,键值为2*/case 0xfb: KeyV alue=3;break; /*KEY3按下,键值为3*/case 0xf7: KeyV alue=4;break; /*KEY4按下,键值为4*/case 0xef: KeyV alue=5;break; /*KEY5按下,键值为5*/case 0xdf: KeyV alue=6;break; /*KEY6按下,键值为6*/case 0xbf: KeyV alue=7;break; /*KEY7按下,键值为7*/case 0x7f: KeyV alue=8;break; /*KEY8按下,键值为8*/}while (KeyISegCodeO!=0xff); /*等待键释放*/}}return(KeyV alue); /*返回键值*/}void display(unsigned char NumLED) /*显示函数*/{ unsigned char code SegCode[16]={63,6,91,79,102,109,125,7,127,111,0}; /*0~9、显黑共阴极段码*/ unsigned char i;BitCtrO=1; /*指向显示器末位*/for (i=0;i<NumLED;i++){ KeyISegCodeO=SegCode[DispBuf[i]]; /*显示当前位*/delay(5); /*延时约4ms(fosc=12MHz)*/BitCtrO=BitCtrO<<1; /*指向前一位*/}}main(){ unsigned char KeyV alue,i;while(1){ KeyV alue=KeyBoardScan(); /*扫描键盘获得键值*/if (KeyV alue!=0){ /*显示缓冲区刷新*/for (i=5;i>0;i--)DispBuf[i]=DispBuf[i-1];DispBuf[0]=KeyV alue;}display(6); /*显示(6位)*/}}TEST4-2.1.C#include <reg51.h>#include <intrins.h>#define KeyROCISegCodeO P1 /*定义键盘行输出列输入/段码输出口*/#define BitCtrO P2 /*定义动态LED显示器位控码输出口*/#define NumRow 3 /*定义键盘行数为3*/#define NumColumn 4 /*定义键盘列数为4*/unsigned char DispBuf[6]={10,10,10,10,11,1}; /*显示数组,初始化为显示"In "*/unsigned char c_50ms=1; /*50毫秒计数*/void delay(unsigned char time) /*延时函数*/{ unsigned char i,j;for (i=0;i<time;i++)for (j=0;j<255;j++);}unsigned char KeyBoardScan() /*键盘扫描函数*/{ unsigned char row=NumRow,RowCode,column=NumColumn,ColumnState; /*行循环、行码、列循环、列状态*/BitCtrO=0; /*关闭显示*/KeyROCISegCodeO=0xf8; /*键盘行线均输出0*/if ((KeyROCISegCodeO|0x0f)!=0xff){ /*有键按下*/delay(12); /*消抖延时约10ms(fosc=12MHz)*/KeyROCISegCodeO=0xf8; /*键盘行线均输出0*/if ((KeyROCISegCodeO|0x0f)!=0xff){ /*确实有键按下,寻找是哪个键*/RowCode=0xfe; /*指向第1行*/for(row=0;row<NumRow;row++) /*扫描共NumRow行*/{ KeyROCISegCodeO=RowCode; /*当前行*/ColumnState=KeyROCISegCodeO|0x0f; /*获取列状态*/for(column=0;column<NumColumn;column++) /*查询共NumColumn列的状态*/if ((ColumnState|0x7f)==0x7f){ while ((KeyROCISegCodeO|0x0f)!=0xff); /*等待键释放*/return(row*NumColumn+column); /*返回键值*/}elseColumnState=_crol_(ColumnState,1); /*指向下一列*/RowCode=_crol_(RowCode,1); /*指向下一行*/}}}return(NumRow*NumColumn); /*返回无键值*/}void display(unsigned char NumLED) /*显示函数*/{ unsigned char code SegCode[12]={63,6,91,79,102,109,125,7,127,111,0,84}; /*0~9、黑、n共阴极段码*/ unsigned char i;BitCtrO=1; /*指向显示器末位*/for (i=0;i<NumLED;i++){ KeyROCISegCodeO=SegCode[DispBuf[i]]; /*显示当前位*/delay(6); /*延时约5ms(fosc=12MHz)*/BitCtrO=BitCtrO<<1; /*指向前一位*/}}main(){ unsigned char i,KeyV alue,lock=0; /*循环,键值,键联锁:0:"停止"键有效、1:数字键有效、2:"开始"键有效*/TMOD=1; /*定时计数器0定时、方式1*/TH0=(65536-50000)/256; /*定时计数器0定时50ms*/TL0=(65536-50000)%256;ET0=1; /*开定时计数器0中断*/EA=1; /*开总中断*/while(1){ KeyV alue=KeyBoardScan(); /*扫描键盘获得键值*/switch (KeyV alue) /*键处理*/{ case 12: break; /*无键按下不处理*/case 11: { if (lock==0){ /*"停止键"有效及处理*/TR0=0; /*关闭T0*/DispBuf[5]=1; /*左边第1个数码管显"I"*/DispBuf[4]=11; /*左边第2个数码管显"n"*/for (i=0;i<4;i++) DispBuf[i]=10; /*后面4个数码管显黑*/lock=1; /*数字键有效*/}} break;case 10: { if (lock==2){ /*"开始"键有效及处理*/TR0=1; /*启动T0*/lock=0; /*"停止"键有效*/}} break;default: { if (lock==1){ /*数字键有效及处理*/DispBuf[0]=KeyV alue; /*右边第1个数码管显键入的字符*/for (i=5;i>0;i--) DispBuf[i]=10; /*其余5个显黑*/lock=2; /*"开始"键有效*/}}}display(6); /*数码管(6个)显示*/}}/**********定时计数器0中断处理程序*********/TC0() interrupt 1 using 1{ unsigned char temp,i;TH0=(65536-50000)/256; /*定时计数器0重新定时50ms*/TL0=(65536-50000)%256;if (c_50ms++>10){ /*0.5s后使键入字符左环移1位*/c_50ms=1;temp=DispBuf[5];for (i=5;i>0;i--) DispBuf[i]=DispBuf[i-1];DispBuf[0]=temp;}}TEST4-2.2.C#include <reg51.h>#include <intrins.h>#define KeyROCISegCodeO P1 /*定义键盘行输出列输入/段码输出口*/#define BitCtrO P2 /*定义动态LED显示器位控码输出口*/#define NumRow 3 /*定义键盘行数为3*/#define NumColumn 4 /*定义键盘列数为4*/unsigned char DispBuf[6]={10,10,13,12,12,9}; /*显示数组,初始化为显示"good "*/unsigned long total; /*T0溢出计数*/void delay(unsigned char time) /*延时函数*/{ unsigned char i,j;for (i=0;i<time;i++)for (j=0;j<255;j++);}void delaytest(unsigned int time) /*延时函数*/{ unsigned int i,j;for (i=0;i<time;i++)for (j=0;j<65535;j++);}unsigned char KeyBoardScan() /*键盘扫描函数*/{ unsigned char row=NumRow,RowCode,column=NumColumn,ColumnState; /*行循环、行码、列循环、列状态*/BitCtrO=0; /*关闭显示*/KeyROCISegCodeO=0xf8; /*键盘行线均输出0*/if ((KeyROCISegCodeO|0x0f)!=0xff){ /*有键按下*/delay(12); /*消抖延时约10ms(fosc=12MHz)*/KeyROCISegCodeO=0xf8; /*键盘行线均输出0*/if ((KeyROCISegCodeO|0x0f)!=0xff){ /*确实有键按下,寻找是哪个键*/RowCode=0xfe; /*指向第1行*/for(row=0;row<NumRow;row++) /*扫描共NumRow行*/{ KeyROCISegCodeO=RowCode; /*当前行*/ColumnState=KeyROCISegCodeO|0x0f; /*获取列状态*/for(column=0;column<NumColumn;column++) /*查询共NumColumn列的状态*/if ((ColumnState|0x7f)==0x7f){ while ((KeyROCISegCodeO|0x0f)!=0xff); /*等待键释放*/return(row*NumColumn+column); /*返回键值*/ }elseColumnState=_crol_(ColumnState,1); /*指向下一列*/RowCode=_crol_(RowCode,1); /*指向下一行*/ }}}return(NumRow*NumColumn); /*返回无键值*/}void display(unsigned char NumLED) /*显示函数*/{ unsigned char code SegCode[18]={63,6,91,79,102,109,125,7,127,111,0,84,92,94,115,119,80,121}; /*0~9、黑、n、o、d、P、A、r、E共阴极段码*/unsigned char i;BitCtrO=1; /*指向显示器末位*/for (i=0;i<NumLED;i++){ KeyROCISegCodeO=SegCode[DispBuf[i]]; /*显示当前位*/delay(6); /*延时约5ms(fosc=12MHz)*/BitCtrO=BitCtrO<<1; /*指向前一位*/ }}void error(){ DispBuf[5]=17; /*显"E"*/DispBuf[4]=16; /*显"r"*/DispBuf[3]=16; /*显"r"*/DispBuf[2]=12; /*显"o"*/DispBuf[1]=16; /*显"r"*/DispBuf[0]=10; /*显黑*/}main(){ unsigned char temp,NumBit,i,KeyV alue; /*临时、数字位数,循环,键值*/ unsigned long result; /*实参值/测量结果*/bit lock=0 ; /*键联锁:0:"测量"键有效、1:数字键/"确认"键有效*/ TMOD=1; /*定时T0定时方式1*/TH0=0;TL0=0;ET0=1; /*开T0中断*/EA=1; /*开总中断*/while(1){ KeyV alue=KeyBoardScan(); /*扫描键盘获得键值*/switch (KeyV alue) /*键处理*/{ case 12: break; /*无键按下不处理*/case 11: { if (lock==0){ /*"测量键"有效及处理*/DispBuf[5]=1; /*显"I"*/DispBuf[4]=11; /*显"n"*/DispBuf[3]=14; /*显"P"*/DispBuf[2]=15; /*显"A"*/DispBuf[1]=16; /*显"r"*/DispBuf[0]=15; /*显"A"*/NumBit=0; /*无数字输入*/lock=1; /*数字/"确认"键有效*/}} break;case 10: { if (lock){ /*"确认"键有效及处理*/if (NumBit>0) /*限定必须输入至少1位实参值*/{ /*获得有效数字位*/for (i=4;i>0;i--)if (DispBuf[i]==10) DispBuf[i]=0;else break;result=10000*DispBuf[4]+1000*DispBuf[3]+100*DispBuf[2]+10*DispBuf[1]+DispBuf[0]; /*获得实参值*/if (result<65536&&result!=0){ total=0; /*T0溢出计数初值0*/TR0=1; /*启动T0*/delaytest((unsigned int)result);TR0=0; /*关闭T0*/result=(total*65536+TH0+TL0)/1000; /*获得ms为单位的测量结果*/if (result<1000000){ /*显示测量结果*/for (i=0;i<6;i++) /*获得测量结果数字位*/{ DispBuf[i]=result%10;result/=10;}for (i=5;i>0;i--) /*去掉测量结果数字位无效0*/if (DispBuf[i]==0)DispBuf[i]=10 ;else break;}elseerror(); /*结果超出显示范围,提示出错*/}elseerror(); /*实参为0或超出65535,提示出错*/}elseerror(); /*实参为0,提示出错*/lock=0; /*"测量"键有效*/}} break;default: { if (lock){ /*数字键有效及处理*/if (NumBit++<5) /*限定只能输入1~5位实参值*/{ if(NumBit!=1){ /*数字位左移*/temp=DispBuf[5];for (i=5;i>0;i--) DispBuf[i]=DispBuf[i-1];DispBuf[0]=temp;DispBuf[0]=KeyV alue;}else{ if (KeyV alue==0){ /*第1位数字为0,提示出错*/error();lock=0; /*"测量"键有效*/}else{ for (i=5;i>0;i--) DispBuf[i]=10;DispBuf[0]=KeyV alue;}}}else{ error();lock=0; /*"测量"键有效*/}}}}display(6); /*数码管(6个)显示*/}}/*******T0中断处理程序*******/TC0() interrupt 1 using 1{ total++;}。

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

实验四:矩阵式键盘接口设计
一、实验目的
1.掌握独立式按键和矩阵式键盘结构和工作原理。

2.掌握矩阵式键盘的按键识别和扫描方法。

3.掌握独立式按键和矩阵式键盘的接口电路及其编程应用。

二、实验说明
键盘的接口形式有两种:独立式按键接口和矩阵式键盘接口。

独立式按键是直接用I/O口构成的单个按键电路,其特点是每个按键单独占用一根I/O 口,每个按键的工作不会影响其它I/O口的状态。

独立式按键电路配置灵活,程序设计简单,但这种键盘占用硬件资源多,每个按键必须占用一根I/O口,因此,在按键较多时,I/O 口浪费较大,不宜采用。

矩阵式键盘由行线和列线组成,按键位于行、列线的交叉点上。

一个4×4的行、列结构可以构成一个含有16个按键的键盘,显然,在按键数量较多时,矩阵式键盘较之独立式按键键盘要节省很多I/O口。

矩阵式键盘中,行、列线分别连接到按键开关的两端,行线通过上拉电阻接到+5V 上。

当无键按下时,行线处于高电平状态;当有键按下时,行、列线将导通,此时,行线电平将由与此行线相连的列线电平决定。

这是识别按键是否按下的关键。

然而,矩阵键盘中的行线、列线和多个键相连,各按键按下与否均影响该键所在行线和列线的电平,各按键间将相互影响,因此,必须将行线、列线信号配合起来作适当处理,才能确定闭合键的位置。

识别按键的方法很多,其中,最常见的方法是扫描法。

按键按下时,与此键相连的行线与列线导通,行线在无键按下时处在高电平。

显然,如果让所有的列线也处在高电平,那么,按键按下与否不会引起行线电平的变化,因此,必须使所有列线处在低电平。

只有这样,当有键按下时,该键所在的行电平才会由高电平变为低电平。

CPU根据行电平的变化,便能判定相应的行有键按下。

在单片机应用系统中,键盘是人机对话不可缺少的组件之一。

在按键比较少时,我们可以一个单片机I/O口接一个按键,但当按键需要很多,I/O资源又比较紧张时,使用矩阵式键盘无疑是最好的选择。

4x4矩阵键盘是运用得最多的键盘形式,也是单片机入门必需掌握的一种键盘识别技术,下面我们就以实例来说明一下4 x 4矩阵键盘的识别方法。

如下图所示,我们把按键接成矩阵的形式,这样用8个I/O口就可以对16个按键进行识别了,节省了I/O口资源。

本实验采用矩阵式键盘,列线接于P3.4—P3.7,行线接于P3.0—P3.3,P0口接入一只数码管用来显示按键编号;编程实现4x4键盘,按“0”号键在数码管显示“0”,按“1”号键在数码管显示“1”,............,按“F”号键在数码管显示“F”。

三、实验内容及步骤
本实验采用51单片机的P0口经74HC573锁存器接单支共阴极数码管,P3口接4x4矩阵式键盘,行线接于P3.0—P3.3,列线接于P3.4—P3.7,实现按“0”号键在数码管显示“0”,按“1”号键在数码管显示“1”,............,按“F”号键在数码管显示“F”。

1、用Keil软件编辑应用程序,实现4x4键盘,按“0”号键在数码管显示“0”,按“1”号键在数码管显示“1”,............,按“F”号键在数码管显示“F”。

2、用proteus软件绘制实验所需硬件电路,并进行仿真运行。

(proteus软件引入器件型号:单片机:AT89C51;共阴极数码管7SEG-COM-CATHODE;常开按钮BUTTON:8D锁存器74HC573;上拉电阻RESPACK-8)。

四、源程序
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar num;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x80};
void delayms(uint xms)
{ uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void display(uchar num)
{
P0=table[num];
}
void xxcan()
{ uchar temp,key;
P3=0xfe;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{ delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{ case 0xee:key=0;break;
case 0xde:key=1;break;
case 0xbe:key=2;break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
display(key);
}
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{ delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{ temp=P3;
switch(temp)
{ case 0xed:key=4;break;
case 0xdd:key=5;break;
case 0xbd:key=6;break;
case 0x7d:key=7;break;
}
while(temp!=0xf0)
{ temp=P3;
temp=temp&0xf0;
}
display(key);
}
}
P3=0xfb;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{ delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{ case 0xeb:key=8;break;
case 0xdb:key=9;break;
case 0x7b:key=11;break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
display(key);
}
}
P3=0xf7;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{ delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{ case 0xe7:key=12;break;
case 0xd7:key=13;break;
case 0xb7:key=14;break;
case 0x77:key=15;break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
display(key);
}
}
}
void main()
{
P0=0;
P0=0xc0;
while(1)
{ xxcan(); }
}
五、电路图
六、实验报告要求:
1、要求写出实验目的和要求;
2、要求写出实验基本原理;
3、写出实验程序并画出硬件电路图(可以复制打印Proteus图形并粘贴到报告上);
4、要求对实验结果进行简单分析,写出有关建议和心得体会。

相关文档
最新文档