【裸机开发】定时器按键消抖(EPIT)

news2025/4/6 9:33:17

实际工程中,不能直接通过延时来消抖 ! 这里我们采用定时器来消抖,这也是内核处理消抖的一种方式。


目录

一、基本原理

1、延时消抖的弊端

2、定时器消抖原理

二、按键消抖实现

1、按键中断

2、定时器中断

三、附加:按键 / 定时器中断初始化 

1、按键初始化

2、定时器初始化


一、基本原理

1、延时消抖的弊端

按键按下的时候,存在抖动,延时消抖其实就是不管中间抖了多少下,全都忽略。这样的话,不确定因素太多。

  • 延时设置的过短可能无法达到消抖的效果;
  • 延时设置的过长可能会存在“第一次按键按下没反应,第二次才有反应”的情况。这就是延时过长导致第一次按下被无视。

2、定时器消抖原理

定时器消抖则是考虑了每一次的抖动。当 t1 时刻产生一次抖动时,我们启动一个定时器,定时器的周期为 10 ms(10ms已经基本覆盖了全部的抖动)

第二次检测到抖动的时候,此时按理说还没有触发中断,我们再次启动定时器,第一次和第二次用的同一个定时器,所以这次定时器启动时会重新计数。

如此往复,直到最后一次抖动出现之前,定时器在不断被刷新计数,始终没有触发过中断,即没有调用过中断服务函数。

当最后一次抖动出现时,说明抖动过程已经结束,此时会调用中断服务函数,中断服务函数里要做的就是按键按下以后的处理逻辑。

这里涉及到两个中断,分别是按键中断、定时器中断

  • 按键中断:中断触发时,启动定时器
  • 定时器中断:中断触发时,执行按键按下以后的处理逻辑

二、按键消抖实现

定时器实现按键消抖的关键在于设置两个中断服务函数。

1、按键中断

每次按键中断触发的时候(假设是下降沿触发),我们都要重新启动 EPIT1 定时器,此时定时器就会刷新计数,重新开始计时。

void key_irqhandler(void* userParams)
{
    restart_epit(33000000/100);     // 启动定时器(每隔10ms触发一次中断)
    GPIO1_ISR |= (1 << 18);
}

restart_epit 函数在最后的《定时器中断初始化》部分。在使用 restart_epit 之前,需要在 main.c 中先调用 epit_init 函数初始化定时器。

2、定时器中断

按键抖动的时候,不会触发定时器中断,只有当按键出现最后一次抖动时(按键抖动过程结束),才会触发定时器中断,此时再实现我们原本希望按键按下时该做的事。

假设我们希望按键按下时,切换LED灯的状态。

void epit_irqhandler(void* userParams)
{
    stop_epit();        // 防止处理中断时,按键再次被按下,影响现有的中断处理
    if (((GPIO1_DR >> 18) & 0x01) == 0)
    {
        switch_led(epit_stat);
        epit_stat = !epit_stat;
    }
    
    EPIT1_SR |= 1;           // 清除中断标志位
}

三、附加:按键 / 定时器中断初始化 

使用中断之前,必然需要先进行中断初始化,这里附上按键和定时器的初始化操作。

1、按键初始化

/* 按键初始化 */
void key_init()
{
    /* 1、设置IO复用为GPIO1_IO03 */
    IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B = 0x5;

    /* 2、初始化复用引脚,设置电气属性 */
    IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B = 0xF080;

    /* 3、初始化GPIO1 */
    GPIO1_GDIR &= ~(1 << 18);

    /* 4、按键中断初始化 */
    key_int_init();
}

/* 按键中断初始化 */
void key_int_init()
{
    /* 使能GIC 中 IRQ 的某个外设对应的中断 */
    GIC_EnableIRQ(99);    // 99 表示 GPIO1_IO16 ~ 31 的中断

    // GPIO1 中断使能
    GPIO1_IMR |= (1 << 18);

    // 配置 GPIO1_IO18 中断触发方式(下降沿触发)
    GPIO1_EDGE_SEL &= ~(1 << 18);
    GPIO1_ICR2 |= (3 << 4);

    // 注册中断服务函数
    register_irqhandler(99, key_irqhandler);
}

2、定时器初始化

定时器初始化时,暂时先不打开定时器,因为要触发了按键中断以后再启动定时器。

/*
 * frac: 代表分频数
 * interval: 代表计数器的初始值
 */
void epit_init(unsigned int frac, unsigned int value)
{
    if (frac < 1 )
        frac = 1;
    else if(frac > 4096)
        frac = 4096;
    
    EPIT1_CR = 0;       // CR 寄存器清零(停止定时器)
    /* EPIT1 使能、分频、时钟源初始化 */
    EPIT1_CR |=(0xE | ((frac - 1) << 4) | (0x1 << 24));

    /* 加载寄存器 */
    EPIT1_LR = value;

    /* 比较寄存器 */
    EPIT1_CMPR = 0;

    /* EPIT1 中断使能 */
    GIC_EnableIRQ(88);

    /* 注册中断服务函数 */
    register_irqhandler(88, epit_irqhandler);

    /* 计数寄存器 */
    // EPIT1_CNR = value;

    // EPIT1_CR |= 1;          // 启动定时器
}

/*
 * 停止定时器
 */
void stop_epit()
{
    EPIT1_CR &= ~(1 << 0);
}

/*
 * 启动定时器
 */ 
void restart_epit(unsigned int val)
{
    stop_epit();
    EPIT1_LR = val;
    EPIT1_CR |= 1;          // 启动定时器
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/686078.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前后端分离开发跨域问题总结

前后端分离开发跨域问题总结 一、什么是跨域访问二、解决跨域问题1、Vue前端配置代理解决跨域2、SpringBoot后端配置解决跨域2.1 跨域配置类CorsConfig&#xff08;常用&#xff09;2.2 Controller添加CrossOrigin注解2.3 添加CORS过滤器CorsFilter&#xff08;常用&#xff09…

selenium之鼠标操作

首先导入ActionChains类&#xff0c;该类可以完成鼠标移动&#xff0c;鼠标点击事件&#xff0c;键盘输入、内容菜单交互等交互行为。 from selenium.webdriver.common.action_chains import ActionChains 操作语法&#xff1a; 第一步&#xff1a;初始化ActionChains类&…

系列二、Maven下载安装配置

一、下载 链接&#xff1a;https://pan.baidu.com/s/1BvwLzAk9kRSP-daxSYe4Vw?pwdyyds 提取码&#xff1a;yyds 二、安装 第一步&#xff1a;下载安装包 第二步&#xff1a;解压至安装目录&#xff0c;例如 第三步&#xff1a;配置settings.xml&#xff08;主要配置maven本…

Open ai 开发指南:gpt接口的第一个问答机器人demo

目录 内容 Python代码 C 代码 workspace 文件 BUILD文件 Java 代码 maven文件 执行效果 内容 基于openai接口实现循环gpt问答&#xff0c;并使用一个文件将问答内容进行记录。 Python代码 # -*- coding: utf-8 -*- import openai import time from pathlib import P…

100天精通Python(可视化篇)——第93天:Pyecharts绘制多种炫酷饼图参数说明+代码实战(百分比、环形、玫瑰、内嵌、多个子图饼图)

文章目录 专栏导读1. 基础饼图add函数简单案例改变颜色 2. 百分比饼图3. 环形饼图4. 玫瑰饼图5. 内嵌环图6. 多个饼图 专栏导读 &#x1f525;&#x1f525;本文已收录于《100天精通Python从入门到就业》&#xff1a;本专栏专门针对零基础和需要进阶提升的同学所准备的一套完整…

学习前端开发,能抛弃HTML和CSS吗?

前言 前端开发里面HTML和CSS是两个非常重要的核心技术&#xff0c;它们是构建网页和应用程序界面的基础。 HTML&#xff08;超文本标记语言&#xff09;是用于描述网页结构的标记语言&#xff0c;它定义了网页的内容、布局和元素。几乎所有的网页都使用HTML来组织和呈现内容&…

5.6.3 套接字

5.6.3 套接字 我们先以示例引入套接字的基本内容&#xff0c;我们知道在邮政通信的时候我们需要在信封上写明我们的收件地址&#xff0c;比如北京市海淀区双清路30号清华大学8444号某某某收&#xff0c;这其中我们需要一个物理地址“北京市海淀区双清路30号”&#xff0c;一个…

SpringBoot 如何使用 Ehcache 作为缓存?

SpringBoot 如何使用 Ehcache 作为缓存&#xff1f; 在现代的应用程序中&#xff0c;缓存是一个非常重要的概念。缓存可以帮助我们加速应用程序的响应时间&#xff0c;减少数据库或其他服务的负载&#xff0c;并提高系统的可扩展性和容错性。Spring Framework 提供了强大的缓存…

Linux下的su指令和last指令

文章目录 1 切换用户命令&#xff08;su&#xff09;2 查看本机的所有登录记录&#xff08;last&#xff09;3 退出当前登录账户&#xff08;exit&#xff09; 1 切换用户命令&#xff08;su&#xff09; su 命令可以切换成不同的用户身份&#xff0c;命令格式如下&#xff1a…

【文本SR:轻量级:残差注意力】

A Lightweight Deep Residual Attention Network for Single Image Super Resolution &#xff08;一种用于单幅图像超分辨率的轻量级深度残差注意力网络&#xff09; 本文将稀疏编码技术应用于基于学习的文本图像超分辨率&#xff08;SR&#xff09;中&#xff0c;以提高光学…

浅析做好数据安全风险评估的重要性

一、被忽略的数据安全风险 快速问答 你知道公司内有多少数据资产吗&#xff1f; 这些数据资产中哪些数据更为重要&#xff1f; 如何保护公司数据资产&#xff0c;防止数据泄露&劫持等事件发生&#xff1f; 如果你一问三不知的话&#xff0c;也许你该好好思考数据安全这项…

数据库系统概论(三)数据库设计、数据库恢复技术、并发控制

作者的话 前言&#xff1a;总结下知识点&#xff0c;自己偶尔看一看。 一、数据库设计 数据库设计是指对于一个给定的应用环境&#xff0c;构造&#xff08;设计&#xff09;优化的数据库逻辑模式和物理结构&#xff0c;并据此建立数据库及其应用系统 1.1概述 1.1.1数据库设计…

mysql 简单定位慢查询并分析SQL执行效率

实际的日常开发工作中可能会遇到某个新功能在测试时需要很久才返回结果&#xff0c;这时就应该分析是不是慢查询导致的&#xff0c;如果确实有慢查询&#xff0c;就需要来学习怎么找到慢查询和怎么分析 SQL 执行效率&#xff1f; 定位慢 SQL 有如下两种解决方案&#xff1a; …

ClickHouse-简单了解

文章目录 前言数据库引擎数据表引擎Log 系列Integration 系列Special 系列MergeTree 系列 ClickHouse 数据类型ClickHouse 常用的函数 前言 什么是 ClickHouse&#xff1f;简单来说它是一个高性能&#xff0c;面向列的SQL数据库管理系统&#xff08;DBMS&#xff09;&#xff…

嵌入式知识分享——GDB程序调试方法说明

前 言 本指导文档适用开发环境&#xff1a; Windows开发环境&#xff1a;Windows 7 64bit、Windows 10 64bit Linux开发环境&#xff1a;Ubuntu 18.04.4 64bit 虚拟机&#xff1a;VMware15.1.0 U-Boot&#xff1a;U-Boot-2020.04 Kernel&#xff1a;Linux-5.4.70 Linux…

接口调用重放测试-业务安全测试实操(21)

接口调用重放测试。 接口调用遍历测试 接口调用重放测试 测试原理和方法 在短信、邮件调用业务或生成业务数据环节中,如短信验证码、邮件验证码、订单生成、评论提交等,对业务环节进行调用(重放) 测试。如果业务经过调用(重放) 后多次生成有效的业务或数据结果,可判断为存在…

PMP®证书增持 CSPM-2证书,哪里办理?

2023年6月起&#xff0c;持有PMP证书的朋友可以直接增持一个同等级证书CSPM-2&#xff0c;不用重新考试&#xff0c;不用重新学习&#xff0c;原PMP证书不影响正常使用&#xff0c;相当于多了一个国标项目管理领域的证书。 第一步准备资料 1、填写能力评价表 2、提供2张2寸蓝底…

在 Jetson Nano 上安装 ncnn 深度学习框架。

Install ncnn deep learning framework on a Jetson Nano. Introduction.RTTI.CMake 3.18.4.Dependencies.Benchmark.Introduction. 本页面将指导您在 Jetson Nano 上安装腾讯的 ncnn 框架。由于 ncnn 框架面向移动设备(例如 Android 手机),因此它不支持 CUDA。然而,大多数…

考虑储能的电价套利收益模型研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

C语言笔记-1 编译过程字节数

文章目录 C 基础语法注意 C 其他知识点编译过程编译器数据模型区别32/64位机器中&#xff0c;各数据类型所占位数assert() 断言&#xff08;宏&#xff09;用法总结与注意事项 C 基础语法 注意 if(a表达式) 判断的就是a的值&#xff0c;而不是判断这个赋值操作的成功与否。 查…