今天写一个进阶级的帖子分享一下,记录过程。
三行按键由烟台南山学院-零点工作室原创,如转载,请标明出处,并附本链接。
我看CSDN上有三行按键相关的分析,但并不是原创作者以及我们工作室相关学长。
三行按键从出生到现在已经很多个年头了,经过几代优化,现在有两个版本,今天分析一下,也在本论坛扩充一下资源。
我在本论坛搜索三行按键,并没有相关的帖子。
首先说明一下什么是三行按键,有什么用,什么好处,以及弊端。
三行按键,顾名思义,代码只有三行;
用处:在咱日常生活中,运用按键时(矩阵按键除外),例如四个独立按键甚至八个。完全可以使用。
最大的好处就是,平时按键会有长按和短按,不难理解,一个是触发就松手,另一就是按下不松手,第二个针对按下就执行某个程序,松开就停止执行,比如手表上调时间的按钮,分钟在长按0.8s之后自己会自加,当松开按钮时,停止自加。
好处:代码简介,但是分析过程比较困难,接下来会进行分析。
弊端:下面两种方法都有各自的弊端,在下面有详细说明。
首先写出三行按键的两个版本:

void Threekey(uchar *Trg,uchar *Cont)
{
        unsigned char ReadData = (P3 & 0x0f) ^ 0xff;
        (*Trg) = ReadData & (ReadData ^ (*Cont));
        (*Cont) = ReadData;
}


void ThreeKey(void)
{
        unsigned char ReadDat = (P3 ^ 0xff) & 0x0f;
        Trg = (ReadDat ^ Cont)& ReadDat;
        Cont = ReadDat;
}

最大的区别不在指针,而是在相与以及或运算的先后顺序。
导致最后当按键触发,运算出来的结果不相同,。
代码分析如下:
//第一种程序解析
/*******************************************/
void key(void)
{
       unsignedchar ReadData = (P3 & 0x0f)^ 0xff;
       Trg)=ReadData & (ReadData^ Cont);
       Cont)=ReadData;
}
//短按
//没有按下情况下:
       ReadData= (0xff & 0x0f) ^ 0xff = 0xf0
       Trg= 0xf0 & (0xf0 ^ 0x00) = 0xf0
       Cont= 0xf0
//第二次扫描未按下
       ReadData= (0xff & 0x0f) ^ 0xff = 0xf0
       Trg= 0xf0  & ( 0xf0 ^  0xf0) = 0x00
       Count=  0xf0
//第三次扫描未按下
       ReadData= (0xff & 0x0f) ^ 0xff = 0xf0
       Trg= 0xf0 & (0xf0 ^ 0xf0) = 0x00
       Cont= 0xf0
//当第一个按键按下情况
       ReadData= (0xfe & 0x0f) ^ 0xff = 0xf1
       Trg= 0xf1 & ( 0xf1 ^ 0xf0) = 0x01
       Cont= 0xf1
//长按
//当按键按下并且不放手情况
       ReadData= (0xfe & 0x0f ) ^ 0xff = 0xf1
       Trg= 0xf1 & (0xf1 ^ 0xf1 ) = 0x00
       Cont= 0xf1
//按键松手
       ReadData= (0xff & 0x0f) ^ 0xff = 0xf0
       Trg= 0xf0 & (0xf0 ^ 0x00) = 0xf0
       Cont= 0xf0


以此类推 短按情况下 Trg = 0x01
                                           0x02
                                           0x04
                                           0x08
长按情况下 Count  = 0xf1
                                              0xf2
                                              0xf4
                                              0xf8
弊端:当按键没有按下,第一次扫描的Trg第一次会有一个值的变化,Trg= 0xf0;现在还没有试出来对执行程序有什么影响。
//第二种程序解析
/*******************************************/
void ThreeKey(void)
{
       unsignedchar ReadDat = (P3 ^ 0xff)& 0x0f;
       Trg= (ReadDat ^ Cont)&ReadDat;
       Cont= ReadDat;
}
//短按
//按键没有按下情况
       ReadDat= (0xff ^ 0xff) & 0x0f = 0x00
       Trg= (0x00 ^ 0x00 ) & 0x00 = 0x00
       Cont= 0x00
//按键按下情况 第一个按键按下
       ReadDat= (0xfe ^ 0xff) & 0x0f = 0x01
       Trg= (0x01 ^ 0x00) & 0x01 = 0x01
       Cont= 0x01
//长按
//按键按下没有松手情况
       ReadDat= (0xfe ^ 0xff ) & 0x0f = 0x01
       Trg= (0x01 ^ 0x01) & 0x01 = 0x00
       Cont= 0x01
//按键松手
       ReadDat= (0xff ^ 0xff) & 0x0f = 0x00
       Trg= (0x00 ^ 0x01) & 0x00 = 0x00
       Count  = 0x00




以此类推 短按情况下 Trg = 0x01
                                           0x02
                                           0x04
                                           0x08
长按情况下 Count  = 0x01
                                              0x02
                                              0x04

                                              0x08

弊端:短按Trg和长按Count运算结果是一样的,也就是说当执行程序的时候需要分明。第二种比较好用。
附件文件和本文程序一样。
主要就是讲这个算法如何用,而不是拿现成的程序来给你们,这样这段算法的意义并不大。
说明一下,第二个代码的Trg以及Count是全局变量,可以在执行按键的函数里面进行调用。
这段例程里面,按键可以放在P30,P31,P32,P33口,四个按键进行举例的。

三段式VXLAN有什么缺点 三段式按键是什么意思_全局变量