无延时去抖按键实现方法(不耗CPU)

来源:https://blog.csdn.net/ieczw/article/details/22926523

关于消除按键的机械抖动的原因:

通常的按键所用开关为机械弹性开关。由于机械触电的弹性作用,按键在闭合及断开的瞬间均伴随有一连串的抖动。键抖动会引起一次按键被误读多次。为了确保CPU对键的一次闭合仅作一次处理,必须去除抖动。 

消除抖动的方法有硬件和软件两种方法。硬件方法常用RS触发器电路。软件方法是当检测出键闭合后执行一个10ms~20ms的延时程序,再一次检测键的状态,如仍保持闭合状态,则确认真正有键按下。

这一灵感来源于定时器计数的方法,最后可以实现的效果跟咱们电脑键盘按键的效果一样!我先来介绍下基本原理吧!

采用定时器中断的方法,比如定时器中断我们设置为5ms,我们需要按键按下超过40ms时才算有按键按下,如果按键超过500ms时,我们就确定按键是连续按下的!

那么我就需要一个变量来计数!每次定时器中断时,我们就需要检测下,某个按键是否按下,如果按下,那么我们就把他对应的计数变量加1,如果这个变量等于8(8 = 40ms/5ms)时,我们就给按键的标志位置为1,如果没有按键检测到那个按键没有按下,那么我们就把他对应的按键标志位清零,且他对应的计数变量清零。下面是他的流程图!

下面具体看程序,程序里面有说的很详细,只是我的英语不是怎么样,可能写的不是很通顺,但是我确定,程序肯定是写的令大家满意的!希望大家多多指点!

  1. /* 

  2.  * @for Key Board 

  3.  * Usage : First of All ,You Must Add Your Code to Scan Your Board Keys  

  4.  *       : in Function of "unsigned char GetKeyValue(void)"; 

  5.  *       : Add function "void CheckKey(void)" into your Timer Interrupter Function; 

  6.  *       : Meanwhile , your should Can modify "TYPECOUNT" to change Count Range; 

  7.  *       : "KEYNUMBER" is a number of key; 

  8.  *       : "LIMITCOUNT_VALUE" is to confirm weather there is key click; 

  9.  *       : "MAXCOUNT_VALUE" is stand for a starting signal to repeat count; 

  10.  * Author : Chen Zhenwei 

  11.  * E-mail : ieczw@qq.com 

  12.  * Date : 2014-04-03 

  13.  * PS : My English is Poor,So There Must Be a Great Deal of Fault; 

  14.  */  

  15.   

  16. /* 

  17.  * @Get Key Value  

  18.  * Depend on Your Board,You Must Edit By yourself; 

  19.  * Return Key Value 

  20.  * 0 : No Valid Key Value 

  21.  * >0 : Valid Key Value 

  22.  */  

  23. unsigned char GetKeyValue(void)  

  24. {  

  25.     unsigned char KeyValue = 0;  

  26.     // To Add your Code to Get KeyValue  

  27.   

  28.   

  29.     return KeyValue;  

  30. }  

  31. /* 

  32.  * Define for Variable Type 

  33.  * You can Set The Type of Variable According to Your Requirement; 

  34.  */  

  35. #define TYPECOUNT   unsigned char         // 0 ~ 255  

  36. /* 

  37.  * Number of Key's Value 

  38.  */  

  39. #define KEYNUMBER   16  

  40. /* 

  41.  * Limit Value of Count 

  42.  *     _   ____    ____________________    __   _ 

  43.  * ___| |_|    |__|                    |__|  |_| |______ 

  44.  *  |   |   |   |   |   |   |   |   |   |   |   |   | 

  45.  *  1   2   3   4   5   6   7   8   9   10  11  12  13 

  46.  * You Can Set KEYNUMBER 6 ~ 9 

  47.  */  

  48. #define LIMITCOUNT_VALUE    20  

  49. /* 

  50.  * Model of Keeping Down  

  51.  *     _   ____    ________________________________________________      

  52.  * ___| |_|    |__|                                                     .... 

  53.  *  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   .... 

  54.  *  1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16 

  55.  */  

  56. #define MAXCOUNT_VALUE      50  

  57. /* 

  58.  * Declare a Global Variable for Key Count 

  59.  */  

  60. TYPECOUNT     KeyCount[KEYNUMBER];  

    镇江stm8l单片机开发,设备退换货:各采购单位单方面原因导致的单片机技术应用实训考核装置选型错误或单片机技术应用实训考核装置购买数量错误,造成单片机技术应用实训考核装置的退换货要求,将不被接受;我们将由专业技术人员为您提供有关单片机技术应用实训考核装置的技术咨询。

  61. /* 

  62.  * Usage :  

  63.  * Get Value : (KeyFilg & (1<<n))  

  64.  *              1 : on click 

  65.  *              0 : no 

  66.  */  

  67. unsigned long KeyFlag;  

  68. typedef void (*FUNC)(void * arg);  

  69. FUNC KeyFunction[KEYNUMBER]={  

  70.     // Register for Key Function  

  71.     // Key0  

  72.   

  73.     // Key1  

  74.       

  75.     // Add your Key Function  

  76. };  

  77. #define NULL    0x0000  

  78. /* 

  79.  * To Check the Key Board 

  80.  */  

  81. void CheckKey(void)  

  82. {  

  83.     unsigned char ret;  

  84.     unsigned char i = 0;  

  85.   

  86.     ret = GetKeyValue();  

  87.     for(i=0; i<KEYNUMBER; i++){  

  88.         if(i+1 == ret){  

  89.             // Count for Key Which is on Clicking   

  90.             KeyCount[i] ++;  

  91.         }  

  92.         else{  

  93.             // Clear Key Flag And Count  

  94.             KeyCount[i] = 0;  

  95.             KeyFlag &= ~(1<<i);  

  96.         }  

  97.         if(KeyCount[i] == LIMITCOUNT_VALUE){  

  98.             // Set Key Flag '1'  

  99.             KeyFlag |= (1<<i);  

  100.             // Do Your Given Key Function  

  101.             KeyFunction[i](NULL);  

  102.         }  

  103.         if(KeyCount[i] > MAXCOUNT_VALUE){  

  104.             KeyCount[i] = 0;  

  105.             KeyFlag &= ~(1<<i);  

  106.         }  

  107.     }  

  108. }  

  109. /* 

  110.  * Key Status 

  111.  */  

  112. #define KEYDOWN     1L  

  113. #define KEYUP       0L  

  114. /* 

  115.  * You Can Use GetKeyStatus(i) to Get The Key Status; 

  116.  * And In Here , You Don't Need to Care About to Clear the Key Flag, 

  117.  * Because It Will Be Auto to Clear the Key Flag. 

  118.  */  

  119. unsigned char GetKeyStatus(unsigned char KeyNumber)  

  120. {  

  121.     unsigned long Status;  

  122.       

  123.     // Get Status of KeyNumber  

  124.     Status = KeyFlag&(1<<KeyNumber);  

  125.       

  126.     // Clear Key Flag  

  127.     KeyFlag &= ~(1<<KeyNumber);  

  128.       

  129.     return (Status ? KEYDOWN : KEYUP);  

  130. }  


我们现在的Cortex-M系列单片机就无法学习寄存器了吗?显然不是。在中,硬件的操作方式就是寄存器的操作,但是其实现却是可以不同。各微处理器提供的C语言库函数包其实质就是将操作寄存器的指令进行了C语言环境下的封装。我们这里用ST官方库函数举一个示例:

生成海报
点赞 0

thePro

我还没有学会写个人说明!

相关推荐