找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3005|回复: 5
收起左侧

三行按键 单片机程序分析

[复制链接]
ID:301186 发表于 2019-9-8 16:48 | 显示全部楼层 |阅读模式
今天写一个进阶级的帖子分享一下,记录过程。
三行按键由烟台南山学院-零点工作室原创,如转载,请标明出处,并附本链接。
我看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口,四个按键进行举例的。
0.png

完整的pdf格式文档51黑下载地址:
三行按键.pdf (128.32 KB, 下载次数: 30)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:56665 发表于 2019-9-9 08:30 | 显示全部楼层
有没有人在项目中用到这个按键
回复

使用道具 举报

ID:66287 发表于 2019-9-9 08:37 | 显示全部楼层
第二种方法我一直在用,实用性较高。
回复

使用道具 举报

ID:66287 发表于 2019-9-9 08:43 | 显示全部楼层
void ThreeKey()
  {
    ReadData = ~ReadData;      // 1
    Trg  = ReadData & ~Cont;  // 2 注“~”优先级高于& ;ReadData为本次键状态,Cont为上次键状态
    Cont = ReadData;               // 3
  }
这是改进版,更好理解。编译后代码量一样。
回复

使用道具 举报

ID:609746 发表于 2019-9-9 21:54 | 显示全部楼层
优秀啊
回复

使用道具 举报

ID:59423 发表于 2019-11-16 09:30 | 显示全部楼层
在实际项目中,实际使用下。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表