今天,还是一个问题,在QQ群(300384358)里有小伙伴一直在问一个问题,如上图。一个按键控制电机的转动,按键按下后,电机转动,按键释放,电机停止,再加一个按键按下时长的检测,当按下超过5秒后,电机也得停止。也就说每次按下按键后电机转动的时间不得超过5秒,就算按键按下时时长超过5秒。
问题其实很简单,才开始的小伙伴就是没想法,其他小伙伴出谋划策后还是没解决问题,今天我们就来慢慢叨叨。
这个问题的难点一是在按键按下5秒的识别,小伙伴说了不要求精确的5秒,大概是5秒就可以了。难点二是按键释放的检测,好多小伙伴想不到办法,还是用检测按键按下的if语句,效果不佳,小代在这呢推荐大家用while循环的方式去实现,具体怎么实现呢?
往下看
直接上代码
按键识别还是采用大家最能接受的二次检测加延时的方式,便于好理解。小代说的while循环检测按键释放,其实 就是第23行,循环结束标志是按键的状态(0或1)再做“非”运算。解释一下,从上面我们的二次检测加延时的方式能看出,按键按下去后,状态值是0,那我们再做一个“非”运算后就变成了1,相反,按键没按下的时候,“非”运算后是0,当while语句的条件变为0了,自然循环就结束了,这里说的按键没按下,其实也可以说是按键从按下到释放的这个过程。
我们来捋一捋这段代码的运行,首先到了while(!KEY){}这个循环,就说明按键已经按下了,此时有两种情况,一种是最简单的,按下时间没到5秒钟,那按键释放后直接停止电机转动就好,第二种情况是按键按下时长大于等于5秒钟,这时需要在按下时长到5秒的时候,关闭电机。上面我们分析过了,按键按下以后,while(!KEY){}循环继续执行,只要按键释放,自动跳出此循环,这样一来,我就只需要在这个while循环里去检测时间有没有到达5秒钟,时间精确度又不要求太高,那我们完全可以采用简单的记录次数来实现时间的计算,在以上代码中,我假设while循环2000次的时间是5秒钟,while循环一次,对计次变量加1,完了再去检测有没有大于等于2000了,当大于等于2000了,就说明按下时间大于等于5秒钟了,此时我们需要关闭电机。当出现第一种情况,就是按下时长小于5秒钟时间,这时直接退出while循环,在循环后面紧跟着关闭电机,再把按下计次变量清零,准备下一次的按键记录。
这样一来就实现对时间的记录,分情况控制。分析问题时我们做了2种情况的分析,写代码时,其实我们只是对按键释放做了识别,又在按键释放之前,做了计次的处理。这样的按键释放检测方式可以用在其他的地方比如我们的按键调整时钟时间,计算器等等。
这样的检测方式也是有弊端的,第一,我们在做按键释放时候,只做了按键的检测,如果有其他实时性要求高的代码段,需要放到这里的while循环中去,比如数码管显示的动态扫描。第二,循环计次的变量,这里我定义成了uint型,最大范围是65535,当记录次数大于这个值的时候,代码就有问题了,当我们长时间的按着按键不释放,比如按着1分钟。要解决这个问题,需要我们此时好一个最长按键时间,比如10秒,只要大于我们要求的时间就好,当到记录次数大于这个值后将不再加1运算。
好了,今天的问题就叨叨到这里,希望我们都有所收获。
·END·