1、键盘接口第二十六课矩阵式键盘接口技术及编程作者:佚名 来源:不详 录入:Admin 更新时间:2008-7-27 16:14:08 点击数:2 【字体: 】1、矩阵式键盘的结构与工作原理在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,如图1所示。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是
2、合理的。矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,上图中,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。具体的识别及编程方法如下所述。2、矩阵式键盘的按键识别方法 确定矩阵式键盘上何键被按下介绍一种“行扫描法”。行扫描法 行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下。1、判断键盘中有无键按下 将全部行线Y0-Y3置低电
3、平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。 2、判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。 下面给出一个具体的例子:图仍如上所示。8031单片机的P1口用作键盘I/O口,键盘的列线接到P1口的低4位,键盘的行线接到P1口的高4位。列线P1.0-P1.
4、3分别接有4个上拉电阻到正电源+5V,并把列线P1.0-P1.3设置为输入线,行线P1.4-P.17设置为输出线。4根行线和4根列线形成16个相交点。1、检测当前是否有键被按下。检测的方法是P1.4-P1.7输出全“0”,读取P1.0-P1.3的状态,若P1.0-P1.3为全“1”,则无键闭合,否则有键闭合。 2、去除键抖动。当检测到有键按下后,延时一段时间再做下一步的检测判断。 3、若有键被按下,应识别出是哪一个键闭合。方法是对键盘的行线进行扫描。P1.4-P1.7按下述4种组合依次输出: P1.7 1 1 1 0P1.6 1 1 0 1P1.5 1 0 1 1P1.4 0 1 1 1在每组
5、行输出时读取P1.0-P1.3,若全为“1”,则表示为“0”这一行没有键闭合,否则有键闭合。由此得到闭合键的行值和列值,然后可采用计算法或查表法将闭合键的行值和列值转换成所定义的键值4、为了保证键每闭合一次CPU仅作一次处理,必须却除键释放时的抖动。 键盘扫描程序:从以上分析得到键盘扫描程序的流程图如图2所示。程序如下SCAN: MOV P1,#0FHMOV A,P1ANL A,#0FHCJNE A,#0FH,NEXT1SJMP NEXT3NEXT1: ACALL D20MSMOV A,#0EFHNEXT2: MOV R1,AMOV P1,AMOV A,P1ANL A,#0FHCJNE A,#
6、0FH,KCODE;MOV A,R1SETB CRLC AJC NEXT2NEXT3: MOV R0,#00H RETKCODE: MOV B,#0FBHNEXT4: RRC AINC BJC NEXT4MOV A,R1SWAP ANEXT5: RRC AINC BINC BINC BINC BJC NEXT5NEXT6: MOV A,P1ANL A,#0FHCJNE A,#0FH,NEXT6MOV R0,#0FFHRET 键盘处理程序就作这么一个简单的介绍,实际上,键盘、显示处理是很复杂的,它往往占到一个应用程序的大部份代码,可见其重要性,但说到,这种复杂并不来自于单片机的本身,而是来自于操
7、作者的习惯等等问题,因此,在编写键盘处理程序之前,最好先把它从逻辑上理清,然后用适当的算法表示出来,最后再去写代码,这样,才能快速有效地写好代码。到本课为止,本站教程暂告一个段落!感谢大家的关心和支持!文件keyboard.h: /* 按键扫描程序工作原理说明: 按键扫描采取行线扫描输出高电平列线扫描接收的方式进行工作 首先在一根行线上输出一个高电平,然后列线扫描接收,如果其 中有按键按下则按键所在列线上接收到高电平信号否则为低,从 而根据接收到高电平时行列编号可确定按键编号。 */ #ifndef_KEYBOARD_H_ #define_KEYBOARD_H_ #include #inclu
8、dedefine.h #defineKEYSUM9 /按键数量 #defineHANGSUM3 /按键行数 #defineLIESUM3 /按键列数 #defineHANGSTART0 /按键行起始端口号 #defineLIEEND6 /按键列末位端口号 #defineKEYOUTPORTB /按键扫描高电平输出端口 #defineKEYINPINB /按键扫描输入端口 structkey ucharkeynum;/按键编号 ucharkeyconter;/按键灵敏度 ucharkeyburstmode;/按键触发方式0为延时电平触发1为按下触发2为抬起触发 ;/按键键值缓冲区 externv
9、olatileucharnowkeynum; /当前按键编号 无按键按下时为0 /*! *brief按键扫描程序 * *读入按键键值并写入全局变量nowkeynum * *return按键键值 */ ucharkeyscan(void); #endif * 文件keyboard.c: #includekeyboard.h /*按键记录电平计数缓冲区 每次扫描有按键按下记录缓冲区加1,直到超过按键灵敏度值。如无按键按下则清零。 */ ucharkeytmpKEYSUM+1= 0,0,0,0,0,0,0,0,0,0 ; /*按键记录缓冲区 当使用沿触发方式时记录按键状态 */ ucharkeytm
10、pnowKEYSUM+1= 0,0,0,0,0,0,0,0,0,0 ; /*按键记录历史缓冲区 当使用沿触发方式时记录上一次按键状态 */ ucharkeytmpoldKEYSUM+1= 0,0,0,0,0,0,0,0,0,0 ; /*按键声明区 定义各个按键属性 */ conststructkeykeyunitKEYSUM+1= 0,1,0,/ 1,2,1,/ 2,5,0,/ 3,5,0,/ 4,5,0,/ 5,5,0,/ 6,5,0,/ 7,5,0,/ 8,5,0,/ 9,5,0,/ ; ucharkeyscan(void) ucharloop1=0;/行扫描循环控制 ucharloop2
11、=0;/列扫描循环控制 ucharkeynumtmp=0;/按键编号缓存 ucharkeyloopmasklie=0;/列扫描掩码 /列扫描掩码设定 keyloopmasklie|=(1LIEEND); KEYOUT=0x00; for(loop1=0;loop1HANGSUM;loop1+) /置行线 KEYOUT|=(1(loop1+HANGSTART); for(loop2=0;loop2=keyunitkeynumtmp.keyconter) nowkeynum=keynumtmp; /计数器计数保持最大值 keytmpkeynumtmp=keyunitkeynumtmp.keycon
12、ter; returnnowkeynum; /没有按键按下相应按键计数寄存器清零 else keytmpkeynumtmp=0; break; /按下触发 case1: /抬起触发 case2: /如果有键按下相应键值计数器加1 if(KEYIN&keyloopmasklie)!=0) keytmpkeynumtmp+; /没有按键按下相应按键计数寄存器清零 else keytmpkeynumtmp=0; /如果计数器计数超出灵敏度设定值按键键值赋高 if(keytmpkeynumtmp=keyunitkeynumtmp.keyconter) /置当前按键电平状态为高 keytmpnowkey
13、numtmp=HIGH; /计数器计数保持最大值 keytmpkeynumtmp=keyunitkeynumtmp.keyconter; /按下触发 if(keyunitkeynumtmp.keyburstmode=1) /上升沿 if(keytmpoldkeynumtmp=LOW&keytmpnowkeynumtmp=HIGH) nowkeynum=keynumtmp; keytmpoldkeynumtmp=keytmpnowkeynumtmp; returnnowkeynum; else /置当前按键电平状态为低 keytmpnowkeynumtmp=LOW; /抬起触发 if(keyun
14、itkeynumtmp.keyburstmode=2) /下降沿 if(keytmpoldkeynumtmp=HIGH&keytmpnowkeynumtmp=LOW) nowkeynum=keynumtmp; keytmpoldkeynumtmp=keytmpnowkeynumtmp; returnnowkeynum; /按键记录推移 keytmpoldkeynumtmp=keytmpnowkeynumtmp; break; keyloopmasklie=1; /列扫描掩码设定 keyloopmasklie=0; keyloopmasklie|=(1LIEEND); /复位行线到KL1 KEY
15、OUT=0x00; nowkeynum=0; returnnowkeynum; * 主程序中定义 volatileucharnowkeynum=0; /当前按键编号 无按键按下时为0 * 程序说明: 本程序适用于3*3矩阵键盘。输入,输出均使用PB口,也可以改为其他口,和其他行列数,更改 keyboard.h中的声明部分即可。 本按键扫描程序可选择电平触发或者沿触发方式,最后的按键键值存在变量nowkeynum中。 使用时在各位的原文件中包含上面的keyboard.h和keyboard.c文件并在主程序中定义 volatileucharnowkeynum=0; 然后就可以调用keyscan()
16、;读出键值了。 推荐使用定时器定时调用的方式来完成按键扫描操作。10.5 说明矩阵式键盘按键按下的识别原理 (2010/08/27 16:26)目录: 网商感悟 浏览字体:大中小第十章 MCS-51 与键盘、显示器的接口设计 2010年06月08日10.1 为什么要排除按键的机械抖动?打消按键的机械抖动的方式有哪多少种?原理是什么? 答: 为了确保CPU对一次按键动作只确认一次按键有效,所以必需清除抖动,修理装备。常采取软件来消除按键抖动,其基础思维是:在第一次检测到有键按下时,该键所对应的行线为低点平,很久以后才发现这个人早已经操纵了我们的喜怒哀乐,手机游戏,执行一段延时10ms的子程序后,
17、确认该行线电平是否仍为低点平,假如仍为低点平,则确以为该行确切有键按下。当按键松开时,行线的低电平变为高电平,履行一段延时10ms的子程序后,检测该行线为高电平,解释按键确实已经松开。 10.3 LED的静态显示方式与动态显示方式有何差别?各有什么优毛病? 答:详见书本P228-P230 10.5 阐明矩阵式键盘按键按下的辨认原理 答:详见书本P234 10.7 键盘有哪三种工作方法?它们各自的工作原理及特色是什么? 答:详见书本P236 -P237 10.9 依据图10-14的电路,编写在6个LED显示器上轮流显示“1,2,3,4,资料2 - 博文预览,手机游戏,5,6”的显示程序. MOV
18、 R2,#06H MOV R0,#79H MOV A,#01H LOOP: MOV RO,A INC A INC R0 DJNZ R2,LOOP 以下代码见P239接 DIR: MOV R9,#79H MOV R3,#01H 。 矩阵式键盘的按键识别方法日期:2010-09-16 来源:本站原创 作者:佚名 字体:大 中 小 (投递新闻) 在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,如图1所示。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,
19、而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。 矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,上图中,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。具体的识别及编程方法如下所述。 矩阵式键盘的按键识别方法 确定矩阵式键盘上何键被按下介绍一种“行扫描法”。
20、行扫描法 行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下。 判断键盘中有无键按下 将全部行线Y0-Y3置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。 判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。 下面给
21、出一个具体的例子: 8031单片机的P1口用作键盘I/O口,键盘的列线接到P1口的低4位,键盘的行线接到P1口的高4位。列线P1.0-P1.3分别接有4个上拉电阻到正电源+5V,并把列线P1.0-P1.3设置为输入线,行线P1.4-P.17设置为输出线。4根行线和4根列线形成16个相交点。 检测当前是否有键被按下。检测的方法是P1.4-P1.7输出全“0”,读取P1.0-P1.3的状态,若P1.0-P1.3为全“1”,则无键闭合,否则有键闭合。 去除键抖动。当检测到有键按下后,延时一段时间再做下一步的检测判断。 若有键被按下,应识别出是哪一个键闭合。方法是对键盘的行线进行扫描。P1.4-P1.
22、7按下述4种组合依次输出: P1.7 1 1 1 0 P1.6 1 1 0 1 P1.5 1 0 1 1 P1.4 0 1 1 1 实例程序: ORG 0000H AJMP MAIN ORG 0030H MAIN: MOV DPTR,#TAB ;将表头放入DPTR LCALL KEY ;调用键盘扫描程序 MOVC A,A+DPTR ;查表后将键值送入ACC MOV P0,A ;将Acc值送入P0口 CLR P2.1 ;开显示 LJMP MAIN ;返回反复循环显示 KEY: LCALL KS ;调用检测按键子程序 JNZ K1 ;有键按下继续 LCALL DELAY2 ;无键按调用延时去抖 A
23、JMP KEY ;返回继续检测按键 K1: LCALL DELAY2 LCALL DELAY2 ;有键按下延时去抖动 LCALL KS ;再调用检测按键程序 JNZ K2 ;确认有按下进行下一步 AJMP KEY ;无键按下返回继续检测 K2: MOV R2,#0EFH ;将扫描值送入R2暂存 MOV R4,#00H ;将第一列值送入R4暂存 K3: MOV P1,R2 ;将R2的值送入P1口 L6: JB P1.0,L1 ;P1.0等于1跳转到L1 MOV A,#00H ;将第一行值送入ACC AJMP LK ;跳转到键值处理程序 L1: JB P1.1,L2 ;P1.1等于1跳转到L2 MOV A,#04H ;将第二行的行值送入ACC AJMP LK ;跳转到键值理程序进行键值处理 L2: JB P1.2,L3 ;P1.2
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1