矩阵按键的组合按键触发

/***12个按键,每一个按键都会让蜂鸣器发出“嘀”的一声,
 同时按下S1和S12会点亮一个LED灯,同时按下***/
#include "REG52.H"
#define const_voice_short 40
#define const_key_time 12
#define const_key_time_comb 14 //组合按键去抖动延时时间
void initial_myself();
void initial_peripheral();
void delay_long(unsigned int uiDelaylong);
void T0_time();
void key_service();
void key_scan();
 
/*
 任意两个组合按键不能处于同一行,否则触发性能大打折扣。
 做产品的时候,在硬件电路设计中,除了四路行输入要加上拉电阻外,
 四路列输出也应该串入一个470欧左右的限流电阻,否则当一行的两个
 按键同时按下时,很容易烧坏单片机的IO口。
*/
sbit key_sr1=P0^1; //第一行输入
sbit key_sr2=P0^2; //第二行输入
sbit key_sr3=P0^3; //第三行输入
sbit key_dr1=P0^4; //第一列输出
sbit key_dr2=P0^5; //第二列输出
sbit key_dr3=P0^6; //第三列输出
sbit key_dr4=P0^7; //第四列输出

sbit led_dr=P3^5; //LED灯
sbit beep_dr=P1^5;
unsigned char ucKeyStep=1; //按键扫描步骤变量
unsigned char ucKeySec=0; //被触发的按键编号
unsigned int uiKeyTimeCnt[12]=0; //12个按键去抖动延时计数器
unsigned char ucKeyLock[12]=0; //12个按键触发后自锁的变量标志

unsigned int uiKeyTimeCnt_01_12=0; //S1和S12组合按键去抖动延时计数器
unsigned char ucKeyLock_01_12=0; //S1和S12组合按键触发后自锁的变量标志

unsigned int uiKeyTimeCnt_04_09=0; //S4和S9组合按键去抖动延时计数器
unsigned char ucKeyLock_04_09=0; //Ss和S9组合按键触发后自锁的变量标志

unsigned int uiListRecord=1; //记录当前扫描到了第几列
unsigned int uiVoiceCnt=0; //蜂鸣器鸣叫的时间计数器
unsigned int uiKeyStatus=0xfff; //此变量每一位代表一个按键的状态,共12个按键。1代表没有被按下,0代表被按下

void main()
{
 initial_myself();
 delay_long(100);
 initial_peripheral();
 while(1)
 {
  key_service();
 }
}
void key_scan()  //按键扫描函数,放到定时中断里
{
 /*
  第一步:先把16个按键翻译成独立按键。
  第二步:再按独立按键的去抖动方式进行按键识别
  第三步:参考独立按键的方式,来实现组合按键
 */
 switch(ucKeyStep)
 {
  case 1: //把12个按键的状态快速记录在uiKeyStatus变量的每一位中,相当于把矩阵键盘翻译成独立按键
   for(uiListRecord=1;uiListRecord<5;uiListRecord++)
   {
    if(uiListRecord==1) //第一列低电平
    {
  key_dr1=0;
  key_dr2=1;
  key_dr3=1;
  key_dr4=1;
   //如果是薄膜按键或者走线比较长的按键,此处应该加几个空延时,等待列输出信号稳定再判断输入的状态
   if(key_sr1==0)
    uiKeyStatus=uiKeyStatus&0xffe; //S1被按下
   
   if(key_sr2==0)
    uiKeyStatus=uiKeyStatus&0xfef; //S5被按下
   
   if(key_sr3==0)
    uiKeyStatus=uiKeyStatus&0xeff; //S9被按下  
    }
   
    else if(uiListRecord==2) //第二列低电平
    {
  key_dr1=1;
  key_dr2=0;
  key_dr3=1;
  key_dr4=1;
   //如果是薄膜按键或者走线比较长的按键,此处应该加几个空延时,等待列输出信号稳定再判断输入的状态
   if(key_sr1==0)
    uiKeyStatus=uiKeyStatus&0xffd; //S2被按下
   
   if(key_sr2==0)
    uiKeyStatus=uiKeyStatus&0xfdf; //S6被按下
   
   if(key_sr3==0)
    uiKeyStatus=uiKeyStatus&0xdff; //S10被按下  
    }
   
    else if(uiListRecord==3) //第三列低电平
    {
  key_dr1=1;
  key_dr2=1;
  key_dr3=0;
  key_dr4=1;
   //如果是薄膜按键或者走线比较长的按键,此处应该加几个空延时,等待列输出信号稳定再判断输入的状态
   if(key_sr1==0)
    uiKeyStatus=uiKeyStatus&0xffb; //S3被按下
   
   if(key_sr2==0)
    uiKeyStatus=uiKeyStatus&0xfbf; //S7被按下
   
   if(key_sr3==0)
    uiKeyStatus=uiKeyStatus&0xbff; //S11被按下  
    }
   
    else  //第四列低电平
    {
  key_dr1=1;
  key_dr2=1;
  key_dr3=1;
  key_dr4=0;
   //如果是薄膜按键或者走线比较长的按键,此处应该加几个空延时,等待列输出信号稳定再判断输入的状态
   if(key_sr1==0)
    uiKeyStatus=uiKeyStatus&0xff7; //S4被按下
   
   if(key_sr2==0)
    uiKeyStatus=uiKeyStatus&0xf7f; //S8被按下
   
   if(key_sr3==0)
    uiKeyStatus=uiKeyStatus&0x7ff; //S12被按下  
    }
   }
  ucKeyStep=2; //切换到下一运行步骤
  break;
  
 case 2:  //像独立按键一样进行去抖动和翻译。
  if((uiKeyStatus&0x001)==0x001) //说明1号按键没有被按下
  {
   uiKeyTimeCnt[0]=0;
   ucKeyLock[0]=0;
  }
  else if(ucKeyLock[0]==0)
  {
   uiKeyTimeCnt[0]++;
   if(uiKeyTimeCnt[0]>const_key_time)
   {
    uiKeyTimeCnt[0]=0;
    ucKeyLock[0]=1; //自锁按键,防止不断触发
    ucKeySec=1;  //触发号按键
   }
  }
  
  if((uiKeyStatus&0x002)==0x002) //说明2号按键没有被按下
  {
   uiKeyTimeCnt[1]=0;
   ucKeyLock[1]=0;
  }
  else if(ucKeyLock[1]==0)
  {
   uiKeyTimeCnt[1]++;
   if(uiKeyTimeCnt[1]>const_key_time)
   {
    uiKeyTimeCnt[1]=0;
    ucKeyLock[1]=1; //自锁按键,防止不断触发
    ucKeySec=2;  //触发2号按键
   }
  }
  
  if((uiKeyStatus&0x004)==0x004) //说明3号按键没有被按下
  {
   uiKeyTimeCnt[2]=0;
   ucKeyLock[2]=0;
  }
  else if(ucKeyLock[2]==0)
  {
   uiKeyTimeCnt[2]++;
   if(uiKeyTimeCnt[2]>const_key_time)
   {
    uiKeyTimeCnt[2]=0;
    ucKeyLock[2]=1; //自锁按键,防止不断触发
    ucKeySec=3;  //触发3号按键
   }
  }
  
  if((uiKeyStatus&0x008)==0x00) //说明4号按键没有被按下
  {
   uiKeyTimeCnt[3]=0;
   ucKeyLock[3]=0;
  }
  else if(ucKeyLock[3]==0)
  {
   uiKeyTimeCnt[3]++;
   if(uiKeyTimeCnt[3]>const_key_time)
   {
    uiKeyTimeCnt[3]=0;
    ucKeyLock[3]=1; //自锁按键,防止不断触发
    ucKeySec=4;  //触发4号按键
   }
  }
  
  if((uiKeyStatus&0x010)==0x010) //说明5号按键没有被按下
  {
   uiKeyTimeCnt[4]=0;
   ucKeyLock[4]=0;
  }
  else if(ucKeyLock[4]==0)
  {
   uiKeyTimeCnt[4]++;
   if(uiKeyTimeCnt[4]>const_key_time)
   {
    uiKeyTimeCnt[4]=0;
    ucKeyLock[4]=1; //自锁按键,防止不断触发
    ucKeySec=5;  //触发5号按键
   }
  }
  
  if((uiKeyStatus&0x020)==0x020) //说明6号按键没有被按下
  {
   uiKeyTimeCnt[5]=0;
   ucKeyLock[5]=0;
  }
  else if(ucKeyLock[5]==0)
  {
   uiKeyTimeCnt[5]++;
   if(uiKeyTimeCnt[5]>const_key_time)
   {
    uiKeyTimeCnt[5]=0;
    ucKeyLock[5]=1; //自锁按键,防止不断触发
    ucKeySec=6;  //触发6号按键
   }
  }
  
  if((uiKeyStatus&0x040)==0x040) //说明7号按键没有被按下
  {
   uiKeyTimeCnt[6]=0;
   ucKeyLock[6]=0;
  }
  else if(ucKeyLock[6]==0)
  {
   uiKeyTimeCnt[6]++;
   if(uiKeyTimeCnt[6]>const_key_time)
   {
    uiKeyTimeCnt[6]=0;
    ucKeyLock[6]=1; //自锁按键,防止不断触发
    ucKeySec=7;  //触发7号按键
   }
  }
  
  if((uiKeyStatus&0x080)==0x080) //说明8号按键没有被按下
  {
   uiKeyTimeCnt[7]=0;
   ucKeyLock[7]=0;
  }
  else if(ucKeyLock[7]==0)
  {
   uiKeyTimeCnt[7]++;
   if(uiKeyTimeCnt[7]>const_key_time)
   {
    uiKeyTimeCnt[7]=0;
    ucKeyLock[7]=1; //自锁按键,防止不断触发
    ucKeySec=8;  //触发8号按键
   }
  }
  
  if((uiKeyStatus&0x100)==0x100) //说明9号按键没有被按下
  {
   uiKeyTimeCnt[8]=0;
   ucKeyLock[8]=0;
  }
  else if(ucKeyLock[8]==0)
  {
   uiKeyTimeCnt[8]++;
   if(uiKeyTimeCnt[8]>const_key_time)
   {
    uiKeyTimeCnt[8]=0;
    ucKeyLock[8]=1; //自锁按键,防止不断触发
    ucKeySec=9;  //触发9号按键
   }
  }
  
  if((uiKeyStatus&0x200)==0x200) //说明10号按键没有被按下
  {
   uiKeyTimeCnt[9]=0;
   ucKeyLock[9]=0;
  }
  else if(ucKeyLock[9]==0)
  {
   uiKeyTimeCnt[9]++;
   if(uiKeyTimeCnt[9]>const_key_time)
   {
    uiKeyTimeCnt[9]=0;
    ucKeyLock[9]=1; //自锁按键,防止不断触发
    ucKeySec=10;  //触发10号按键
   }
  }
  
  if((uiKeyStatus&0x400)==0x400) //说明11号按键没有被按下
  {
   uiKeyTimeCnt[10]=0;
   ucKeyLock[10]=0;
  }
  else if(ucKeyLock[10]==0)
  {
   uiKeyTimeCnt[10]++;
   if(uiKeyTimeCnt[10]>const_key_time)
   {
    uiKeyTimeCnt[10]=0;
    ucKeyLock[10]=1; //自锁按键,防止不断触发
    ucKeySec=11;  //触发11号按键
   }
  }
  
  if((uiKeyStatus&0x800)==0x800) //说明12号按键没有被按下
  {
   uiKeyTimeCnt[11]=0;
   ucKeyLock[11]=0;
  }
  else if(ucKeyLock[11]==0)
  {
   uiKeyTimeCnt[11]++;
   if(uiKeyTimeCnt[11]>const_key_time)
   {
    uiKeyTimeCnt[11]=0;
    ucKeyLock[11]=1; //自锁按键,防止不断触发
    ucKeySec=12;  //触发12号按键
   }
  }
  
  
  if((uiKeyStatus&0x801)==0x000) //S1和S12的组合按键被按下
  {
   if(ucKeyLock_01_12==0)
   {
    uiKeyTimeCnt_01_12++;
    if(uiKeyTimeCnt_01_12>const_key_time_comb)
    {
     uiKeyTimeCnt_01_12=0;
     ucKeyLock_01_12=1;
     ucKeySec=13; //触发13号组合按键
    }
   }
  }
  
  else
  {
   uiKeyTimeCnt_01_12=0;
   ucKeyLock_01_12=0;
  }
  
  if((uiKeyStatus&0x108)==0x000) //S4和S9的组合按键被按下
  {
   if(ucKeyLock_04_09==0)
   {
    uiKeyTimeCnt_04_09++;
    if(uiKeyTimeCnt_04_09>const_key_time_comb)
    {
     uiKeyTimeCnt_04_09=0;
     ucKeyLock_04_09=1;
     ucKeySec=14; //触发14号组合按键
    }
   }
  }
  
  else
  {
   uiKeyTimeCnt_04_09=0;
   ucKeyLock_04_09=0;
  }
  
  
  uiKeyStatus=0xfff; //及时恢复状态,方便下一次扫描
  ucKeyStep=1; //返回第一步
  break;
 }
}

void key_service() //第三区,按键服务应用程序
{
 switch(ucKeySec)
 {
  case 1:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;
  
  case 2:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;
  case 3:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;
  case 4:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;
  case 5:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;
  case 6:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;
  case 7:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;
  case 8:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;
  case 9:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;
  case 10:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;
  
  case 11:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;
  case 12:
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;

case 13:
   led_dr=0; //LED亮
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;

case 14:
   led_dr=1; //LED灭
   uiVoiceCnt=const_voice_short;
   ucKeySec=0;
   break;   
  
 }
}
void T0_time() interrupt 1
{
 TF0=0;
 TR0=0;
 
 key_scan();
 
 if(uiVoiceCnt!=0)
 {
  uiVoiceCnt--;
  beep_dr=0;
 }
 else
 {
  ;
  beep_dr=1;
 }
 
 TH0=0xf8;
 TL0=0x2f;
 TR0=1;
}
void delay_long(unsigned int uiDelayLong)
{
 unsigned int i;
 unsigned int j;
 for(i=0;i<uiDelayLong;i++)
  for(j=0;j<500;j++)
   ;
}
void initial_myself()
{
 beep_dr=1;
 TMOD=0x01;
 TH0=0xf8;
 TL0=0x2f;
}
void initial_peripheral()
{
 EA=1;
 ET0=1;
 TR0=1;
}

原文地址:https://www.cnblogs.com/TheFly/p/12003797.html

时间: 2024-10-28 11:37:43

矩阵按键的组合按键触发的相关文章

两个独立按键的组合按键触发------基于上一例略作改动

#include "REG52.H"#define const_voice_short 40/* 调整抖动时间阈值的大小,,可以更改按键的触发灵敏度 去抖动的时间本质上等于累计定时中断次数的时间*/#define const_key_time12 20  //按键去抖动延时的时间void initial_myself();void initial_peripheral();void delay_long(unsigned int uiDelayLong);void T0_time();

JS监听组合按键

有些时候,我们需要在网页上,增加一些快捷按键,方便用户使用一些常用的操作,比如:保存,撤销,复制.粘贴等等. 下面简单梳理一下思路: 我们所熟悉的按键有这么集中类型: 单独的按键操作,如:delete.up.down等 两位组合建,如:ctrl(cmd)+ 其他按键,alt+其他按键,shift+其他按键 三位组合键,如:ctrl(cmd)+ shift + 其他按键,Ctrl(cmd)+ alt + 其他按键 大概只有这么几种情况了,至少我没有见过其他的情况.如果确实存在的话,基本实现的原理也

Dom监听组合按键

有些时候,我们需要在网页上,增加一些快捷按键,方便用户使用一些常用的操作,比如:保存,撤销,复制.粘贴等等. 下面简单梳理一下思路: 我们所熟悉的按键有这么集中类型: 单独的按键操作,如:delete.up.down等 两位组合建,如:ctrl(cmd)+ 其他按键,alt+其他按键,shift+其他按键 三位组合键,如:ctrl(cmd)+ shift + 其他按键,Ctrl(cmd)+ alt + 其他按键 大概只有这么几种情况了,至少我没有见过其他的情况.如果确实存在的话,基本实现的原理也

WinForm中快捷键与组合按键的设置方法

新建一个空白窗体 每个窗体都有这样3个事件:KeyDown.KeyPress.KeyUp,KeyDown和KeyPress都是按键按下事件,但KeyDown用的是KeyCode跟键盘各个按键相对应,它对应Keys枚举,用起来比较方便:而KeyPress用的是KeyChar,这个就要找ASC II编码了,不方便.KeyUp是按键弹起事件,不常用,因此我们使用KeyDown事件来设置窗体的快捷键,双击该事件后的空白生成代码,首先我们设置单个按键,让它按下F11最大化,再次按下还原,在事件中加入如下代

bash默认组合按键

组合按键 运行结果 Ctrl + C 终止目前的命令 Ctrl + D 输入结束 (EOF),例如邮件结束的时候: Ctrl + M 就是 Enter 啦! Ctrl + S 暂停屏幕的输出 Ctrl + Q 恢复屏幕的输出 Ctrl + U 在提示字符下,将整列命令删除 Ctrl + Z 『暂停』目前的命令 内容来源:http://cn.linux.vbird.org/linux_basic/0320bash_4.php (完) 原文地址:https://www.cnblogs.com/lis

JS组合按键事件监听插件

[1].[代码] [JavaScript]代码 跳至 [1] ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 7

c#组合按键响应

private void textbox_KeyDown(object sender, KeyEventArgs e) { // 如果按下组合键CTRL+Enter if (e.KeyData == (Keys.Control | Keys.Enter)) { ... } } private void textbox_KeyDown(object sender, KeyEventArgs e) { // 如果按下组合键CTRL+R if (e.Control && e.KeyCode ==

按键-长按只触发一次次

PS:没有做抖动的处理 bit scanKey(){ bit res = 0; if(K1 == 0 && pressStatus == 0){ res = 1; } pressStatus = K1==0?1:0; return res; } .

JS监听键盘的组合按键

Mark 一下: $(document).keydown(function (e) { console.log(e); var keyCode = e.keyCode || e.which || e.charCode; var shiftKey = e.shiftKey; if (shiftKey && keyCode == 68) {//shift+D var leftbtnDisplay = $("#Leftbtn").css('display'); if (lef