|  | 
 
| 通常我们在写按键程序的时候例如下面的例子: 
 
 都是这样进行识别按键的,但是这样的程序就会出现一个问题,就是按键在按下的时候程序会死在while(KEY1==0);//等待按键松开程序中,这样的话就造成一个问题,程序的执行效率很低很低复制代码   while(1)
        {
                        if(KEY1==0)
                {
                        while(KEY1==0);//等待按键松开
                        ............
                }
                        LED_1=~LED_1;
        }
有什么什么方法可以解决一下呢?
 当然是有的,例如下面就给出了一个解决方法
 同样的,我也来做一个LED灯闪烁的程序和上面一样例如
 
 KEY_Scan();按键扫描程序,这个程序我们测试就放在这个循环程序里,当然到时候可以做一个20ms的定时器,把这个程序放入定时器中就可以了复制代码   while(1)
        {
                        KEY_Scan();//按键扫描程序
                        for(q=0;q<KEY_number;q++)
                {
                        KEY=Get_KEY_state(q);//获取按键状态
                        if(KEY==Press)
                        {
                        printf("按键短按:%d\r\n",q);
                        }
                        
                        if(KEY==LongPress)
                        {
                        printf("按键长按:%d\r\n",q);
                        }
                }        
                        delay_ms(20);
                        if(w++>=10)
                {
                        w=0;
                        LED_1=~LED_1;
                }
        }
 KEY=Get_KEY_state(q);//获取按键状态    通过这个程序可以获取按键是否被按下
 
 Press   :按键被短按了一下
 
 LongPress    :按键被长按了一下
 
 
 
 接下来是我们的按键扫描程序
 
 
 
 #define KEY_number                                10                        //按键个数
 #define KEY_PressDown_state                0                        //按键按下状态
 #define KEY_LongPress_Time                100                //超过时间判断为长按 ,按键按下的实际时间计算为=按键扫描周期时间     X    KEY_LongPress_Time
 
 
 u16 KEY_Time[KEY_number];//保存按键时间
 bool KEY_Pin_state[KEY_number];//保存按键状态
 
 
 
 
 typedef enum//定义按键的状态
 {
 Release=0,        //释放,也就是没有按键按下
 Press=1,               //正常按下
 LongPress=2,                //长按
 NoRelease=3,                //按键按下但是还没有被释放
 
 }_KEY_state;
 
 
 
 复制代码//请将这个程序放入定时器或者是一个单独的任务中调用时间一般为20ms
void KEY_Scan()
{
                        u8 q;
                        for(q=0;q<KEY_number;q++)
        {
                        KEY_Pin_state[q]=GPIO_ReadInputDataBit(KEY_GPIOX[q],KEY_GPIO_Pin[q]);//获取按键状态
                        if(KEY_Pin_state[q]==KEY_PressDown_state)
                {
                        if(KEY_Time[q]<=60000){KEY_Time[q]++;}//计时
                }
                        else
                {
                        KEY_Time[q]=0;//如果按键被释放了则就清空计时
                }
                        
        }
}
 下面是按键的识别程序
 
 通过上面改良的按键设备程序就可以实现按键的:短按,长按并且是拒绝死等的。同时可以支持多个按键按下,在这个程序中就支持了10个按键复制代码//获取的按键状态
//key_id:按键的ID号,请与前面定义的端口对应
_KEY_state Get_KEY_state(u8 key_id)//获取按键状态
{
                        static _KEY_state mode[KEY_number];
                        static bool state[KEY_number];
                        if(KEY_Pin_state[key_id]==KEY_PressDown_state)
        {
                        state[key_id]=1;
                        if(KEY_Time[key_id]<KEY_LongPress_Time){mode[key_id]=Press;}
                        else{mode[key_id]=LongPress;}        
//                        printf("按键被按下了:%d-%d\r\n",key_id,mode[key_id]);
        }
                        else
        {
                        if(state[key_id]==1)
                {
                        state[key_id]=0;
//                        printf("按键被按下过:%d\r\n",mode);
                        return mode[key_id];
                }
                        else
                {
                        return Release;
                }
        }
//                        printf("按键处理为还未释放\r\n");
                        return NoRelease;
}
 
 
 
 
 
 
 | 
 
×本帖子中包含更多资源您需要 登录 才可以下载或查看,没有账号?立即注册 
  |