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

[复制链接]
 楼主| huzb11 发表于 2016-7-11 13:55 | 显示全部楼层 |阅读模式
本帖最后由 huzb11 于 2016-7-11 13:57 编辑

u8 key_Process(u8 key_ad)
{        
u8 kad;
kad=GetADCResult(0);

if(kad==0) //执行K1操作
{


Disp(GetADCResult(0));

}

}
else if(kad>20&&kad<25)          //执行K2操作
{
close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>30&&kad<45)        //执行K3操作
{

close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>55&&kad<70)        //执行K4操作
{

close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>78&&kad<85)        //执行K5操作
{

close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>90&&kad<110)        //执行K6操作
{
close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>125&&kad<135)         //执行K7操作
{

close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>150&&kad<160)          //执行K8操作
{

close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>248&&kad<260)          //执行无按键AD值为全值255操作
{   
                //tg_comp();//检测无人站在托盘上时,进行发语音提醒
        close_Led();        
        Fault_Fled();
}


return 1;

}

上面程序控制K1-K8按键,当按下后,显示对应的AD键值,当松手后,就没显示了,如何让它松手后才正常显示AD键值。

后来,我把第一个按键改成这样,发现第一个按键,按下直接不显示。ADC按键扫描松手后检测如何做?哪位帮看一下。哪里出了问题?


if(kad==0) //执行K1操作
{
   Delay1ms();
   if(kad==0)
   {
   Delay1ms();
   while(kad)
   {

Disp_tg(GetADCResult(0));
   }
   }

}
wangyy608 发表于 2016-7-11 14:41 | 显示全部楼层
保存前一次的AD值
 楼主| huzb11 发表于 2016-7-11 14:47 | 显示全部楼层
wangyy608 发表于 2016-7-11 14:41
保存前一次的AD值

现有的程序如何改?如何操作?
wangyy608 发表于 2016-7-11 14:52 | 显示全部楼层
kad=GetADCResult(0);
if((kad!=old——ad)&&(kad>248&&kad<260)   )
{   
     if(kad==0) //执行K1操作
    {
         Disp(GetADCResult(0));
    }
    .......
}
old_ad = kad;



大概是这么个意思
 楼主| huzb11 发表于 2016-7-11 15:50 | 显示全部楼层
wangyy608 发表于 2016-7-11 14:52
kad=GetADCResult(0);
if((kad!=old——ad)&&(kad>248&&kad

&&(kad>248&&kad<260  

这一句是什么意思?

还有old_ad = kad;

这一句是最后再给old_ad赋一次值吗?
 楼主| huzb11 发表于 2016-7-11 15:56 | 显示全部楼层
wangyy608 发表于 2016-7-11 14:52
kad=GetADCResult(0);
if((kad!=old——ad)&&(kad>248&&kad

试过了,不行。第一组按键 Kad=0,第一个按键按了之后,松手开始显示。
jrcsh 发表于 2016-7-11 16:35 | 显示全部楼层
  来个超时处理不就行了,
 楼主| huzb11 发表于 2016-7-11 16:37 | 显示全部楼层
求教各位高人如何解决,ADC按键松手后检测,下午弄很久了,都没成效。。。以上程序如何修改?
 楼主| huzb11 发表于 2016-7-11 16:50 | 显示全部楼层
fxmxh 发表于 2016-7-11 16:41
else if(kad>248&&kad248&&kad

那么我上面的程序如何修改呢?
 楼主| huzb11 发表于 2016-7-11 16:55 | 显示全部楼层
关键是按键松手后,怎么能让它正常显示?按一下才显示,我最上面已经OK了。我要ADC按键松手后才正常显示。。。
datouyuan 发表于 2016-7-11 17:33 | 显示全部楼层
你把按键分析和按键执行分开,就好做了.

再用一个变量存上一次的键值.

  1. u8 u8KeyOld;
  2. u8 key_Process(void)
  3. {
  4.         u8 kad;
  5.         kad=GetADCResult(0);
  6.         kad=GetKey(kad);
  7.         if(u8KeyOld==kad)
  8.         {//按键无变化
  9.         }
  10.         else
  11.         {//按键有变化
  12.                 if(u8KeyOld=0xff)
  13.                 {
  14.                         //ExeKey(kad);//按下执行
  15.                 }
  16.                 else
  17.                 {//松手
  18.                         ExeKey(u8KeyOld);//松手执行
  19.                 }
  20.         }
  21.         u8KeyOld==kad;
  22. }
zyj9490 发表于 2016-7-11 17:35 | 显示全部楼层
huzb11 发表于 2016-7-11 16:37
求教各位高人如何解决,ADC按键松手后检测,下午弄很久了,都没成效。。。以上程序如何修改? ...

你必须要用状态机原理,检测一次按键的过程,非高电平--去抖---再判---得出一个键,开始计时(区争长键还是短按)---检出高电平(恢复原始状态),完成一个短按键的过程,(超时,得出一个长按事件),执行按键函数。
datouyuan 发表于 2016-7-11 17:40 | 显示全部楼层
本帖最后由 datouyuan 于 2016-7-11 17:46 编辑
  1. u8 GetKey(u8 Kad)
  2. {
  3.         f(kad==0) //执行K1操作
  4.                 return 1;
  5.         else if(kad>20&&kad<25)          //执行K2操作
  6.                 return 2;
  7.         //....
  8.         else if(kad>248&&kad<260)          //执行无按键AD值为全值255操作
  9.                 return 0xff;
  10. }
  11. void ExeKey(u8 keyvalue)
  12. {

  13.         switch (keyvalue)
  14.         {
  15.                 case 1://执行K1操作
  16.                 {
  17.                 }break;
  18.                 case 2://执行K2操作
  19.                 {
  20.                 }break;
  21.                 default:
  22.                 {
  23.                 }break;
  24.         }
  25. }

 楼主| huzb11 发表于 2016-7-11 17:45 | 显示全部楼层
本帖最后由 huzb11 于 2016-7-11 17:47 编辑

上面的程序,如何才能像普通按键一样,按键释放后仍能读取按键的值,如下面。在主程序直接可以直接调用。

u8 Readkey(void)
{
  u8 temp;
  temp=P5IN&0xf0;
  if(temp!=0xf0)
  {
    delayms(10);
    if(temp==(P5IN&0xf0))
    {
        return temp;
      }
  else
    return 0xff;
   }
    else
      return 0xff;
}

u8 keysend(u8 dat)
{
  u8 key;
  key=Readkey();
  switch(key)
  {
  case 0xe0: key=1;
  break;
  case 0xd0: //sp();
                 key=2;
                 //P5OUT=~BIT0;
                 break;
  case 0xb0: key=3;
  break;
  case 0x70: key=4;
  break;
  
  }
   return key;
}


--------------------

main(void)
{
while(1)
if(keysend(Readkey())==1)
                                
{   delayms(10);           //消除按键抖动
                             
if(keysend(Readkey())==1)
{
执行某操作
}
else if(keysend(Readkey())==2)
{
执行某操作
....
}-}

datouyuan 发表于 2016-7-11 17:50 | 显示全部楼层
本帖最后由 datouyuan 于 2016-7-11 17:54 编辑
huzb11 发表于 2016-7-11 17:45
上面的程序,如何才能像普通按键一样,按键释放后仍能读取按键的值,如下面。在主程序直接可以直接调用。

...

这2个函数仅仅是分析和执行按键.

你需要的功能是只要按15楼的程序做.在按下的位置再加全局变量保存你要的值
在松手的位置处理这些全局变量.
 楼主| huzb11 发表于 2016-7-11 19:07 | 显示全部楼层
datouyuan 发表于 2016-7-11 17:33
你把按键分析和按键执行分开,就好做了.

再用一个变量存上一次的键值.

kad=GetKey(kad);

这一句:getkey(kad),从哪里得到的值?
billliu66 发表于 2016-7-11 21:56 | 显示全部楼层
在没有跳转语句的情况下,程序是顺序执行的,在没有第二次执行"kad=GetADCResult(0);"时,kad的值是不会变的,尽管你已松手,因而将"Disp(GetADCResult(0));"改为"Disp(kad);"即可达成目标.
datouyuan 发表于 2016-7-12 10:36 | 显示全部楼层
huzb11 发表于 2016-7-11 19:07
kad=GetKey(kad);

这一句:getkey(kad),从哪里得到的值?

我在17楼给了示范代码(是根据你的u8 key_Process(u8 key_ad)函数写的)
Getkey(kad)           按键分析
Exekey(keyvalue)    按键执行

分开后,功能灵活,互不影响,结构清晰.

16楼的代码是定时执行(可以每隔50mS执行一次),结合时间你可以用17楼的2个函数,产生短按下 长按下 短按下抬起 长按下抬起 长按连发等各种按键效果.16楼的代码只给出了短按下 和按键抬起这两功能.
 楼主| huzb11 发表于 2016-7-12 12:05 | 显示全部楼层
datouyuan 发表于 2016-7-12 10:36
我在17楼给了示范代码(是根据你的u8 key_Process(u8 key_ad)函数写的)
Getkey(kad)           按键分析
E ...

我现在把它改为独立按键了。按键与菜单程序以前研究得太少。很多子程序都弄好了,一但放在按键里,就出问题了。要么按键松手后,去执行某一个函数,没反应。要么按完了,不执行。比如下面的程序。。。

u8 Readkey(void)
{
  u8 temp;
  temp=P5IN&0xf0;
  if(temp!=0xf0)
  {
    delayms(10);
    if(temp==(P5IN&0xf0))
    {
        return temp;
      }
  else
    return 0xff;
   }
    else
      return 0xff;
}

u8 keysend(u8 dat)
{
  u8 key;
  key=Readkey();
  switch(key)
  {
  case 0xe0: key=1;
  break;
  case 0xd0: //sp();
                 key=2;
                 //P5OUT=~BIT0;
                 break;
  case 0xb0: key=3;
  break;
  case 0x70: key=4;
  break;
  
  }
   return key;
}


--------------------

main(void)
{
while(1)
if(keysend(Readkey())==1)
                                
{   delayms(10);           //消除按键抖动
                             
if(keysend(Readkey())==1)
{
   Disp_tg();   调用体重测量函数。。。
}
else if(keysend(Readkey())==2)
{
执行某操作
....
}-}

以上程序也是,按键一松手后,程序就不执行。。。如何松手后还在执行。。。
 楼主| huzb11 发表于 2016-7-12 12:44 | 显示全部楼层
ADC按键,改成独立按键。还是按下去有显示测量,松手下后,又没显示。

u8 Readkey(void)
{
  u8 temp;
  temp=P2&0x0f;
  if(temp!=0x0f)
  {
  //  delayms(10);
    if(temp==(P2&0x0f))
    {
        return temp;
      }
  else
    return 0xff;
   }
    else
      return 0xff;
}


u8 keysend(u8 key)
{

  switch(key)
  {
  case 0x0e: key=1; break;
  case 0x0d: key=2; break;
  case 0x0b: key=3;break;
  case 0x07: key=4;break;
  
  }
   return key;
}

extern u8 ky;



main()       
{
   u8 key_num;
    io_init();
   //time_init();
        P0=P1=P2=P3=P4=P5=0xff;
        close_Led();
    init_SR04();   
        Sp=0;
        InitADC();
        while(1)
        {
          Srelay();       
                 
          //Disp_tg(GetADCResult(0));       
           //Disp_tg(ADC_key_filter());       
           //key_Process(GetADCResult(0));
            //readkey();
                ky=keysend(Readkey());
switch(ky)
  {
  case 1: Disp_tg(tg_test()); break;
  case 2:Disp_sg(sg_test());; break;
  case 3: //key=3;
  break;
  case 4:
  //key=4;
  break;
  
  }


       
               
               
   }   

}       

单个程序放在while(1)下都能正常执行。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

55

帖子

1

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