您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 市场营销 > 一种矩阵键盘的定位的方法(编码方式)
图1是本发明方法的键盘扫描定位原理框图,图2是说明本发明方法的一个实施例的电路图,所述方法通过嵌入式设备和键盘扫描定位程序来实现,所述的嵌入式设备包括键盘和微控制器,所述的键盘扫描定位程序在微控制器中运行。开始键盘初始化等待键盘扫描采样时间到键号处理采样读取现态键值键盘状态稳定?现态状态码转为前态状态码组合现态键值至现态状态码查状态码表获取状态号、键号当前键盘状态维持时间计时根据状态号和键盘状态维持时间确定键号是否图1图2中,键盘的4个按键以2×2的矩阵形式排列,所有的行线与列线都通过上拉电阻接至电源+VCC,并连接至微控制器的I/O接口。本实施例要求利用4个按键实现以下操作:操作0:键盘从有键按下恢复到没有任何键按下后,时间达到2min时,执行一次操作0;操作1:按键S1单键按下操作时,执行一次操作1;操作2:按键S2单键按下操作时,执行一次操作2;按键S2单键按下时间持续3s以上后,每隔0.1s执行一次操作2,直到S2释放(或者键盘状态发生其他改变);操作3:按键S3单键按下时间持续2s以上后,执行一次操作3;操作4:按键S3单键释放操作时,执行一次操作4;操作5:按键S4单键按下后,再按下按键S3的组合键操作,执行一次操作5。如图1所示的键盘进行初始化,主要是前后读入2次键值,分别作为前态键值与现态键值保存,组合成状态码,同时作为前态状态码和现态状态码保存。如图1所示的等待键盘扫描时间到,等待时间周期T为10~50ms之间的一个固定值,本实施例选择等待时间为20ms,微控制器采用周期扫描的方式对键盘的当前状态进行读取采样。如图1所示的采样读取现态键值,本实施例中,图2所示键盘的键值为4位二进制码。例如,没有键按下的键值是1111,S1按下的键值是0101,S1、S2同时按下的键值是0100。采样读取键值的方法为反转法。首先在所有行线输出低电平,采样读取列线状态作为键值的高2位;再在所有列线输出低电平,采样读取行线状态作为键值的低2位;组合键值的高2位和低2位,得到4位键值。在采样读取现态键值前,将上一次采样读取的键值保存为前态键值。如图1所示的键盘状态是否稳定判断,用于确定键盘是否处于稳定状态,如果前后两次键盘采样的键值相同,即现态键值等于前态键值,键盘处于稳定状态,进入下一步骤;如果前后两次键盘采样的键值不同,现态键值不等于前态键值,则返回等待下一次键盘扫描时间到。由于键盘扫描周期在10~50ms之间,当前后两次键盘采样键值相同时,有效地避开了键盘按键抖动的影响。如图1所示的将现态状态码转为前态状态码,合并现态键值组成现态状态码,用于确定键盘状态或者是键盘操作。进入该步骤后,现态键值与前态键值相等,反映的是稳定的键盘状态。状态码由进入该步骤后前、后2次稳定的键值组合而成,前一次稳定的键值在前,后1次稳定的键值在后。例如,本实施例中,没有键按下的状态码是11111111,S1键单键按下操作的状态码是11110101;S1键单键按下维持的状态码是01010101;S1键单键释放操作的状态码是01011111;先按下S2后,再按下S1,S1按下操作的组合状态码是01100100。合并现态键值组成现态状态码的方法是:现态状态码存放在现态状态码寄存器中,先将现态状态码寄存器中的低半部分内容移至高半部分,然后将现态键值放入至现态状态码寄存器的低半部分。在合并现态键值组成现态状态码之前,将上一次合并键值组成的状态码保存为前态状态码。如图1所示的当前键盘状态维持时间计时,计时的目的是方便处理与键盘状态维持时间相关的键盘操作。实施例中计时的具体方法是:利用计数器k对扫描周期20ms进行计数,现态状态码与前态状态码不相等,令k=1;相等则k加1;为了防止计数器溢出,在k加1后等于设定的上限值MAX时,令k等于设定的下限值MIN。所述的下限值MIN要大于键盘操作要求的最大计时时间,在本实施例中,键盘操作最大计时时间是2min,对应的计数器k值是6000,下限值MIN取10000,上限值MAX取12000。如图1所示的查状态码表获取状态号、键号,目的是通过查状态码表的方式快速获取状态号与键号。在本实施例中,共设有6种有效的键盘操作,键号0至键号5与操作0至操作5一一对应。状态号共有7个,状态码表见表1。表1状态号01234567状态码11111111111101011111011001100110100110011001111110101000其他键号0122345255表1中的状态码中,有有效状态码,也有无效状态码,前面7个有效状态码对应的是有效键盘操作,类型有单键操作状态码,有组合键操作状态码,也有键盘处于维持状态的状态码,状态码表中所有的有效状态码都有一个状态号,且都与其相应的操作键号对应。其他的状态码都是无效状态码,都对应状态号7,且都为无效键号255。所述的查状态码表,只在所述状态码发生改变,即k=1时进行查询,在k>1的维持状态下,不进行查询。查表时,分别对现态状态码和前态状态码进行查询,并保存查询结果。如果现态状态码与表1的某个有效状态码相符合,则记录与其对应的现态状态号和现态键号;如果现态状态码与表1的所有有效状态码都不相同,则现态状态号是7,现态键号是无效键号255。如果前态状态码与表1的某个有效状态码相符合,则记录与其对应的前态状态号;如果前态状态码与表1的所有有效状态码都不相同,则前态状态号是7。如图1所示的根据状态号和键盘状态维持时间确定键号,目的是确定键号是否有效,有效键号为根据现态状态码查状态码表获取的键号。在本实施例中,满足下面条件时,键号有效且等于现态键号:现态状态号0,并且k等于6000(时间持续2min),或者是现态状态号1,或者是现态状态号2,或者是现态状态号3,并且前态状态号是2,并且k大于150,并且k模5等于0(时间持续3s以上每隔0.1s),或者是现态状态号4,并且前态状态号是0,并且k等于100(时间持续2s),或者是现态状态号5,或者是现态状态号6。所述条件中,状态号1、状态号2、状态号5、状态号6对应的键盘操作是按键按下或者是按键释放操作,无需加时间条件即有效;其他操作是键盘状态维持一段时间到后再进行的操作,与键盘状态维持时间相关,必须增加相应的时间条件一起判断是否有效,确定相应的键盘状态操作有效的时间点。不满足所述的键号有效的条件时,键号设置为无效键号255。.如图1所示的键号处理,如果是有效键号,进行相应处理后返回等待键盘扫描时间到,其中,相应处理包括直接进行与键号相应的键盘操作处理,或者是将有效键号排入队列等待应用程序读取;如果是无效键号,则直接返回等待键盘扫描时间到。本发明方法可以用于M×N矩阵键盘。此时,键盘的键值为M+N位二进制码,状态码为2×(M+N)位二进制码。所述的发明方法中,将对单键操作、组合键操作、键盘维持状态操作的扫描定位,转换成同一二进制长度的状态码,采用查表与时间条件相结合的方式进行统一处理,单键操作、组合键操作、键盘维持状态操作仅体现在状态码的不同上,扫描定位方法完全相同,可以一并处理;如果需要增减按键操作功能或者是调整按键操作功能,不需要修改键盘扫描程序结构,只需增减状态码表的大小或者是调整状态码表中与状态码对应的键号即可。S1P1.1R2R1+VCCS2S3S4R4R3P1.0P1.2P1.3微控制器图2附程序:(1)key.c:#includereg52.h#includekeyboard.h#definelineP1ucharread_key(void){ucharvalue;line=0xf0;value=line;line=0x0f;value&=0xf0;value|=(line&0x0f);returnvalue;}uintread_status(void){staticuinti=0;ucharex_value,cur_value,ex_status;staticucharcur_status=0xff;ex_value=read_key();cur_value=read_key();while(ex_value!=cur_value){ex_value=cur_value;cur_value=read_key();}ex_status=cur_status;cur_status=cur_value;if(cur_status==ex_status){i++;if(i350){i-=30;return(ex_status*256+cur_status);}elsereturn0xffff;}else{i=0;return(ex_status*256+cur_status);}}(2)main.c:#includereg51.h#includeintrins.h#includestdio.h#includekeyboard.h#defineucharunsignedchar#defineuintunsignedint#defineLCD_dataP0#definedelayNOP();{_nop_();_nop_();_nop_();_nop_();};sbitLCD_RS=P2^6;sbitLCD_RW=P2^5;sbitLCD_EN=P2^7;sbitLCD_PSB=P3^2;sbitLCD_RST=P3^7;voiddelay(intms){while(ms--){uchari;for(i=0;i150;i++){_nop_();_nop_();_nop_();_nop_();}}}voiddelay1(intms){while(ms--){uchary;for(y=0;y100;y++);}}bitlcd_busy(){bitresult;LCD_RS=0;LCD_RW=1;LCD_EN=1;delayNOP();result=(bit)(P0&0x80);LCD_EN=0;return(result);}voidlcd_wcmd(ucharcmd){while(lcd_busy());LCD_RS=0;LCD_RW=0;LCD_EN=0;_nop_();_nop_();P0=cmd;delayNOP();LCD_EN=1;delayNOP();LCD_EN=0;}voiddisp_str(char*p){while(*p!='\0'){if(*p0x80){lcd_wdat(*p);p++;lcd_wdat(*p);p++;}}}voidlcd_init(){LCD_PSB=1;//²¢¿Ú·½Ê½LCD_RST=0;//Òº¾§¸´Î»delay(3);LCD_RST=1;delay(3);lcd_wcmd(0x34);//À©³äÖ¸Áî²Ù×÷delay(5);lcd_wcmd(0x30);//»ù±¾Ö¸Áî²Ù×÷delay(5);lcd_wcmd(0x0C);//ÏÔʾ¿ª£¬¹Ø¹â±êdelay(5);lcd_wcmd(0x01);//Çå³ýLCDµÄÏÔʾÄÚÈÝdelay(5);}voidlcd_pos(ucharX,ucharY){ucharpos;if(X==1){X=0x80;}elseif(X==2){X=0x90;}elseif(X==3){X=0x88;}elseif(X==4){X=0x98;}pos=X+Y;lcd_wcmd(pos);}voidmain(){ucharabc[5];uintnum=88;delay(100);lcd_init();lcd_pos(1,0);disp_str(数值:);while(1){sprintf(abc,%5hu,num);lcd_pos(1,3);disp_str(abc);switch(read_status()){case0x7777:num+=11;break;case0x77ff:--num;break;case0xdbdb:--num;break;case0xffee:++num;break;case0x
本文标题:一种矩阵键盘的定位的方法(编码方式)
链接地址:https://www.777doc.com/doc-2825968 .html