您的位置:控制工程论坛网论坛 » 自动化软件 » 按键程序的总结

xilinxue

xilinxue   |   当前状态:在线

总积分:16186  2024年可用积分:0

注册时间: 2008-06-26

最后登录时间: 2020-03-22

空间 发短消息加为好友

按键程序的总结

xilinxue  发表于 2008/11/7 17:44:15      1530 查看 2 回复  [上一主题]  [下一主题]

手机阅读

/*按键程序的总结
110xia 发表于 2007-11-9 21:24:00 按键程序的总结
        关于按键程序偶总结出以下几个关键点:
        1. 按键数值的抓取
        第一,在这个过程中一定要有去抖动处理的,可以使用硬件去抖动,一般在按键输入口外加电容就可以了;也可以使用软件处理去抖动,程序中使用延时再判断的办法,一般延时10ms就可以了。
        第二,根据实际情况,设计多个按键同时按下,或某个(某些)按键先按下不松开,是否响应其他按键按下。
        第三,根据实际情况,设计某些按键是否有长按功能。
        2. 按键数值的处理
        在这个过程中,根据实际情况,有些是需要按键按下就动作,还有些是需要按键松开就动作,大多数情况是要求按键按下就动作的。
       为了不丢掉
        例一,定时扫描按键,按键松开动作 软件处理抖动 4*4的键盘程序,定时10ms  调用 Matrix_Key_Detect() 这个函数,这是个普通的处理方法,在实际应用中,建议把它优化后在使用*/
// 矩阵键盘通用程序(引脚输入输出方向不切换)
//KEY_PINS 低4位为ROW(监听) 高4位为COL(输出,低电平)
// 7 6 5 4 3 2 1 0   
// Co4 Co3 Co2 Co1 Ro4 Ro3 Ro2 Ro1
 /* COL 4 3 2 1
 ROW 4
  3
  2
  1
*/
 
//Matrix_Key (row 行 col 列 从1开始计数)
#define KEY_PINS P0
sbit ROW1 = P0^0;
sbit ROW2 = P0^1;
sbit ROW3 = P0^2;
sbit ROW4 = P0^3;
sbit COL1 = P0^4;
sbit COL2 = P0^5;
sbit COL3 = P0^6;
sbit COL4 = P0^7;
 
unsigned char row="0",col=0;


//<返回其列号(col) 需要事先准备其行号掩码>
static unsigned char Matrix_Key_Scan_Col(const unsigned char rowbitmask)
{
 unsigned char i="0";
 unsigned char colmask;
 KEY_PINS = 0x0f;
 colmask=0x0f;
 while ( (KEY_PINS & rowbitmask)==0)
 {
  colmask = colmask<<1;
  KEY_PINS = colmask | 0x0f;
  i++;
 }
 return i;
}


//<检测是否有按键按下,并返回其行号(row)>
static unsigned char Matrix_Key_Scan_Row()
{
 KEY_PINS = 0x0f;
 
 if (ROW1 == 0)
 {
  return 1;
 }
 else if (ROW2 == 0)
 {
  return 2;
 }
 else if (ROW3 == 0)
 {
  return 3;
 }
 else if (ROW4 == 0)
 {
  return 4;
 }
 return 0;
}
unsigned char Matrix_Key_Detect() //行/列
{
 static unsigned char keep_time;
 static unsigned char keep_row;
 static unsigned char keep_col;
 static unsigned char state  = 0;
 unsigned char uScanReturn;
 switch (state)
 {
  case 0: //检测是否有按钮按下
   if (Matrix_Key_Scan_Row() != 0 )
   { //<初始化>
    keep_time = 0;
    keep_row = 0;
    keep_col = 0;
    state++;
   }
   break;
  case 1:
   uScanReturn = Matrix_Key_Scan_Row();
   if (uScanReturn != 0 ) //按键按下姿态
   {
    if (keep_time<250) keep_time++;
    if (keep_row == 0)
    {
     keep_row = uScanReturn;
    }
    if (keep_row != 0 && keep_col == 0)
    {
     keep_col = Matrix_Key_Scan_Col( 0x01<<(keep_row-1) );
    }
   }
   else     //按键松起姿态
   {
    if (keep_time>5) //检测到有效按键
    {
     keep_time = 0;
     state++;
    }
    else    //按键无效
    {
     state = 0;
    }
   }
   break;
  case 2:
   if (Matrix_Key_Scan_Row() == 0 )  //按键松起姿态(保持)
   {
    if (keep_time<250) keep_time++;
    if (keep_time>5) //检测到有效松起
    {
     /* 返回信息:检测到有效按键,并可以执行对应操作 */
     state = 0;
     row = keep_row;
     col = keep_col;
     return 1;
    }
   }
   else //按键被重新按下
   {
     keep_time=0; //重新计时
   }
   break;
 }
 return 0;
}


//例二 是将例一该善后的程序, 一个2*4的键盘, 当一个按键按下,不在响应其他按键盘。
//key 扫描
 unsigned char data key_io;
 unsigned char data keyflag;
 unsigned char data keyedge_old;
 
uchar Key_Det_col(uchar keycol){
 uchar keyrow;
 P0=(~keycol);
 _nop_();
 _nop_();
 keyrow=(~P0);
 return(keyrow);
}
/*----------------------------- Subroutine -------------------------------------
        Name: Key_Detect
    Function:
       Entry: key_io
        Exit: keyflag,keyedge_old,keyedge
     Caution:
-------------------------------------------------------------------------------*/
void Key_Detect(void){
 static unsigned char state="2";
 unsigned char keybuf;
 
 state++;
 if(state>2)
  state="0x00";
 if(state<2)
  keybuf="Key"_Det_col(state+1);
 switch (state){
  case 0:
   key_io&=0xf0; //first cow
   key_io|=(keybuf>>4);
  break;
 
  case 1:    //second cow
   key_io&=0x0f;
   keybuf&=0xf0;
   key_io|=keybuf;
  break;
 
  case 2:
   keybuf="keyflag"&key_io;
   if(keybuf==0){
    keyflag="key"_io;   
    keyedge_old=0x00;
   }
   else {
    keyedge|=(keybuf&(~keyedge_old));
    keyedge_old=keybuf;
   }
  break;
 }
}
 
//例三 根据需要当一个按键按下时,还需要响应其他按键盘,可以把 例二 改善一下,只需要改 void Key_Detect(void); 这个函数里面的内容:
/*----------------------------- Subroutine -------------------------------------
        Name: Key_Detect
    Function:
       Entry: key_io
        Exit: keyflag,keyedge_old,keyedge
     Caution:
-------------------------------------------------------------------------------*/
void Key_Detect(void){
 static unsigned char state="2";
 unsigned char keybuf;
 
 state++;
 if(state>2)
  state="0x00";
 if(state<2)
  keybuf="Key"_Det_col(state+1);
 switch (state){
  case 0:
   key_io&=0xf0; //first cow
   key_io|=(keybuf>>4);
  break;
 
  case 1:    //second cow
   key_io&=0x0f;
   keybuf&=0x70;
   key_io|=keybuf;
  break;
 
  case 2:
   keybuf="keyflag"&key_io;
  
   keyflag="key"_io;    
   keyedge|=(keybuf&(~keyedge_old));
   keyedge_old=keybuf;
  
  break;
 }
}
 

1楼 0 0 回复
  • xilinxue

    xilinxue   |   当前状态:在线

    总积分:16186  2024年可用积分:0

    注册时间: 2008-06-26

    最后登录时间: 2020-03-22

    空间 发短消息加为好友

    xilinxue   发表于 2008/11/4 18:58:13

      这个是以前我写的一个程序,写的很烦琐,不过挺适合初学的人,


    高手看了 希望不要见笑,把你们的意见提出来,我们大家一起讨论,谢谢了

    2楼 回复本楼

    引用 xilinxue 2008/11/4 18:58:13 发表于2楼的内容

总共 , 当前 /