一、什么是抖动
????????a、较为官方的解释:
????????在机械按键的触点闭合和断开时,都会产生抖动,为了保证系统能正确识别按键的开关,就必须对按键的抖动进行处理。 ????????按键的抖动对于人类来说是感觉不到的,但对单片机来说,则是完全可以感应到的,而且还是一个很“漫长”的过程,因为单片机处理的速度在“微秒”级,而按键抖动的时间至少在“毫秒”级。 ????????单片机如果在触点抖动期间检测按键的通断状态,则可能导致判断出错,即按键一次按下或释放被错误地认为是多次操作,从而引起误处理。因此,为了确保单片机对一次按键动作只作—次响应,就必须考虑如何消除按键抖动的影响。(以上均来自百度百科——按键抖动)
? ? ? ? b、较为个人的理解:
? ? ? ? 在任何时候,一切物体在分离与嵌入均会有一个过程。就比如说,小时候认为水在滴落到水面上是一滴落就与水面融为一体了,但实际上是有一定的震动时间的。所以在我们的硬件中也是一样的道理。在硬件的断开与闭合时,也会有一定的波动,而这个波动时我们不想要的,会影响我们的一下相关操作。
二、分析以及解决抖动
所以解决办法有两种:
? ? ? ? a、靠延时,跳过该阶段(不精确)。
? ? ? ? b、靠中断,检测一段时间内的电平变化(较为精确)。
三、实列代码(STM32F407ZET6)
?该代码中的引脚由实际情况而定,如果对应的引脚不同则修改后即可
#include "stm32f4xx.h" //stm32的标准头头文件
//延时函数
void delay(int number)
{
for(int i = 0 ; i < number ; i++)
{
for(int j = 0 ; j <10000 ; j++) ;
}
}
int main(void)
{
GPIO_InitTypeDef GPIOx ; //用来存放引脚配置的结构体
//注意:由于本示例中的按键引脚在PE与PA中,所以打开对应时钟 !!!
//如果你是其他引脚可打开其他引脚的时钟!!!
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE) ; // 打开对应PE组引脚的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE) ; // 打开对应PA组引脚的时钟
//配置按钮所接的对应引脚信息
GPIOx.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 ; //图中的PE2、PE3、PE4
GPIOx.GPIO_Mode = GPIO_Mode_IN ; //设置为输入
GPIOx.GPIO_PuPd = GPIO_PuPd_UP ; //设置为上拉 也可以为浮空 尽量不要为下拉 当然在这里可以无所谓
GPIO_Init(GPIOE, &GPIOx) ; //调用配置函数
GPIOx.GPIO_Pin = GPIO_Pin_0 ; //图中的PA0
GPIO_Init(GPIOA, &GPIOx) ; //调用配置函数
while(1)
{
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0x00) //判断是否按下按钮
{
delay(20) ; //跳过抖动过程 ————时间因机器而定一般在10ms左右
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0x00) //判断是否还在按下
{
//想做的事情
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0x00) ; //如果不在按下则跳出循环
}
}
//==========================================================
// 下面的三个if与上面道理向同
// 只是改变了对应的按钮与按钮所对应的引脚位置
// 所以就不再赘述了
//===========================================================
if(GPIO_ReadInputDataBit(GPIOE ,GPIO_Pin_2) == 0x00)
{
delay(20) ;
if(GPIO_ReadInputDataBit(GPIOE ,GPIO_Pin_2) == 0x00)
{
//想做的事情
while(GPIO_ReadInputDataBit(GPIOE ,GPIO_Pin_2) == 0x00) ;
}
}
if(GPIO_ReadInputDataBit(GPIOE ,GPIO_Pin_3) == 0x00)
{
delay(20) ;
if(GPIO_ReadInputDataBit(GPIOE ,GPIO_Pin_3) == 0x00)
{
//想做的事情
while(GPIO_ReadInputDataBit(GPIOE ,GPIO_Pin_3) == 0x00) ;
}
}
if(GPIO_ReadInputDataBit(GPIOE ,GPIO_Pin_4) == 0x00)
{
delay(20) ;
if(GPIO_ReadInputDataBit(GPIOE ,GPIO_Pin_4) == 0x00)
{
//想做的事情
while(GPIO_ReadInputDataBit(GPIOE ,GPIO_Pin_4) == 0x00) ;
}
}
}
}
中间还有一个中断消抖方式下一篇更新
以上是我个人对抖动的消除操作,如果有些的不好的希望大家一起指出,谢谢!!!
有消息必回
|