打印

矩阵键盘 按键弹起检测,求大神 纠结一天了

[复制链接]
4159|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wang12zhe|  楼主 | 2013-6-13 17:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
按键接在P0的8位和P20还有P45,

#include".\include\REG51xD2.H"
#include <intrins.h>
#include".\include\def.h"
#include".\include\timerapp.h"
#include".\include\LCMdriver.h"
#include".\include\common.h"
#include".\include\uart.h"
extern bit b_ScreenChangeAuto_EN;  //供LCD使用。
extern bit b_g_flag_lrnkeydn_first;
unsigned int keyscan(void)//键盘扫描函数,使用行列反转扫描法 比如:行为低电位,列为高四位
{
  unsigned int uiLow=0;
  unsigned int uiHigh=0;
  unsigned char uc_temp_P0;

  //行线5位写0  列线5位写1
/*  
  P0=0x1F;
  KEYIN9 =0;
  KEYIN10= 0;
*/  
  uiLow=P0&0x1F;   //取出低5位
     
//行线5位写1  列线5位保持
    KEYIN9=1;
    KEYIN10=1;
    P0=(uiLow|0xE0);

// =========读取按键值
    uiHigh|=(P0&0xE0);
    uiHigh|=((P4&0x20)<<4);   
    uiHigh|=((P2&0x1)<<8);

    return(uiHigh+uiLow);
}

unsigned int  Key_Down()
{
//unsigned char i;
unsigned int xdata ui_value=0;
unsigned char xdata uc_valueP0=0;
unsigned char xdata tempui_value;

bit b_Time_Out =0;   //定时时间到标志  1 时间到  0 时间未到
//_nop_(); _nop_();   _nop_();
//行线5位写0  列线5位写1
P0=0x1f;
KEYIN9 =0;
KEYIN10= 0;  
//=================    定时器延时去抖 处理   
if(P0!=0x1f)
  {
   if(b_g_flag_lrnkeydn_first)//如果是按键第1次被按下   当定时器计时时间没到的话按下按键不处理
     {
     app_timers[KEY_INPUT_TIMER].uc_flag_enabled=1;  //启动延时抖动定时器
     b_g_flag_lrnkeydn_first=0;   // 第一次按下按键标志
     app_timers[KEY_INPUT_TIMER].us_count=0; // 延时定时器初值
   }
  }
if(app_timers[KEY_INPUT_TIMER].uc_flag_enabled==1){
    if(app_timers[KEY_INPUT_TIMER].us_count>=KEY_DOWN_TIME){
       b_Time_Out = 1;  //延时抖动定时器时间到,确定有按键按下
       b_g_flag_lrnkeydn_first=1;
       app_timers[KEY_INPUT_TIMER].uc_flag_enabled=0;
  
   }
}
//===================================
if(b_Time_Out ==1){  //定时时间到,检查按键是否依然处于按下状态
if(P0!=0x1f){
//确实有按键按下
    //当有按键按下时,关闭屏幕自动切换,打开背光
     b_ScreenChangeAuto_EN =0;
       ui_value = keyscan();
//=========test start   打印按键值====================     
    tempui_value =ui_value>>8;   
    Print_String(&tempui_value, 1);     //打印高字节
    tempui_value = ui_value&0xff;
    Print_String(&tempui_value, 1); //打印低字节
//===============================   
    Print_String("CLR", 3);
    LED_LEARN =ON; //  LED3
   // P0 =ui_value&0x1f;
    Delay_1ms(250);Delay_1ms(250);Delay_1ms(250);Delay_1ms(250);
    LED_LEARN =OFF; //  LED3
    uc_valueP0 =P0;
    Print_String(&uc_valueP0, 1);
//===========test end=============== */  
   
   while((P0&0X1F)!=0X1F);      //等待按键弹起   
  LED_LEARN =OFF; //  LED3
      Delay_1ms(250);Delay_1ms(250);Delay_1ms(250);Delay_1ms(250);
   
  }   
  }
}

  return ui_value ;
}


/*

我使用的是模拟的定时器,使用定时器延时去抖动

我的原来的想法是,当按键弹起的话P0的低5位应该是0X1F,但是通过打印的方法发现按键松开的时候低5位不是0X1F;

另一种测试方法:我认为按键弹起的时候P0应该是FF
while((P0&0XFF)!=0XFF);      //等待按键弹起     

但是通过串口打印发现 当按键按键按下时P0是几,弹起的时候还是几,



方法3 :

在while((P0&0XFF)!=0XFF);     前先给P0=0XFF,但是发现按键有没有弹起 读出的P0都等于0xff,

*/
我是要在LCD上通过矩阵键盘输入号码 的,但是按下一次按键就输入几个相同的值,
比如按下 1  我的意思是输入一个 1 ,但其实LCD上显示几个 1 ,所以想有个按键弹起的检测的。

有其他办法一次输入一个号码也行   

相关帖子

沙发
xuyaqi| | 2013-6-13 17:46 | 只看该作者
“通过打印的方法”是什么意思?

使用特权

评论回复
板凳
xuyaqi| | 2013-6-13 17:48 | 只看该作者
上图说明方便,要有图

使用特权

评论回复
地板
xuyaqi| | 2013-6-13 17:56 | 只看该作者
判断一次键按下后,要延时一段时间再判断,否则按一次会判断出几个来。

使用特权

评论回复
5
wang12zhe|  楼主 | 2013-6-13 18:32 | 只看该作者
xuyaqi 发表于 2013-6-13 17:56
判断一次键按下后,要延时一段时间再判断,否则按一次会判断出几个来。

你说的是去除抖动的延时,还是两次安几按键按下之间的延时?

使用特权

评论回复
6
wang12zhe|  楼主 | 2013-6-13 20:34 | 只看该作者
xuyaqi 发表于 2013-6-13 17:46
“通过打印的方法”是什么意思?

就是我使用了单片机串口,在串口助手上打印出对应的值

使用特权

评论回复
7
xuyaqi| | 2013-6-13 21:21 | 只看该作者
当你按键按下没有抬起时,第一次判断到按下接着马上又判断,这两个判断间要有延时。应该在0。5秒以上。

使用特权

评论回复
8
dirtwillfly| | 2013-6-14 08:04 | 只看该作者
多少个按键啊?为啥还接P20还有P45?

使用特权

评论回复
9
wang12zhe|  楼主 | 2013-6-14 11:13 | 只看该作者
dirtwillfly 发表于 2013-6-14 08:04
多少个按键啊?为啥还接P20还有P45?

5*5的矩阵键盘

使用特权

评论回复
10
yiucing| | 2013-6-14 15:08 | 只看该作者
keyscan改成这样应该可以吧
行5位置0,列5位置设为输入,读取低5位键值
列5位置0,行5位置设为输入,读取高5位键值
这样就获取了10位键值

当键值是二进制11111 11111b时表示按键松开

使用特权

评论回复
11
wang12zhe|  楼主 | 2013-6-19 21:32 | 只看该作者
yiucing 发表于 2013-6-14 15:08
keyscan改成这样应该可以吧
行5位置0,列5位置设为输入,读取低5位键值
列5位置0,行5位置设为输入,读取高 ...

很遗憾,如果是这样我就不用问了,
问题已经解决  谢谢

使用特权

评论回复
12
1毛1| | 2015-11-4 08:54 | 只看该作者
楼主的解决方法是什么?小弟也遇到这问题了,求解决方法

使用特权

评论回复
13
ayb_ice| | 2015-11-4 09:03 | 只看该作者
本帖最后由 ayb_ice 于 2015-11-4 14:37 编辑
1毛1 发表于 2015-11-4 08:54
楼主的解决方法是什么?小弟也遇到这问题了,求解决方法

        sbit KEY0 = P0^0;
        bit key_scan_flag_10ms;        // 每间隔10MS置1
        while(1)
        {
                bit bkp;

                if(key_scan_flag_10ms){
                        bit b = KEY0;
                        key_scan_flag_10ms = 0;
                        if(b&& !bkp){
                                        // 弹起
                        }else
                        if(!b&& bkp){
                                        // 压下
                        }
                        bkp = b;
                }

                other_task();
        }

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

101

主题

205

帖子

1

粉丝