目的:记录自己学习过程

大神按键处理程序:原著
https://blog.csdn.net/qq_26697807/article/details/78196263
另一位大神详细对上面的博文发表的个人看法,并加入防抖
https://blog.csdn.net/tianxuechao/article/details/51675033

程序

1、未加防抖

unsigned char Trg;
unsigned char Cont;void KeyRead( void )
{unsigned char ReadData = PINB^0xff;   // 1Trg = ReadData & (ReadData ^ Cont);   //按键按下,trg置一只保持一次Cont = ReadData;                      // Cont代表的是长按键,如果按着不放,那么Cont的值就为 1;
}#define KEY_MODE 0x01    // 模式按键
#define KEY_PLUS 0x02     // 加
void KeyProc(void)
{if (Trg & KEY_MODE) // 如果按下的是KEY_MODE,而且你常按这按键也没有用,{                    //它是不会执行第二次的哦 , 必须先松开再按下Mode++;         // 模式寄存器加1,当然,这里只是演示,你可以执行你想// 执行的任何代码}if (Cont & KEY_PLUS) // 如果“加”按键被按着不放{cnt_plus++;       // 计时if (cnt_plus > 100) // 20ms*100 = 2S 如果时间到{Func();      // 你需要的执行的程序}          }
}

2、加入防抖

//按键变量
unsigned char   KeyPressDown=0x00;
unsigned char   KeyRelease=0x00;
unsigned char   LastKey=0x00;//按键扫描,定时10ms执行一次
void KeyScan(void)
{   static unsigned char LastReadKey=0x00;     //记录上次KeyScan()读取的IO口键值unsigned char CurrReadKey;  //记录本次KeyScan()读取的IO口键值unsigned char CurrKey;        //记录本次经过消抖处理后的有效按键值 P1|=KEYMASK;  //将按键对应的IO设置为输入状态CurrReadKey=(~P1)&KEYMASK; //取反//消抖原理很简单://如果上次LastReadKey和当前CurReadKey读取的键值都为1,那么当前有效键值CurrKey一定为1//如果上次和当前读取的键值不一样的话,则与上次有效键值LastKey保持一致。//通过这种方式来进行消抖,抖动时间必须小于keyscan()定时扫描周期,否则会出现错误。CurrKey=(CurrReadKey&LastReadKey)|LastKey&(CurrReadKey^LastReadKey);//记录按键按下及释放KeyPressDown=(~LastKey)&CurrKey;KeyRelease=LastKey&(~CurrKey);LastReadKey=CurrReadKey;LastKey=CurrKey;
}

我是新手,看了半天才领会算法防抖的奇妙
我对程序加注释

void KEY_Check(void)
{static unsigned int LastReadKey=0x00;     //记录上次KeyScan()读取的IO口键值unsigned int CurrReadKey;               //记录本次KeyScan()读取的IO口键值unsigned int CurrKey;                 //记录本次经过消抖处理后的有效按键值 /********************KEY1_IN引脚运行代码示例*******************************CurrReadKey   CurrKey   KeyTrg    KeyRel    LastKey   LastReadKey初始值:    0x0000       0x0000    0x0000    0x0000    0x0000      0x0000按下消抖:    0x0001       0x0000    0x0000    0x0000    0x0000      0x0001   确认按下:    0x0001       0x0001    0x0001    0x0000    0x0001      0x0001长按按键:    0x0001       0x0001    0x0000    0x0000    0x0001      0x0001释放消抖:    0x0000       0x0001    0x0000    0x0000    0x0001      0x0000确认释放:    0x0000       0x0000    0x0000    0x0001    0x0000      0x0000***************************************************************************/CurrReadKey = (~KEY_Signal.iBuf)^0xFFFF;            //读当前IO口键值CurrKey=(CurrReadKey&LastReadKey)|(LastKey&(CurrReadKey^LastReadKey));    //消抖算法,当前读取键值与上次读取键值相同才说明无已消抖KeyTrg = CurrKey & (CurrKey ^ LastKey);           //按键按下,KeyTrg置一只保持一次KeyRel = LastKey & (LastKey ^ CurrKey);           //按键释放,KeyRel置一只保持一次LastKey = CurrKey;                                // LastKey代表的是长按键,如果按着不放,那么LastKey值的对应位为 1LastReadKey=CurrReadKey;                          //存储当前读取的IO口键值
}
void IO_Read(void)
{  KEY_Signal.onebits.bKEY1 = KEY1_IN;KEY_Signal.onebits.bKEY2 = KEY2_IN;KEY_Signal.onebits.bKEY3 = KEY3_IN;KEY_Signal.onebits.bKEY4 = KEY4_IN;KEY_Signal.onebits.bKEY5 = KEY5_IN;KEY_Signal.onebits.bKEY6 = KEY6_IN;KEY_Signal.onebits.bKEY7 = KEY7_IN;KEY_Signal.onebits.bKnob1 = Knob_IN1;KEY_Signal.onebits.bKnob2 = Knob_IN2;KEY_Signal.onebits.bKnob4 = Knob_IN4;KEY_Signal.onebits.bKnob3 = Knob_IN3;KEY_Signal.onebits.bKnob5 = Knob_IN5;KEY_Signal.onebits.bKnob6 = Knob_IN6;
}
typedef union
{unsigned int iBuf;struct{unsigned bKEY1 :1;unsigned bKEY2 :1;unsigned bKEY3 :1;unsigned bKEY4 :1;unsigned bKEY5 :1;unsigned bKEY6 :1;unsigned bKEY7 :1;unsigned       :1;unsigned bKnob1 :1;unsigned bKnob2 :1;unsigned bKnob3 :1;unsigned bKnob4 :1;unsigned bKnob5 :1;unsigned bKnob6 :1;unsigned :1; unsigned :1;}onebits;
}KEY_TYPE;
           CurrReadKey   CurrKey   KeyTrg    KeyRel    LastKey   LastReadKey初始值:    0x0000       0x0000    0x0000    0x0000    0x0000      0x0000
按下消抖:    0x0001       0x0000    0x0000    0x0000    0x0000      0x0001
确认按下:    0x0001       0x0001    0x0001    0x0000    0x0001      0x0001
长按按键:    0x0001       0x0001    0x0000    0x0000    0x0001      0x0001
释放消抖:    0x0000       0x0001    0x0000    0x0000    0x0001      0x0000
确认释放:    0x0000       0x0000    0x0000    0x0001    0x0000      0x0000

这样看是不是更能理解了?我只要判断LastKey、KeyRel、KeyTrg的值就能判断按键所处的状态,而且通过创建一个共同体就能不受限制的使用任何一个引脚,只要 #define KEY1_IN _RA8,宏定义一下。这里只需要注意共同体的值就可以了。

经典按键算法使用心得相关推荐

  1. 高频交易算法研发心得--WAVT指标(Warensoft交易量趋势指标)算法及应用

    高频交易算法研发心得--WAVT指标(Warensoft交易量趋势指标)算法及应用 注:WAVT指标由Warensoft(王宇)原创. 前面聊了一系列的常见应用指标,包括短线.长线的指标,并且也无耐的 ...

  2. 十种经典排序算法精粹(c语言版本)

    下面给出这段时间我苦心研究验证过的十种经典排序算法的C语言版本,即下面的排序算法: 插入排序,shell排序,冒泡排序,快速排序,选择排序,堆排序,归并排序,桶排序,基数排序和计数排序.整理出来以作备 ...

  3. C语言100个经典的算法

    POJ上做做ACM的题 语言的学习基础,100个经典的算法 C语言的学习要从基础开始,这里是100个经典的算法-1C语言的学习要从基础开始,这里是100个经典的算法 题目:古典问题:有一对兔子,从出生 ...

  4. 3分钟快速实现:9种经典排序算法的可视化

    作者 | 爱笑的眼睛 来源 | 恋习Python(ID:sldata2017) 最近在某网站上看到一个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感. ▼ 6分钟演示15种排序算法 不知道 ...

  5. 十大经典排序算法动画与解析,看我就够了

    作者 | 程序员小吴 转载自五分钟学算法(ID: CXYxiaowu) 排序算法是<数据结构与算法>中最基本的算法之一. 排序算法可以分为内部排序和外部排序.内部排序是数据记录在内存中进行 ...

  6. 世界上有哪些代码量很少,但很牛逼很经典的算法或项目案例?

    来自公众号:五分钟学算法 今天分享四个代码量很少,但很牛逼很经典的算法或项目案例. 1.no code 项目地址: https://github.com/kelseyhightower/nocode ...

  7. 十大经典排序算法(建议收藏)

    来自:Damonare的个人博客 原文:http://blog.damonare.cn/2016/12/20/十大经典排序算法总结(javascript描述)/ 0.算法概述  0.1 算法分类 十种 ...

  8. 3min利用Python实现9种经典排序算法可视化!(附源代码)

    来源:恋习Python 本文附视频,建议收藏. 本文为你分享实现9种经典排序算法可视化的方法,3分钟即可实现. [导 读]近在某网站上看到一个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感 ...

  9. 【十大经典数据挖掘算法】k-means

    [十大经典数据挖掘算法]k-means https://mp.weixin.qq.com/s/SWlE-KBJ4mVza92nJFX1hg 作者简介: Treant  人工智能爱好者社区专栏作者 博客 ...

最新文章

  1. SpringBoot中@ControlAdvice的使用
  2. mhd格式三维图像显示_人体面骨三维有限元模型重构及碰撞分析
  3. CentOS7下安装MySQL5.7安装与配置(转)
  4. PHP新浪乐居面试题,一个朋友去新浪乐居面试时的面试题(PHP)
  5. 关于Orchard CMS
  6. 怎样让一个心浮气躁的孩子静下心学习?
  7. 单板剥皮机行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  8. win7计算机无法连接投影仪,Win7电脑如何连接投影仪?投影仪连接电脑用什么线连接?...
  9. python编写一个程序、判断用户输入的数是正数还是负数_编写一个程序,判断用户输入的数是正数还是负数。_学小易找答案...
  10. VBA操作EXCEL根据单元格数值填充颜色
  11. 【JY】浅析消能附加阻尼比
  12. 空间两直线间最短距离计算公式
  13. 新元宇宙每周连载《地球人奇游天球记》第十八回冥王遇鬼
  14. 【微信小程序入门到精通】— AppID和个性配置你学会了么?
  15. 苹果计算机如何显示错误,科普电脑打开苹果手机视频教程及Apple ID验证失败发生未知错误怎么解决...
  16. 考Java二级要不要背方法英文_考英语二级有什么技巧吗?
  17. RGB彩色空间的不同转换公式
  18. 数值型数据的表示(3.0)
  19. 水晶报表(crystal reports)--java
  20. 轻松学会linux下查看内存频率,内核函数,cpu频率

热门文章

  1. 微信添加表情提示过大怎么解决?GIF太大怎么变小?
  2. 考研英语单词-近义词分类-Second Day
  3. [BZOJ3460]Jc的宿舍
  4. 微信自定义分享、二次分享解决方案
  5. 华师大计算机基础在线作业,华东师范大学计算机作业答案
  6. Freeswitch和微信小程序对接
  7. 找工作面试会遇到哪些坑(校招篇)
  8. 【习题之局域网及组网技术篇】子网划分分配方案
  9. python计算时间差的方法_如何计算时间差,用Python算法的话
  10. proftpd java_Proftpd文件系统安装