[STC单片机] STC 单片机ADC按键扫描松手检测程序问题

[复制链接]
 楼主| huzb11 发表于 2016-7-12 12:53 | 显示全部楼层
是不是一定要把按键处理放在中断里进行呢?按一下调用中断处理,去进行身高测量,体重测量。。。。
 楼主| huzb11 发表于 2016-7-12 22:28 | 显示全部楼层
ADC按键与普通按键松手检测,已经解决了。我把它写出来,以防以后有类似的新手,遇到相同的问题得不到解决办法。我的方法是,我在主循环里面。用switch 判断键值。。。在对应case语句里,进行执行死循环while(1)。。。在死循环while(1)下执行某一个要执行的测量函数,同时判断标志位,当执行死循环后,按键一直执行里面的程序,就算你松手了,它也在执行。如果要跳死循环,用标志位作状态判断,当然你测量函数里也要有用那个标志位,标志位设置成extern 变量即可。当标志位等于某个状态时,用break跳出即可。


         ky=keysend(Readkey());
                 switch(ky)
  {

                 

  case 1:
                    while(1)
            {    tg_comp();                 //第一个按键 发送语音提醒:开始测量
                 if(flag==1)break;
                  }
                       
                   break;
  case 2: ; break;                          

}

这样,只要按键按下后,它会执行对应的case语句,松手后,它进入死循环里。。。当标志位等于设定某个值时,跳出。。。这个程序目前已经解决了我的基本问题,但是按键偶尔有点失灵,请坛友帮我分析一下,是由于按键抖动的问题造成的吗?怎么修正当前的缺陷?
datouyuan 发表于 2016-7-14 09:26 | 显示全部楼层
huzb11 发表于 2016-7-12 22:28
ADC按键与普通按键松手检测,已经解决了。我把它写出来,以防以后有类似的新手,遇到相同的问题得不到解决 ...

你这种做法很不好.
请仔细看看22楼的回复.
按键程序最通常的做法:
定时获得键值,根据键值和持续时间来确定按键状态,根据按键状态和按键值做相应的按键处理.
获得键值要用1个函数或表达式完成.这样不管你是哪种按键,AD 独立 阵列式按键,你只需要改写这部分,多省事.
按键处理也单独开来,主要精力就是写该部分代码.
这样处理按键的优点:占用mcu时间短,几乎是0耗时,可以很方便的嵌入到任何应用中.
datouyuan 发表于 2016-7-14 10:24 | 显示全部楼层
给你看看我的实际工程中的做法:
获取按键键值
  1. uint8 KeyGet(void)
  2. {
  3.         return (GetADC_8(5)+8)/16;//AD按键
  4. }
  5. uint8 KeyGet(void)                //独立按键
  6. {
  7.         uint8 i;
  8.         i=VOID_KEY;
  9.         if(p10_pin==0) //呼叫键
  10.                 i|=1;
  11.         if(p37_pin==0) //系统卡设置键
  12.         {
  13.                 p37_pin=1;
  14.                 DELAY_uS(5);
  15.                 if(p37_pin==0)
  16.                         i|=2;
  17.                 p37_pin=0;
  18.         }
  19.         return i;
  20. }


和按键处理有关的几个定义

  1. #define VOID_KEY      0         //无键键值
  2. //和按键时间有关的常数(mS)
  3. #define DLY_XD        40        //消抖
  4. #define DLY_NO_KEY    120        //无键
  5. #define DLY_RPT_START 1000        //重发首键
  6. #define DLY_RPT       200        //重发间隔
  7. #define DLY_LONG      10000        //长按



按键执行程序.keyvalue++;是为了去除编译警告用的,
  1. void Key_Down_short(uint8 keyvalue)        //短按
  2. {keyvalue++;
  3. }
  4. void Key_Down_long_rpt(uint8 keyvalue)        //长按连发
  5. {keyvalue++;
  6. }
  7. void Key_Down_long(uint8 keyvalue)        //长按20S
  8. {//keyvalue++;
  9.         if(keyvalue==8)//监视键当老化键
  10.         {
  11.         }
  12. }
  13. void Key_Up_long(uint8 keyvalue)        //长按抬起
  14. {keyvalue++;
  15. }
  16. void Key_Up_short(uint8 keyvalue)        //短按抬起
  17. {//keyvalue++;
  18.         uint8 i;
  19.         switch (keyvalue)
  20.         {
  21.                 case 2://电控锁  1        开锁(电控锁)键
  22.                 {
  23.                 }break;
  24.                 case 4://电磁锁/摄像头  2        开锁(电磁锁)键
  25.                 {//对讲时,开锁作用。开关3#mkj
  26.                 }break;
  27.                 case 6://菜单  3        铃声选择键
  28.                 {
  29.                 }break;
  30.                 case 8://监视/-
  31.                 {
  32.                 }break;
  33.                 case 10://5        对讲/户户通键
  34.                 {//
  35.                 }break;
  36.                 case 1://hht  6        铃声音量键
  37.                 {//
  38.                 }break;
  39.                 default:
  40.                 {
  41.                 }break;
  42.         }
  43. }


datouyuan 发表于 2016-7-14 10:32 | 显示全部楼层
huzb11 发表于 2016-7-12 22:28
ADC按键与普通按键松手检测,已经解决了。我把它写出来,以防以后有类似的新手,遇到相同的问题得不到解决 ...

你所说的松手检测在我的代码里叫"抬起"
有"长按抬起" "短按抬起"2种,比较常用是"短按抬起".
 楼主| huzb11 发表于 2016-7-14 16:03 | 显示全部楼层
嗯,受益不少
kk118a 发表于 2016-7-14 17:22 | 显示全部楼层
把按键值定议一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部