12. 定时器按键消抖

2023-11-11 18:36
文章标签 定时器 按键 消抖

本文主要是介绍12. 定时器按键消抖,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

12. 定时器按键消抖

  • 定时器按键消抖简介
  • 定时器消抖配置步骤
  • 程序编写
    • bsp_keyfilter.h
    • bsp_keyfilter.c
    • main

定时器按键消抖简介

使用延时函数消抖会浪费 CPU 性能,因为延时函数就是空跑。如果按键是使用中断的方式实现的,就更不能在中断服务函数中使用延时函数,因为中断服务函数最基本的要求就是快进快出。 所以可以使用定时器设置好时间,就可以去跑其他的进程,当时间到了,就会触发中断,然后在中断函数中做相应的处理。
在这里插入图片描述
需要在图中t1 ~ t3 这个时间段消抖。设置按键为下降沿触发,因此会在t1、t2和t3这3个时刻会触发按键中断,每次进入中断处理函数都会重新开启定时器中断。但是t1 ~ t2 和 t2 ~ t3 这两个时间段是小于设定的定时器时间,所以虽然 t1 开启了定时器,但是定时器定时器时间还没到,就重置了定时器,最终只有t3时刻开启的定时器能完整的完成整个定时器周期并触发中断

定时器消抖配置步骤

  1. 配置按键 IO 中断
    配置按键所使用的 IO,因为要使用到中断驱动按键,所以要配置 IO 的中断模式
  2. 初始化消抖用的定时器
  3. 编写中断处理函数
    需要两个中断处理函数:按键对应的 GPIO 中断处理函数和 EPIT1 定时器的中断处理函数。按键中断处理函数主要是开启定时器。

程序编写

bsp_keyfilter.h

#pragma once
void filterkey_init();
void filtertimer_init(unsigned int value);
void filtertimer_stop();
void filtertimer_restart(unsigned int value);
void filtertimer_irqhandler();
void gpio1_16_31_irqhandler();

bsp_keyfilter.c

#include "bsp_key.h"
#include "bsp_gpio.h"
#include "bsp_int.h"
#include "bsp_beep.h"
#include "bsp_keyfilter.h"void fileterkey_init()
{gpio_pin_config_t key_config;// 1. 初始化 IOIOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF080);// 2. 初始化 GPIO 为中断key_config.direction = kGPIO_DigitalInput;key_config.interruptMode = kGPIO_IntFallingEdge;key_config.outputLogic = 1;gpio_init(GPIO1, 18, &key_config);// 使能 GPIO 中断,并且注册中断处理函数GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);system_register_irqhandler(GPIO1_Combined_16_31_IRQn,(system_irq_handler_t)gpio1_16_31_irqhandler,NULL);gpio_enableint(GPIO1, 18);// 使能GPIO1_IO18中断filetertimer_init(66000000/100);// 初始化定时器10ms
}/** @description		: 初始化用于消抖的定时器,默认关闭定时器* @param - value	: 定时器EPIT计数值* @return 			: 无*/
void filtertimer_init(unsigned int value)
{EPIT1->CR = 0;	//先清零/** CR寄存器:* bit25:24 01 时钟源选择Peripheral clock=66MHz* bit15:4  0  1分频* bit3:	1  当计数器到0的话从LR重新加载数值* bit2:	1  比较中断使能* bit1:    1  初始计数值来源于LR寄存器值* bit0:    0  先关闭EPIT1*/EPIT1->CR = (1<<24 | 1<<3 | 1<<2 | 1<<1);/* 计数值    */EPIT1->LR = value;/* 比较寄存器,当计数器值和此寄存器值相等的话就会产生中断 */EPIT1->CMPR	= 0;	GIC_EnableIRQ(EPIT1_IRQn);	/* 使能GIC中对应的中断 *//* 注册中断服务函数		    */system_register_irqhandler(EPIT1_IRQn, (system_irq_handler_t)filtertimer_irqhandler, NULL);	
}void filtertimer_stop(void)
{EPIT1->CR &= ~(1<<0);	/* 关闭定时器 */
}/** @description		: 重启定时器* @param - value	: 定时器EPIT计数值* @return 			: 无*/
void filtertimer_restart(unsigned int value)
{EPIT1->CR &= ~(1<<0);	/* 先关闭定时器 */EPIT1->LR = value;		/* 计数值 			*/EPIT1->CR |= (1<<0);	/* 打开定时器 		*/
}void filtertimer_irqhandler(void)
{ static unsigned char state = OFF;if(EPIT1->SR & (1<<0)) 					// 判断比较事件是否发生{filtertimer_stop();					// 关闭定时器if(gpio_pinread(GPIO1, 18) == 0)	// KEY0 {state = !state;beep_switch(state);				// 反转蜂鸣器 }}EPIT1->SR |= 1<<0; 						// 清除中断标志位 	
}void gpio1_16_31_irqhandler(void)
{ // 开启定时器filtertimer_restart(66000000/100);// 清除中断标志位gpio_clearintflags(GPIO1, 18);
}

main

int main(void)
{unsigned char state = OFF;int_init(); 				// 初始化中断(一定要最先调用)imx6u_clkinit();			clk_enable();				led_init();					beep_init();				filterkey_init();			while(1)			{	state = !state;led_switch(LED0, state);delay(500);}return 0;
}

这篇关于12. 定时器按键消抖的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/392062

相关文章

【Qt】定时器事件

定时器事件 在之前学习QTimer中实现了定时器的功能,而在QTimer背后是QTimerEvent定时器事件进行支撑的。在QObject中提供了一个timeEvent这个函数。 startTimer启动定时器killTimer关闭定时器 Qt 中在进⾏窗⼝程序的处理过程中,经常要周期性的执⾏某些操作,或者制作⼀些动画效果,使⽤定 时器就可以实现。所谓定时器就是在间隔⼀定时间后,去执⾏某⼀

独立按键单击检测(延时消抖+定时器扫描)

目录 独立按键简介 按键抖动 模块接线 延时消抖 Key.h Key.c 定时器扫描按键代码 Key.h Key.c main.c 思考  MultiButton按键驱动 独立按键简介 ​ 轻触按键相当于一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通与断开。  ​ 按键抖动 由于按键内部使用的是机

【JavaScript】在循环体中了解定时器工作机制

for (var i = 0; i < 5; i++) {setTimeout(function() {console.log(i);}, 1000);}console.log(i);   如果我们约定,用箭头表示其前后的两次输出之间有 1 秒的时间间隔,而逗号表示其前后的两次输出之间的时间间隔可以忽略,代码实际运行的结果该如何描述?会有下面两种答案: A. :5 -> 5 -> 5 ->

3.门锁_STM32_矩阵按键设备实现

概述 需求来源: 门锁肯定是要输入密码,这个门锁提供了两个输入密码的方式:一个是蓝牙输入,一个是按键输入。对于按键输入,采用矩阵按键来实现。矩阵按键是为了模拟触摸屏的按键输入,后续如果项目结束前还有时间就更新为触摸屏按键输入。 矩阵按键开发整体思路: 由于矩阵按键就是GPIO的控制,所以不进行芯片和设备的分层编写,控制写在同一个文件中,最终向应用层提供一个接口。 代码层级关系:

WebAPI (一)DOM树、DOM对象,操作元素样式(style className,classList)。表单元素属性。自定义属性。间歇函数定时器

文章目录 Web API基本认知一、 变量声明二、 DOM1. DOM 树2. DOM对象3. 获取DOM对象(1)、选择匹配的第一个元素(2)、选择匹配多个元素 三、 操作元素1. 操作元素内容2. 操作元素属性(1)、常用属性(href之类的)(2)、通过style属性操作CSS(3)、通过类名(className)操作CSS(4)、通过classList操作控制CSS(5)、操作表单

深入理解C语言中的POSIX定时器

引言 在Unix和类Unix系统中,定时器是一种常见的机制,用于在特定时间间隔后执行某些操作。POSIX定时器因其灵活性和功能丰富而被广泛采用。本文将深入探讨POSIX定时器的工作原理、内部机制、使用方法及其在实际开发中的应用。 POSIX定时器基础 POSIX定时器是一种高级定时器接口,它允许用户创建定时器并指定定时器到期时的动作。POSIX定时器支持以下特性: 信号通知:定时器到

Android AnalogClock TextClock DigitalClock Chronometer 时钟 定时器

AnalogClock 相关属性:  android:dial="@drawable/img1" //表盘android:hand_hour="@drawable/alert_dialog_icon" //时针android:hand_minute="@drawable/alert_dialog_icon" //分针 TextClock 相关属性: android:f

STM32F4按键状态机--单击、双击、长按

STM32F4按键状态机--单击、双击、长按 一、状态机的三要素二、使用状态机原因2.1资源占用方面2.2 执行效率方面:2.3 按键抖动方面: 三、状态机实现3.1 状态机分析3.1 程序实现 百度解析的状态机概念如下 状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。有限状态机简写为FSM(

JS触发按键事件

<script type="text/javascript" language=JavaScript charset="UTF-8">document.onkeydown=function(event){var e = event || window.event || arguments.callee.caller.arguments[0];if(e && e.keyCode==27){ // 按