精华内容
下载资源
问答
  • 按键抖动 成功扫描到按键按下后,由于按键本身有着不可避免的抖动问题,一般我们会设置一段延时,延时过后再次判断按键是否按下。 这是使用逻辑分析仪捕捉的一个按键从按下到松开的过程(高电平为按下)。可以发现...
    转载请说明出处。
    

    接上文STM32–矩阵键盘的设计实现

    按键抖动

    成功扫描到按键按下后,由于按键本身有着不可避免的抖动问题,一般我们会设置一段延时,延时过后再次判断按键是否按下。
    一个按键按下到松开的逻辑过程
    这是使用逻辑分析仪捕捉的一个按键从按下到松开的过程(高电平为按下)。可以发现,在按下的一瞬间,按键的电平发生了一段无规律跳动,这个就是抖动。
    很多在学校的小伙伴可能对这种现象不以为然。当然,设置一小段时间的delay的确可以解决这个问题。但在一些公司的项目开发中,是不允许使用任何的延时函数的,这会造成主程序的阻塞(即使是几毫秒的延时阻塞也不允许),用按键触发的外部中断或者用while来判断按键松开也会对主函数造成一瞬间的阻塞(不松开按键主程序就无法继续执行那种),这也是不允许的。
    那么,不允许使用延时函数来过滤抖动信号,还有什么方法来解决这个问题呢?
    很多小伙伴应该会立马给出一个答案:定时器
    定时器的确可以完美解决这个问题。将定时器配置为每1ms触发一次定时器中断,或者每5ms、10ms触发一次,通过这个设置计时标志,只需要检测这个计时标志是否到达所需要的时间,到了之后再检测按键是否按下。期间不会对主程序造成阻塞,程序会一直循环执行。

    比如我们配置一个定时器TIM2

    static void MX_TIM2_Init(void)
    {	
      //Tout = ((10 Period)*(7200 Prescaler))/72000000 Hz(外部高速时钟) = 0.001s 	
    
      TIM_ClockConfigTypeDef sClockSourceConfig = {0};
      TIM_MasterConfigTypeDef sMasterConfig = {0};
      
      htim2.Instance = TIM2;
      htim2.Init.Prescaler = 7200-1;
      htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim2.Init.Period = 10-1;
      htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
      if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
      {
        Error_Handler();
      }
      sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
      if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
      {
        Error_Handler();
      }
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
      sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
      if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
      {
        Error_Handler();
      }
    }
    

    每1ms触发一次计数溢出中断,函数外部设置一个全局变量,在中断回调函数中每触发一次对这个值进行自增。

    uint16_t ShakeTime = 0;		//全局变量
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
    	if (htim->Instance == htim2.Instance){
    		ShakeTime++;
    		
    		//这个的作用是防止计数溢出。对这个全局变量清零的比较频繁的话可以不用这段代码
    		if (ShakeTime >= 32768){
    			ShakeTime = 0;
    		}
    	}
    }
    

    每1ms触发一次计数溢出中断,也就是说这个全局变量每1ms自增一次。

    在检测到按键按下后,把这个值清零,之后在每一轮的程序循环中,只需要检测这个全局变量是否自增到了某个数字,到了之后再对按键电平进行检测即可。

    特殊情况

    我们对这个按键抖动的问题一般只对按下时进行解决而已,但有没有想过,在松开的瞬间,按键是否也会产生抖动?

    答案是有的,不过松开按键产生抖动的情况可能会比按下按键的情况少一点,但在项目开发中,如果对产品设计严格一点的话,这也是一个不允许被忽略的问题。
    按键按下到送开的过程

    从图中我们可以看到,按键按下跟松开时都有一段时间的抖动。比如按键操作一个LED灯,结合上述提出的情况,这段松开按键的过程如果不做任何处理的话,很有可能会造成一瞬间的一亮一灭,然后又会点亮。在严格一点的项目开发中是不允许这种情况出现的。

    什么,你说松开的一瞬间即使抖动,由于LED被操作了一次,这段抖动也可以被开头的消抖操作给自动过滤掉,没问题啊?

    那么我们再看一下这个
    按键按下到松开的过程
    (没想到吧)

    这种现象我估计在按键使用过久老化之后才会出现的多(你啪啦啪啦瞎乱按一通也可能会出现),不对这个进行处理的话,产品使用久了,按键抖动的厉害,可能就会导致操作失误。

    解决办法倒也简单,检测到按键松开时再进行抖动检测就好,跟上面按下时检测抖动的步骤基本一样。

    展开全文
  • 写在前面   一般引用都写在最后,...  一开始学习单片机的时候我接触到按键的时候就知道按键抖动,记得当初按键消抖分为硬件和软件,硬件上常用于复位按键如下图 原创文章 10获赞 10访问量 1934 关注 私信
  • 按键抖动: 在机械按键的触点闭合和断开时,都会产生抖动,为了保证系统能正确识别按键的开关,就必须对按键的抖动进行处理。 按键的抖动对于人类来说是感觉不到的,但对单片机来说,则是完全可以感应到的,而且还是...

    按键抖动:

    在机械按键的触点闭合和断开时,都会产生抖动,为了保证系统能正确识别按键的开关,就必须对按键的抖动进行处理。
    按键的抖动对于人类来说是感觉不到的,但对单片机来说,则是完全可以感应到的,而且还是一个很“漫长”的过程,因为单片机处理的速度在“微秒”级,而按键抖动的时间至少在“毫秒”级。
    单片机如果在触点抖动期间检测按键的通断状态,则可能导致判断出错,即按键一次按下或释放被错误地认为是多次操作,从而引起误处理。因此,为了确保单片机对一次按键动作只作—次响应,就必须考虑如何消除按键抖动的影响。

    按键读取识别异常:根本是按键触发后电平不稳定,会有波动,端口能识别。使用代码延时,让CPU忽略电平波动
    方法:使用延时消抖

    中断模块:
    解决作业一按键的冲突(CPU循环扫描检测按键事件)

    中断模块能够帮我们去检测一些内定的一些异常事件源(中断检测内定异常,则给CPU报告异常)

    1.内定事件异常
    2.事件监听
    3.报告异常
    4.优先级:仲裁
    5.收到中断响应决策
    6.继续任务
    

    STM32内部有很多固定的(编号列表)让中断模块检测的中断源(产生中断异常的源头动作)

    GPIO模块,…
    NVIC模块,嵌套中断向量控制器,中断管理模块,NVIC管理的是全局中断,对中断优先级仲裁
    EXTI模块,32中专门管理中断的模块

    eg:usb插拔,以太网线插拔能对应扫描检测驱动
    检测引脚电平变化:外部中断,22个外部中断,0-15是连接对应每组GPIO的0-15;

    配置中断:
    0.开启EXTI相关时钟RCC_ APB2PeriphClockCmd(RCC_ APB2Periph_ SYSCFG, ENABLE);
    1.对应引脚使用GPIO_init();配置为输入模式
    2.使用SYSCFG_ EXTILineConfig() ;选择一个引脚连接对应的一个外部中断线(EXTI0-15)
    3.使用EXTI_init() ;选择模式(中断模式,事件模式(不会以中断机制处理))(上升沿,下降沿,都)
    4.配置刚开启的外部中断优先级(中断管理,优先级管理)涉及:仲裁器 配置中断优先级函数NVIC_init();
    优先级:
    抢占优先级(0-15):第一优先
    响应优先级(0-15):第二优先
    两个或者两个抢占优先级一样才考虑响应优先级

    按键延迟消抖代码实现:

    #include <stm32f4xx.h>
    
    void lightinit (void)//配置灯
    {
    	GPIO_InitTypeDef  GPIO_InitStructure;
    
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
    
    	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9 | GPIO_Pin_10;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Medium_Speed;
    	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    	GPIO_Init(GPIOF, &GPIO_InitStructure);
    
    	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14;
    	GPIO_Init(GPIOE, &GPIO_InitStructure);
    
    	GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);
    	GPIO_SetBits(GPIOE,GPIO_Pin_13 | GPIO_Pin_14);
    }
    
    void keyinit(void)//配置按键
    {
    	GPIO_InitTypeDef  GPIO_InitStructure;
    
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    	GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_3| GPIO_Pin_2;
    	GPIO_Init(GPIOE, &GPIO_InitStructure);
    }
    
    void delay(int delay_t)//设置粗延时
    {
        int i;
        while(delay_t--)
        {
            for(i=384000;i>0;i--);
        }
    }
    
    int main()
    {
    	int num=0;
    	int i;
    	int temp[4]={0};
    	
    	lightinit ();
    	keyinit();
    	
    	while(1)
    	{
    		if(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))
    		{
    			delay(1);//延时消抖
    			if(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))
    			{
    				while(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0));
    				GPIO_ToggleBits(GPIOF,GPIO_Pin_9);
    			}
    		}
    	}	
    }
    
    
    
    展开全文
  • STM32按键消抖的问题

    千次阅读 2019-03-26 22:50:17
    最近在用STM32调试按键,通过按下一个按键来切换不同的状态,如:第一次按下,OLED显示“IntelligentModel”,第二次按下显示“CommonModel”。结果写好之后,按下按键,不能一次切换过去,要按下多次才能切换,而且...

           

    最近在用STM32调试按键,通过按下一个按键来切换不同的状态,如:第一次按下,OLED显示“IntelligentModel”,第二次按下显示“CommonModel ”。结果写好之后,按下按键,不能一次切换过去,要按下多次才能切换,而且OLED的屏幕一直在闪烁这几个字符。于是我想想到了按键消抖的问题,加一个延时10ms,结果不行,当我延时到50ms时,问题解决了!当出现类似问题时,可以适当加大延时,也许就可以解决按键抖动的问题。下面是部分代码:

     while(1)
        {
            key = KEY_Scan(0);
            if(KEY0 == 0)
            {
    			delay_ms(50);
                if(KEY0 == 0)
                {
    				delay_ms(50);
                    flag = ~flag;
                    if(flag)
    				{
                        OLED_ShowStr(0, 1, (unsigned char*)"IntelligentModel");
    				}
                    else
    				{
                        OLED_ShowStr(0, 1, (unsigned char*)"CommonModel");
    				}
                }
            }
      }
    展开全文
  • stm32 利用定时器中断消除按键抖动

    千次阅读 2019-12-20 19:45:32
    button.c ...//i代表int型变量,ButtonFlag表示重按键标志,1代表重新按键,0为没有重新按键 int g_iButtonState;//g是globle代表全局变量,会在其他地方引用;i代表int型变量,ButtonState表示按键标...

     

     

    button.c

    int iButtonCount;//i代表int型变量,ButtonCount表示按键计数变量
    int iButtonFlag;//i代表int型变量,ButtonFlag表示重按键标志,1代表重新按键,0为没有重新按键
    int g_iButtonState;//g是globle代表全局变量,会在其他地方引用;i代表int型变量,ButtonState表示按键标志,1代表按下,0代表松开
    void ButtonScan(void)
    {
        if( HAL_GPIO_ReadPin(Button_GPIO_Port,Button_Pin) == GPIO_PIN_RESET )//如果引脚检测到                低电平
        {
        iButtonCount++; //按键按下,计数iButtonCount加1
            if(iButtonCount>=30) //1ms中断服务函数里运行一次,iButtonCount大于等于30,即按键已稳定按下30ms
            {
                if(iButtonFlag==0) //判断有没有重按键,1为有,0为没有
                {
                    g_iButtonState=1; //设置按键标志
                    iButtonCount=0;
                    iButtonFlag=1; //设置重按键标志
                }
                else //如果重按键,则重新计数
                iButtonCount=0;
            }
            else //如果没有稳定按下30ms,则代表没有按下按键
                g_iButtonState=0;
        }
        else //如果一直无检测到低电平,即一直无按键按下
        {
            iButtonCount=0; //清零iButtonCount
            g_iButtonState=0; //清除按键标志
            iButtonFlag=0; //清除重按键标志
        }
    }

     

    stm32fxx_it.c 文件里面 SysTick_Handler() 函数中添加 

    ButtonScan();

     

    main.c

    if(g_iButtonState == 1)
    {
        HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);//翻转LED引脚(PB12)的电平
    }

     

    展开全文
  • stm32外部中断按键消抖(电路与stm32程序),测试通过。按键抖动,抗干扰5768875687687687678
  • STM32 经典应用原理(一):按键消抖 消抖原理,就是检测,延时,检测。可以应用到扫描式操作(就是放在循环里面) /** * 函数功能: 读取按键KEY1的状态 * 输入参数:无 * 返 回 值: KEY_DOWN:按键被按下; * ...
  • STM32 HAL】按键消抖

    千次阅读 2021-08-20 17:09:08
    文章目录按键消抖(一)按键抖动(二)消抖方法(三) 两种常用的软件消抖方式(1)阻塞方式的按键消抖(2)状态机和定时器中断控制的按键消抖 按键消抖 (一)按键抖动 按键的机械特性会导致按键信号的抖动 按键...
  • STM32 软件按键消抖

    千次阅读 2019-07-24 13:04:00
     通常按键所用的开关都是机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上就稳定的接通,在断开时也不会一下子彻底断开,而是在闭合和断开的瞬间伴随了一连串的抖动,...
  • STM32 实现按键检测

    2021-10-13 14:18:12
    上图是一个按键按下的波形图,假设按键按下时连接着GND,那按键按下就是低电平,按下瞬间会有T1个周期时间是电平不稳定的状态,松开的时候会有T2个周期时间时电平不稳定的状态,这个不稳定的状态就.
  • 首先我们的按键使用在有操作系统的环境中,不能使用占用CPU的延时函数,使用操作系统的延时每20ms对按键进行一次检测。 终极目标 我们的按键需要实现的终极目标是检测按键按下、长按、松开、长松(一般没啥用)。...
  •  2、系统是阻塞的,这样系统在检测到按键按下的情况,由于机械按键抖动的原因不需要在这里等待一段时间,然后在确定按键是否正常按下。  3、按键FIFO程序在系统定时器中定时检测按键状态,确认按键按下后将状态...
  • STM32单片机按键消抖和FPGA按键消抖大全 按键去抖:由上图可以看出理想波形与实际波形之间是有区别的,实际波形在按下和释放的瞬间都有抖动的现象,抖动时间的长短和按键的机械特性有关,一般为5~10ms。通常我们手动...
  • stm32 按键 扫描 实验

    千次阅读 2020-06-12 15:55:47
    按键扫描的两种模式: 支持连续按      就是:一直按着也算有效      例如:按键检测时间为1ms 按了1s的话等同于按了十次 不支持连续按    &...
  • stm32按键 长按 短按 函数 一

    万次阅读 多人点赞 2018-11-04 00:48:27
    stm32工程中,长按和短按的代码书写,调用的读取按键状态的底层函数。封装成的按键函数代码。下面是函数的头文件,和.c文件的代码。使用定时器来扫描按键。 #define KEY_ON 1 #define KEY_OFF 0 #define KEY_...
  • 按键演示防抖动部分的主要思路是:利用系统定时器溢出间隔中断来延时防抖。这样做可以提高代码的执行效率。我们怎么很好的利用这个系统定时器来延时呢?如果只是简单在系统定时器中断中置位延时标志位,没有任何...
  • 3.STM32按键

    千次阅读 2019-02-03 17:52:02
    STM32按键 按键扫描有两种思路 支持连按:举个例子就像家里的遥控器,如果支持连按那么你按下音量键以后音量会一直改变增加。 不支持连按:还是举遥控器的例子,如果不支持连按,那么你一直按着音量键也只会增加一...
  • stm32按键实验讲解

    千次阅读 2020-07-20 22:22:48
    按键实验GPIO引脚图及相关配置按键初始化函数按键扫描函数按下按键给出对应响应 GPIO引脚图及相关配置 图1 由原理图,可以看出各按键的GPIO接口如下表。 | WK_UP | KEY0 | KEY1 | |:-----------:|:-----------:|:--...
  • Mini STM32按键输入实验

    2021-02-17 23:32:40
    DS0、DS1 和 STM32 的连接在上一章已经介绍了,在 MiniSTM32 开发板上的按键 KEY0连接在 PC5 上、KEY1 连接在 PA15 上、WK_UP 连接在 PA0 上。如图 7.2.1 所示: 图 7.2.1 按键STM32 连接原理图 这里需要...
  • 一、当按键按下的时刻,将向开发板输送低电平,可以得到以下控制图: 二、主函数控制逻辑如下: #define KEYA_SPEED1 100 //长按的时间长度(单位10mS) #define KEYA_SPEED2 10 //双击的时间长度(单位20mS) ...
  • 程序中需要使用到STM32官方库V3.5.0版本,当然如果使用其他版本可以根据要求自行更改,这里不啰嗦了,直接上程序 首先在头文件中定义按键事件和宏定义,用于表示当前的按键状态: #define MY_BUTTON_DOWN_MS 50 //...
  • STM32 状态机实现按键消抖处理源码

    千次阅读 2018-08-17 13:55:45
    key.h #ifndef __KEY_H__ #define __KEY_H__ ...stm32f10x.h" #ifdef KEY_GLOBALS #define KEY_EXT #else #define KEY_EXT extern #endif //IO定义 #define down() GPIO_ReadInputDataBit(GP...
  • stm32 按键操作

    千次阅读 2017-08-09 12:06:24
    抖动时间的长短由按键的机械特性决定,一般为5ms~10msvoid key() { static u8 flag = 1; if(flag == 1 && KEY_UP == 1) { delay_ms(10); if(KEY_UP == 1) { flag = 0; led1 =
  • 问题:被按键控制的数码管,8个led无规律高频闪烁,手靠近会闪,远离不闪。 状况:按键按下为电平上拉,引脚初始化为下拉电平。 原因:按键引脚被设置成了输出 解决:修改按键引脚为输入。 ...
  • [5]STM32按键输入实验-GPIO做输入

    千次阅读 2019-08-05 22:18:17
    STM32按键输入实验会把之前的LED灯和蜂鸣器的控制加入进来,通过按键来进行控制,是一个综合性比较高的实验。最后要实现的目的是:KEY_UP 控制蜂鸣器,按一次叫,再按一次停; KEY1 控制 DS1,按一次亮,再按一次灭...
  • STM32-MatrixKey 基于STM32F4的矩阵键盘程序, 带按键抖动检测, 带按键松手检测.
  • STM32按键程序

    千次阅读 2016-11-28 13:43:11
    u8 KEY_Scan(u8 mode) { static u8 key_up=1;//按键按松开标志 if(mode)key_up=1; //支持连按 if(key_up&...(KEY0==0||KEY1==0||KEY2==0||...//去抖动 key_up=0; if(KEY0==0)return 1; else if(KEY1==0)return
  • //ALIENTEK Mini STM32 开发板范例代码 2 //按键输入实验 //技术支持: www.openedv.com //广州市星翼电子科技有限公司 int main(void) { u8 t; delay_init(); //延时函数初始化 LED_Init(); //初始化与 LED 连接...
  • STM32按键输入实验的按键优先级和上下拉电阻的配置 最近重新看了下按键输入实验,觉得有两个地方比较有趣。 1、优先级问题,下面这个函数的优先级是KEY0>KEY1>KEY2>KEY3,也就是说假如四个按键同时按下,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,102
精华内容 440
关键字:

stm32按键去抖动