经典按键算法使用心得
目的:记录自己学习过程
大神按键处理程序:原著
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,宏定义一下。这里只需要注意共同体的值就可以了。
经典按键算法使用心得相关推荐
- 高频交易算法研发心得--WAVT指标(Warensoft交易量趋势指标)算法及应用
高频交易算法研发心得--WAVT指标(Warensoft交易量趋势指标)算法及应用 注:WAVT指标由Warensoft(王宇)原创. 前面聊了一系列的常见应用指标,包括短线.长线的指标,并且也无耐的 ...
- 十种经典排序算法精粹(c语言版本)
下面给出这段时间我苦心研究验证过的十种经典排序算法的C语言版本,即下面的排序算法: 插入排序,shell排序,冒泡排序,快速排序,选择排序,堆排序,归并排序,桶排序,基数排序和计数排序.整理出来以作备 ...
- C语言100个经典的算法
POJ上做做ACM的题 语言的学习基础,100个经典的算法 C语言的学习要从基础开始,这里是100个经典的算法-1C语言的学习要从基础开始,这里是100个经典的算法 题目:古典问题:有一对兔子,从出生 ...
- 3分钟快速实现:9种经典排序算法的可视化
作者 | 爱笑的眼睛 来源 | 恋习Python(ID:sldata2017) 最近在某网站上看到一个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感. ▼ 6分钟演示15种排序算法 不知道 ...
- 十大经典排序算法动画与解析,看我就够了
作者 | 程序员小吴 转载自五分钟学算法(ID: CXYxiaowu) 排序算法是<数据结构与算法>中最基本的算法之一. 排序算法可以分为内部排序和外部排序.内部排序是数据记录在内存中进行 ...
- 世界上有哪些代码量很少,但很牛逼很经典的算法或项目案例?
来自公众号:五分钟学算法 今天分享四个代码量很少,但很牛逼很经典的算法或项目案例. 1.no code 项目地址: https://github.com/kelseyhightower/nocode ...
- 十大经典排序算法(建议收藏)
来自:Damonare的个人博客 原文:http://blog.damonare.cn/2016/12/20/十大经典排序算法总结(javascript描述)/ 0.算法概述 0.1 算法分类 十种 ...
- 3min利用Python实现9种经典排序算法可视化!(附源代码)
来源:恋习Python 本文附视频,建议收藏. 本文为你分享实现9种经典排序算法可视化的方法,3分钟即可实现. [导 读]近在某网站上看到一个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感 ...
- 【十大经典数据挖掘算法】k-means
[十大经典数据挖掘算法]k-means https://mp.weixin.qq.com/s/SWlE-KBJ4mVza92nJFX1hg 作者简介: Treant 人工智能爱好者社区专栏作者 博客 ...
最新文章
- SpringBoot中@ControlAdvice的使用
- mhd格式三维图像显示_人体面骨三维有限元模型重构及碰撞分析
- CentOS7下安装MySQL5.7安装与配置(转)
- PHP新浪乐居面试题,一个朋友去新浪乐居面试时的面试题(PHP)
- 关于Orchard CMS
- 怎样让一个心浮气躁的孩子静下心学习?
- 单板剥皮机行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
- win7计算机无法连接投影仪,Win7电脑如何连接投影仪?投影仪连接电脑用什么线连接?...
- python编写一个程序、判断用户输入的数是正数还是负数_编写一个程序,判断用户输入的数是正数还是负数。_学小易找答案...
- VBA操作EXCEL根据单元格数值填充颜色
- 【JY】浅析消能附加阻尼比
- 空间两直线间最短距离计算公式
- 新元宇宙每周连载《地球人奇游天球记》第十八回冥王遇鬼
- 【微信小程序入门到精通】— AppID和个性配置你学会了么?
- 苹果计算机如何显示错误,科普电脑打开苹果手机视频教程及Apple ID验证失败发生未知错误怎么解决...
- 考Java二级要不要背方法英文_考英语二级有什么技巧吗?
- RGB彩色空间的不同转换公式
- 数值型数据的表示(3.0)
- 水晶报表(crystal reports)--java
- 轻松学会linux下查看内存频率,内核函数,cpu频率