来源:https://blog.csdn.net/ieczw/article/details/22926523
关于消除按键的机械抖动的原因:
通常的按键所用开关为机械弹性开关。由于机械触电的弹性作用,按键在闭合及断开的瞬间均伴随有一连串的抖动。键抖动会引起一次按键被误读多次。为了确保CPU对键的一次闭合仅作一次处理,必须去除抖动。
消除抖动的方法有硬件和软件两种方法。硬件方法常用RS触发器电路。软件方法是当检测出键闭合后执行一个10ms~20ms的延时程序,再一次检测键的状态,如仍保持闭合状态,则确认真正有键按下。
这一灵感来源于定时器计数的方法,最后可以实现的效果跟咱们电脑键盘按键的效果一样!我先来介绍下基本原理吧!
采用定时器中断的方法,比如定时器中断我们设置为5ms,我们需要按键按下超过40ms时才算有按键按下,如果按键超过500ms时,我们就确定按键是连续按下的!
那么我就需要一个变量来计数!每次定时器中断时,我们就需要检测下,某个按键是否按下,如果按下,那么我们就把他对应的计数变量加1,如果这个变量等于8(8 = 40ms/5ms)时,我们就给按键的标志位置为1,如果没有按键检测到那个按键没有按下,那么我们就把他对应的按键标志位清零,且他对应的计数变量清零。下面是他的流程图!
下面具体看程序,程序里面有说的很详细,只是我的英语不是怎么样,可能写的不是很通顺,但是我确定,程序肯定是写的令大家满意的!希望大家多多指点!
-
/*
-
* @for Key Board
-
* Usage : First of All ,You Must Add Your Code to Scan Your Board Keys
-
* : in Function of "unsigned char GetKeyValue(void)";
-
* : Add function "void CheckKey(void)" into your Timer Interrupter Function;
-
* : Meanwhile , your should Can modify "TYPECOUNT" to change Count Range;
-
* : "KEYNUMBER" is a number of key;
-
* : "LIMITCOUNT_VALUE" is to confirm weather there is key click;
-
* : "MAXCOUNT_VALUE" is stand for a starting signal to repeat count;
-
* Author : Chen Zhenwei
-
* E-mail : ieczw@qq.com
-
* Date : 2014-04-03
-
* PS : My English is Poor,So There Must Be a Great Deal of Fault;
-
*/
-
-
/*
-
* @Get Key Value
-
* Depend on Your Board,You Must Edit By yourself;
-
* Return Key Value
-
* 0 : No Valid Key Value
-
* >0 : Valid Key Value
-
*/
-
unsigned char GetKeyValue(void)
-
{
-
unsigned char KeyValue = 0;
-
// To Add your Code to Get KeyValue
-
-
-
return KeyValue;
-
}
-
/*
-
* Define for Variable Type
-
* You can Set The Type of Variable According to Your Requirement;
-
*/
-
#define TYPECOUNT unsigned char // 0 ~ 255
-
/*
-
* Number of Key's Value
-
*/
-
#define KEYNUMBER 16
-
/*
-
* Limit Value of Count
-
* _ ____ ____________________ __ _
-
* ___| |_| |__| |__| |_| |______
-
* | | | | | | | | | | | | |
-
* 1 2 3 4 5 6 7 8 9 10 11 12 13
-
* You Can Set KEYNUMBER 6 ~ 9
-
*/
-
#define LIMITCOUNT_VALUE 20
-
/*
-
* Model of Keeping Down
-
* _ ____ ________________________________________________
-
* ___| |_| |__| ....
-
* | | | | | | | | | | | | | | | | ....
-
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
-
*/
-
#define MAXCOUNT_VALUE 50
-
/*
-
* Declare a Global Variable for Key Count
-
*/
-
TYPECOUNT KeyCount[KEYNUMBER];
镇江stm8l单片机开发,设备退换货:各采购单位单方面原因导致的单片机技术应用实训考核装置选型错误或单片机技术应用实训考核装置购买数量错误,造成单片机技术应用实训考核装置的退换货要求,将不被接受;我们将由专业技术人员为您提供有关单片机技术应用实训考核装置的技术咨询。
-
/*
-
* Usage :
-
* Get Value : (KeyFilg & (1<<n))
-
* 1 : on click
-
* 0 : no
-
*/
-
unsigned long KeyFlag;
-
typedef void (*FUNC)(void * arg);
-
FUNC KeyFunction[KEYNUMBER]={
-
// Register for Key Function
-
// Key0
-
-
// Key1
-
-
// Add your Key Function
-
};
-
#define NULL 0x0000
-
/*
-
* To Check the Key Board
-
*/
-
void CheckKey(void)
-
{
-
unsigned char ret;
-
unsigned char i = 0;
-
-
ret = GetKeyValue();
-
for(i=0; i<KEYNUMBER; i++){
-
if(i+1 == ret){
-
// Count for Key Which is on Clicking
-
KeyCount[i] ++;
-
}
-
else{
-
// Clear Key Flag And Count
-
KeyCount[i] = 0;
-
KeyFlag &= ~(1<<i);
-
}
-
if(KeyCount[i] == LIMITCOUNT_VALUE){
-
// Set Key Flag '1'
-
KeyFlag |= (1<<i);
-
// Do Your Given Key Function
-
KeyFunction[i](NULL);
-
}
-
if(KeyCount[i] > MAXCOUNT_VALUE){
-
KeyCount[i] = 0;
-
KeyFlag &= ~(1<<i);
-
}
-
}
-
}
-
/*
-
* Key Status
-
*/
-
#define KEYDOWN 1L
-
#define KEYUP 0L
-
/*
-
* You Can Use GetKeyStatus(i) to Get The Key Status;
-
* And In Here , You Don't Need to Care About to Clear the Key Flag,
-
* Because It Will Be Auto to Clear the Key Flag.
-
*/
-
unsigned char GetKeyStatus(unsigned char KeyNumber)
-
{
-
unsigned long Status;
-
-
// Get Status of KeyNumber
-
Status = KeyFlag&(1<<KeyNumber);
-
-
// Clear Key Flag
-
KeyFlag &= ~(1<<KeyNumber);
-
-
return (Status ? KEYDOWN : KEYUP);
-
}
我们现在的Cortex-M系列单片机就无法学习寄存器了吗?显然不是。在中,硬件的操作方式就是寄存器的操作,但是其实现却是可以不同。各微处理器提供的C语言库函数包其实质就是将操作寄存器的指令进行了C语言环境下的封装。我们这里用ST官方库函数举一个示例: