[51单片机] 求助:程序算法思想:两个按键,按键顺序不同,功能不同。

[复制链接]
3560|15
 楼主| 亲亻尔嘴 发表于 2014-2-21 16:23 | 显示全部楼层 |阅读模式
先按键1松开,再按键2松开,这是一个作用(即置位作用1标志位)。
先按键2松开,再按键1松开,这又是一个作用(即置位作用2标志位)。


该怎么去设计程序呀??
嵌入式云终端 发表于 2014-2-21 16:27 | 显示全部楼层
你这不是已经将你的任务描述出来了么,写个流程图就好了,用定时器,规定时间内开始检测,判别功能,两次判别时间要长点,否则会误判
ningling_21 发表于 2014-2-21 16:33 | 显示全部楼层
先画流程图,看看逻辑是否矛盾,如果有矛盾就不要继续了...
 楼主| 亲亻尔嘴 发表于 2014-2-21 16:55 | 显示全部楼层
ningling_21 发表于 2014-2-21 16:33
先画流程图,看看逻辑是否矛盾,如果有矛盾就不要继续了...

恩恩 我去画个流程图··
 楼主| 亲亻尔嘴 发表于 2014-2-21 16:56 | 显示全部楼层
嵌入式云终端 发表于 2014-2-21 16:27
你这不是已经将你的任务描述出来了么,写个流程图就好了,用定时器,规定时间内开始检测,判别功能,两次判 ...

我先去画流程图
很忙 发表于 2014-2-21 17:14 | 显示全部楼层
最近发现按键原来可以这样处理:
比如你的按键是IO口检测的,一般按下去了该IO口为0,松开,该IO口为1,
你可以这样设计:
bit KEY1
bit KEY2
bit key1_buf=1;
bit key2_buf=1;

unsigned char  key_detect=0;
unsigned char  key_ok=0;

if(key1_buf!=KEY1)
{
   if(key1_buf=0)
   {
    if(key_detect==0)  key_detect=2;
    else if(key_detect==1)  
       {
        key_detect=0;
        key_ok=1;
       }
   }  
   key1_buf=KEY1;
}
if(key2_buf!=KEY2)
{
   if(key2_buf=0)
   {
    if(key_detect==0)  key_detect=1;
    else if(key_detect==2)  
       {
        key_detect=0;
        key_ok=2;
       }
   }  
   key2_buf=KEY2;
}
key_ok这个就是你要等到的标志位的按键了。
实现起来很简单。
ff8zgs 发表于 2014-2-21 17:15 | 显示全部楼层
其实用状态机可以实现这个想法,我所有的仪表类的显示任务都用按键顺序修改状态机。非常灵活。
 楼主| 亲亻尔嘴 发表于 2014-2-21 17:28 | 显示全部楼层
很忙 发表于 2014-2-21 17:14
最近发现按键原来可以这样处理:
比如你的按键是IO口检测的,一般按下去了该IO口为0,松开,该IO口为1,
你 ...

别看就这几行代码,我是看晕了···
天南星雨 发表于 2014-2-21 17:28 | 显示全部楼层
有没有时间限制,如果没有那就相当简单了。
很忙 发表于 2014-2-21 17:34 | 显示全部楼层
亲亻尔嘴 发表于 2014-2-21 17:28
别看就这几行代码,我是看晕了···

很好理解啊。
if(key1_buf!=KEY1)和if(key2_buf!=KEY2)
说明IO口电压有变化
if(key1_buf=0)说明变化的时候IO口的前一个状态是低,说明这个时候按键是松开了。
if(key_detect==0)  key_detect=2;
    else if(key_detect==1)  
       {
        key_detect=0;
        key_ok=1;
       }
这些就是在按键松开的时候做些判断,如果按键2有松开就执行功能,如果按键2没有松开就设标志自己松开了。
按键2也是这样理解。所以很简单啊。
 楼主| 亲亻尔嘴 发表于 2014-2-21 17:40 | 显示全部楼层
天南星雨 发表于 2014-2-21 17:28
有没有时间限制,如果没有那就相当简单了。

简单? 我是弄的头都晕了···

我刚开始是这样想的:判断按键1是否按下,如果键1按下判断按键2是否按下,如果键2按下,则置位作用1标志。
紧接着
判断按键2是否按下,如果键2按下判断按键1是否按下,如果键1按下,则置位作用2标志。


但是在调试时发现,不论先按哪个,总是作用1标志位被置位~

然后我就发现,我的上述思想,不论先按哪个,总是说明两个按键均被按下,也就使得判断不分先后了~~~
 楼主| 亲亻尔嘴 发表于 2014-2-21 18:12 | 显示全部楼层
很忙 发表于 2014-2-21 17:34
很好理解啊。
if(key1_buf!=KEY1)和if(key2_buf!=KEY2)
说明IO口电压有变化
  1. bit KEY1
  2. bit KEY2
  3. bit key1_buf=1;
  4. bit key2_buf=1;

  5. unsigned char  key_detect=0;
  6. unsigned char  key_ok=0;


  7. /***********************************************
  8. 首先按键1按下松开:因为初始时key_detect = 0,所以使得key_detect = 2,
  9.              如果按键2一直不动作,key_detect值会一直不变(为2)。
  10.                          即使再次按下按键1,key_detect值仍会一直不变
  11. 然后按键2动作:因为key_detect = 2,则key_detect=0;且key_ok=2;

  12. 首先按键2动作:key_detect=1,
  13.                如果按键1一直不动作key_detect仍为1
  14.                            即使再次动作按键2,key_detect仍为1
  15. 然后按键1动作:key_detect=0;key_ok=1;

  16. 结论:key_ok=2:先按键1动作,再按键2动作
  17.           key_ok=1:先按键2动作,再按键1动作
  18. ***********************************************/
  19. if(key1_buf!=KEY1)         //按键1端口电平有变化
  20. {
  21.    if(key1_buf=0)         //判断按键前一个状态是否为低
  22.    {                                 //说明按键松开了
  23.         if(key_detect==0)  key_detect=2;
  24.         else if(key_detect==1)  
  25.         {
  26.             key_detect=0;
  27.             key_ok=1;
  28.         }
  29.    }  
  30.    key1_buf=KEY1;
  31. }
  32. if(key2_buf!=KEY2)       
  33. {
  34.    if(key2_buf=0)
  35.    {
  36.     if(key_detect==0)  key_detect=1;
  37.     else if(key_detect==2)  
  38.        {
  39.         key_detect=0;
  40.         key_ok=2;
  41.        }
  42.    }  
  43.    key2_buf=KEY2;
  44. }




我是这样分析的~~
草民 发表于 2014-2-21 21:52 | 显示全部楼层
李宾 发表于 2014-2-21 23:02 | 显示全部楼层
呵呵,如果两次按键之间没有时间限制。
貌似程序设计不复杂呀。
可以设计两个变量:

unsigned char  老键值,新键值;

关于键值,可以作简单的处理。
0:代表没有键被按下并抬起;
1:代表按键1被按下抬起;
2:代表按键2被按下抬起。
(通过键盘扫描程序,可以规避第四种可能,即两键同时被按下。再进上步说就是先查1键,如果1键没按下,再查2键。如果1键按下并抬起,则返回键值1,不检查2键。)

在程序初始时,将 “旧键值”和“新键值”同时置成0;

程序中设计一个循环体:

{
扫描键盘,得到一个键值(0,1,2三者之一)。
将键值赋予“新键值”变量;
判断:如果((新键值为1,而且,旧键值为2)或者(新键值为2,而且,旧键值为1))
     {完成二个任务,第一个任务执行相应的功能,即新1旧2,完成某种功能,新2旧1完成某种功能。在完成第一个任务后,需要把“新键值”“旧键值”两个变量重新清0;以便开始新一轮检测。}
     否则,(注意这个“否则”和上面的“如果”一般需要用 if....else...实现。)
{完成一个任务,将“新键值”赋予给“旧键值”}
}
李宾 发表于 2014-2-21 23:16 | 显示全部楼层
本帖最后由 李宾 于 2014-2-21 23:19 编辑

首先,一般情况,很少有这种按键功能设计成这样的。
即使设计成这样,比较合理的规格,应该要求两次按键之间要有一定短的时间间隔,比如,
先按1键,在半秒内,再按2键,2键抬起后,如何如何。1键按完后,半秒内无按键,则认为1键按下抬起为无效的。
先按2键,在半秒内,再按1键,1键抬起后,如何如何。2键按完后,半秒内无按键,则认为1键按下抬起为无效的。

两次按键之间没有时间限制,这样不是很完善。
 楼主| 亲亻尔嘴 发表于 2014-2-22 15:11 | 显示全部楼层
李宾 发表于 2014-2-21 23:16
首先,一般情况,很少有这种按键功能设计成这样的。
即使设计成这样,比较合理的规格,应该要求两次按键之 ...

非常感谢,让我有学会了一种思想···
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

46

帖子

0

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