按键消抖

正点原子FPGA按键消抖笔记

自闭症网瘾萝莉.ら 提交于 2020-03-12 07:50:46
出自正点原子《开拓者FPGA开发指南V1.3》第九章按键控制蜂鸣器实验 寄存器:key_flag 按键数据有效信号 寄存器:key_value 按键消抖后的数据 寄存器:delay_cnt 延时计数 系统时钟:50MHz 思路: 一直检测按键状态,一旦按键状态发现变化,给delay_cnt计数器赋初值100_0000,也就是20ms计数。按键状态不发生改变,那么计数器开始递减计数,直到计数器减到1时,说明按键状态稳定保持20ms,此时给出一个时钟周期的按键有效通知信号key_flag,并将按键数据寄存器key_value锁存输出。 Verilog硬件语言和C语言的不同之一,C语言是顺序语言,如果给出一条赋值语句,左值会立刻变化,而Verilog语言的一条幅值语句需要一个时钟周期改变幅值,也就是一个时钟周期内,所有寄存器的值都不会被改变,只有下一个时钟信号到来,寄存器的值才会被改变。 module key_debounce( input sys_clk, input sys_rst_n, input key, output reg key_value, output reg key_flag ); reg [31:0] delay_cnt; reg key_reg; always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys

掌据这几个设计思想,从单片机小白立马升级为单片机工程师

谁说我不能喝 提交于 2020-02-26 23:30:51
分层思想 分层的思想,并不是什么神秘的东西,事实上很多做项目的工程师本身自己也会在用。看了不少帖子都发现没有提及这个东西,然而分层结构确是很有用的东西,参透后会有一种恍然大悟的感觉。如果说我不懂LCD怎么驱动,那好办,看一下datasheet,参考一下阿别人的程序,很快就可以做出来。但是如果不懂程序设计的思想的话,会给你做项目的过程中带来很多很多的困惑。 参考了市面上各种各样的嵌入式书籍,MCS-51,AVR ,ARM 等都有看过,但是没有发现有哪本是介绍设计思想的,就算有也是凤毛麟角。写程序不难,但是程序怎么样才能写的好,写的快,那是需要点经验积累的。结构化模块化的程序设计的思想,使最基本的要求。然而这么将这个抽象的概念运用到工程实践当中恩?那需要在做项目的过程中经历磨难,将一些东西总结出来,抽象升华为理论,对经验的积累和技术的传播都大有裨益。所以在下出来献丑一下,总结一些东西。 就我个人的经验而谈,有两个设计思想是非常重要的。 一个就是 “时间片轮的设计思想” ,这个对实际中解决多任务问题非常有用,通常可以用这个东西来判断一个人是单片机学习者,还是一个单片机工程师。这个必须掌握。(下文将介绍)。 第二个就是 “分层屏蔽的设计思想” 即分层思想。下面用扫描键盘程序例子作为引子,引出今天说的东西。 问题的提出 单片机学习板一般为了简单起见,将按键分配的很好,例如整个 4*4

基于状态转移的独立按键程序设计

最后都变了- 提交于 2020-01-07 11:28:19
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 从网上搜集而来,出处不可考。感谢原作者。 对于按键处理讲得很透彻。 从这一章开始,我们步入按键程序设计的殿堂。在基于单片机为核心构成的应用系统中,用户输入是必不可少的一部分。输入可以分很多种情况,譬如有的系统支持PS2键盘的接口,有的系统输入是基于编码器,有的系统输入是基于串口或者USB或者其它输入通道等等。在各种输入途径中,更常见的是,基于单个按键或者由单个键盘按照一定排列构成的矩阵键盘(行列键盘)。我们这一篇章主要讨论的对象就是基于单个按键的程序设计,以及矩阵键盘的程序编写。 ◎按键检测的原理 常见的独立按键的外观如下,相信大家并不陌生,各种常见的开发板学习板上随处可以看到他们的身影。 总共有四个引脚,一般情况下,处于同一边的两个引脚内部是连接在一起的,如何分辨两个引脚是否处在同一边呢?可以将按键翻转过来,处于同一边的两个引脚,有一条突起的线将他们连接一起,以标示它们俩是相连的。如果无法观察得到,用数字万用表的二极管挡位检测一下即可。搞清楚这点非常重要,对于我们画PCB的时候的封装很有益。 它们和我们的单片机系统的I/O口连接一般如下: 对于单片机I/O内部有上拉电阻的微控制器而言,还可以省掉外部的那个上拉电阻。简单分析一下按键检测的原理。当按键没有按下的时候,单片机I/O通过上拉电阻R接到VCC

ZYNQ学习之按键消抖

可紊 提交于 2019-12-17 05:49:50
参考链接:米联客教程: https://blog.csdn.net/jinry001/article/details/9969498 按键消抖子程序: module key # ( parameter CLK_FREQ = 100000000 ) ( input clk_i, input key_i, output key_cap ); //10ms,100MHz时钟对应计数值,1/100_000_000*val=10*10^-3 parameter CNT_10MS = (CLK_FREQ/100 - 1'b1); parameter KEY_S0 = 2'd0; parameter KEY_S1 = 2'd1; parameter KEY_S2 = 2'd2; parameter KEY_S3 = 2'd3; reg [24:0] cnt10ms = 25'd0; reg [1:0] key_s = 2'b0; reg [1:0] key_s_r = 2'b0; wire en_10ms ; //产生10ms计数时钟 assign en_10ms = (cnt10ms == CNT_10MS); //按键按下的检测逻辑, assign key_cap = (key_s==KEY_S2)&&(key_s_r==KEY_S1); always @(posedge clk_i

51单片机入门教程(4)——按键控制

岁酱吖の 提交于 2019-12-04 17:54:21
51单片机入门教程(4)——按键控制 一、独立按键 1.1 独立按键的原理 1.2 独立按键的仿真电路 1.3 按键消抖 二、矩阵键盘 2.1 矩阵键盘原理 2.2 矩阵键盘扫描原理 2.3 矩阵键盘扫描程序 单片机与外界的信息交互主要有两大类,输入信息和输出信息。 之前的博客介绍了通过单片机控制LED灯和数码管向外界输出信息,该教程介绍单片机常用的输入设备——独立按键和矩阵键盘。 一、独立按键 1.1 独立按键的原理 独立按键一共有四个针脚,两个短针脚之间默认不导通,两个长针脚之间默认导通。实物图如图: 1.2 独立按键的仿真电路 在Proteus中对按键进行了简化,只有两个接线针脚。按键的一端接到单片机的IO口上,另一端与GND连接。当按键按下时,单片机的IO口与GND连接,端口电平被拉低。因此通过读取端口电平即可获知按键状态。 仿真电路如图: 1.3 按键消抖 关于 按键抖动 : 通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。即单片机在按键被按下的一瞬间检测到的信号是 很多次的忽高忽低的电平信号 ,如图: 这种信号是不稳定的。因此,我们需要使用按键消抖的算法使单片机获取到正常稳定的信号。 为了避免在最不稳定的时候采集信号,常用的操作是延时,即当检测到低电平输入时,延时若干时间

进阶项目(11) 矩阵键盘程序设计讲解

一世执手 提交于 2019-11-29 15:39:06
写在前面的话 在使用按键的时候,如果按键不多的话,我们可以直接让按键与FPGA相连接,但是如果按键比较多的时候,如果还继续使用直接让按键与FPGA相连接的话,会大量增加FPGA端口的消耗,为了减少FPGA端口的消耗,我们可以把按键设计成矩阵的形式。接下来,梦翼师兄将和大家一起学习扫描键盘的电路原理以及驱动方式。 项目需求 设计 4*4 矩阵键盘 按键 扫描模块 , 正确解析按键值 。 矩阵键盘的原理 由上图可以知道,矩阵键盘的行row(行)与col(列)的交点,都是通过一个按键相连接。传统的一个按键一个端口的方法,若要实现16个按键,则需要16个端口,而现在这个矩阵键盘的设计,16个按键,仅仅需要8个端口,如果使用16个端口来做矩阵键盘的话,可以识别64个按键,端口的利用率远远比传统的设计高好多,所以如果需要的按键少的话,可以选择传统的按键设计,如果需要的按键比较多的话,可以采用这种矩阵键盘的设计。而我们现在就以扫描法为例来介绍矩阵键盘的工作原理。 首先col(列)是FPGA给矩阵键盘输出的扫描信号,而row(行)是矩阵键盘反馈给FPGA的输入信号,用于检测哪一个按键被按下,示意图如下: 如上图所示,FPGA给出扫描信号COL[3:0],COL = 4’b0111,等下一个时钟周期COL = 4’b1011,再等下一个时钟周期COL = 4’b1101,再等下一个时钟周期COL =

最好的按键扫描和消抖方法,适用于复合、长按、按下或抬起响应按键

我只是一个虾纸丫 提交于 2019-11-26 03:38:34
刚参加工作的时候,看了一些同事采用的按键扫描和消抖方法,对比学校里和网上查到的按键处理,发现觉得不尽善尽美,有以下几点: 1. 消抖复杂,效率低。有人直接在电平判断后使用delay()函数,进行消抖,耽误时间;有人在按键电平中断中进行消抖和处理,导致其他的服务反应慢,不适合做实时系统; 2. 许多功能在不同界面下是不同的,把按键处理在中断进行,导致分支很多,业务流不清晰。 3. 特殊功能按键的处理麻烦。在需要长按作为特殊按键、复合按键响应、复合按键长按响应的时候,需要增加很多的标志位,反复使用if..else判断,流程看起来很乱。 4. 跟硬件设计或业务关联很深,不便于移植和修改,导致每个项目都要更改一次。 想了很久之后,我结合PC的键盘处理方法,编写了自己的按键函数,经过几次修改,定了下来。这十多年来,无论更换单片机,还是采用端口/扫描方式,还是采用前后台或操作系统,都一直在用,方便移植,也比较清晰。 / **** / 它主要有几个特点: 按键扫描和取值分开。 在中断中,每隔10ms调用keyScan()进行按键扫描,多次扫描进行消抖,获得的按键值不返回,作为消息放到全局变量中; 在业务层需要判断的地方使用getKeyValue()获取当前的键值,进行处理。 每一个按键,都有单独的标志位和计时变量。 消抖计时: 每调用一次10ms中断,如果按键按下,gucKeyOkTimer