OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10696|回复: 7

小梅哥和你一起深入学习FPGA之独立按键检测

[复制链接]

40

主题

177

帖子

0

精华

高级会员

Rank: 4

积分
921
金钱
921
注册时间
2013-10-23
在线时间
94 小时
发表于 2014-10-23 21:22:36 | 显示全部楼层 |阅读模式

几乎没有哪一个系统没有输入输出设备,大到显示器,小到led灯,轻触按键。作为一个系统,要想稳定的工作,输入输出设备的性能占了很重要的角色。本实验,小梅哥就通过一个独立按键的检测实验,来正式步入基本外设驱动开发的大门。

 

一、        实验目的

实现4个独立按键的抖动检测实验,并通过4个独立按键控制4led灯亮灭状态的翻转。

二、        实验原理

实际系统中常用的按键大部分都是轻触式按键,如图2-1所示。该按键内部由一个弹簧片和两个固定触点组成,当弹簧片被按下,则两个固定触点接通,按键闭合。弹簧片松开,两个触点断开,按键也就断开了。根据这种按键的机械特性,在按键按下时,会先有一段时间的不稳定期,在这期间,两个触点时而接通,时而断开,我们称之为抖动,当按键大约按下20ms后,两个触点才能处于稳定的闭合状态,按键松开时和闭合时情况类似。而我们的FPGA工作在很高的频率,按键接通或断开时任何一点小的抖动都能轻易的捕捉到,如果不加区分的将每一次闭合或断开都当做一次按键事件,那么势必一次按键动作会被FPGA识别为很多次按键操作,从而导致系统工作稳定性下降。

2-1 轻触按键实物图

一次按键动作的大致波形如下图所示:

因此,我们所需要做的工作,就是滤除按键按下和释放时各存在的20ms的不稳定波形

 

三、        硬件设计

独立按键属于一种输入设备,其与FPGA连接的IO口被接上了10K的上拉电阻,在按键没有按下时,FPGA会检测到高电平;当按键按下后,FPGAIO口上则将呈现低电平。因此,按键检测的实质就是读取FPGAIO上的电平。

3-1 独立按键典型电路

 

四、        架构设计

本实验由总共四个模块组成,分别为LED驱动模块、独立按键检测模块、控制模块和顶层模块,其架构如下:


4-1 led实验模块组织结构图

由图可知本实验有n个输出端口,对应驱动了nled灯。n+2个输入端口,对应了n个按键输入和一个时钟输入以及一个复位输入。详细端口名及其意义如下

端口说明

端口名

端口功能或意义

Rst_n

全局复位

Led

LED驱动输出Pin,驱动控制LED灯亮灭

Key_in

按键输入端口

Clk

系统时钟输入端口

4-1 独立按键检测实验端口说明

 

因为存在模块间的连接,因此有部分内部信号,下表为内部信号的名称和功能说明

内部信号说明

内部信号名

内部信号功能或意义

Sig

LED控制输入,LED输出状态将于本信号的各位状态一致

Key_Value

按键检测结果输出

Key_Flag

按键检测成功标志信号

4-2 独立按键检测实验内部信号说明

 

 

一、        代码组织方式

         本实验中,按键检测部分用到了状态机,该状态机包括两个状态:按下消抖状态和释放消抖状态,详细内容将在关键代码中进行讲解,此处不做细致讨论。

实验中还设计了一个控制器,该控制器主要进行按键事件与LED灯状态的控制,通过读取按键值,并根据按键信息翻转对应的LED的亮灭状态。这部分内容由于篇幅原因,不在文档中写出,请直接参看附件源代码即可。

LED的驱动采用实验一的模块,因此这里不进行过多的分析介绍。

 

二、        关键代码解读

以下为按键电平变化的检测代码,通过存储前一次时钟上升沿时的按键状态和当前时钟上升沿时的按键状态,并比较两次状态是否相同,即可获知是否有按键按下。

/*-------存储按键状态的上一个状态---------------*/	
	always @ (posedge Clk or negedge Rst_n)
	begin
		if(!Rst_n)
			begin
				key_tmp <= 'd0;
				key_tmp1 <= 'd0;	
			end
		else
			begin
				key_tmp <= Key_in;
				key_tmp1 <= key_tmp;		
			end	
	end

/*---通过比较按键上一个状态和此时刻状态来获知按键状态是否改变---*/	
	assign level_change = (key_tmp == key_tmp1)?1'b0:1'b1;
					[/mw_shl_code]
	
    以下为按键抖动检测的代码,采用状态机的方式编写,总共有两个状态,按下消抖为状态0,释放消抖为状态1。具体的消抖流程代码中的注释已经写的比较清楚,但如果全部用文字解释出来还是有一定的复杂性。这也是实地讲解和网上文档的一点点差距吧,希望我后期的视频里面能讲清楚。其实抖动消除的核心思路就是对按键状态的变化进行计时,若两次电平变化之间时间小于20ms,则视为抖动,若低电平稳定时间超过20ms,则表明检测到了稳定的按键状态。释放时的消抖过程与按下时的消抖过程类似。
always @ (posedge Clk or negedge Rst_n)
	if(!Rst_n)
	begin	
		cnt1 <= 20'd0;
		state <= 1'b0;
		Key_Value <= 4'b0000;
		Key_Flag <= 1'b0;
	end
	else
	begin
		case(state)
		0:	/*按下检测*/
			//没有电平变化,且按键输入状态不全为1
			if(!level_change & key_tmp1 != {KEY_WIDTH{1'b1}})
				begin
					if(cnt1 == cnt1_TOP)/*计数满消抖所需时间*/
						begin
							Key_Value <= ~Key_in;
							Key_Flag <= 1;
							cnt1 <= 0;
							state <= 1;
						end
					else
						cnt1 <= cnt1 + 1'b1;
				end
			else
				begin
					cnt1 <= 0;
					Key_Flag <= 0;
					state <= 0;
				end
		
		1:/*释放检测*/
			begin
				Key_Flag <= 0;
				/*没有电平变化,且按键输入状态全为1*/
				if(!level_change & key_tmp1 == {KEY_WIDTH{1'b1}})
					begin
						if(cnt1 == cnt1_TOP)/*计数满消抖所需时间*/
							begin
								cnt1 <= 0;
								state <= 0;
							end
						else
							cnt1 <= cnt1 + 1'b1;
					end
				else
					begin
						cnt1 <= 0;
						state <= 1;
					end						
			end
		endcase	
	end[/mw_shl_code]
	


一、        测试平台设计


本实验主要对按键检测的结果进行观察和分析,通过仿真,验证设计的正确性和合理性。按键消抖模块的testbench的代码如下:

`timescale 1ns/1ns

module normal_keys_detect_tb;

	reg Clk;
	reg Rst_n;
	reg [3:0]Key_in;
	
	wire Key_Flag;
	wire [3:0]Key_Value;
	
	normal_keys_detect 
	#(
		.KEY_WIDTH(4)
	)
	normal_keys_detect_inst1(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.Key_in(Key_in),
		.Key_Flag(Key_Flag),
		.Key_Value(Key_Value)
	);
	
	initial begin
		Clk = 1;
		Rst_n = 0;
		Key_in = 4'b1111;
		#100;
		Rst_n = 1;
		press_key(0);
		#30000000;
		press_key(1);
		#30000000;
		press_key(2);
		#30000000;
		press_key(3);
		#30000000;
		$stop;
	end
	
	always #10 Clk = ~Clk;
	
	task press_key;
		input [1:0]Key;
		begin
			Key_in = 4'b1111;
			
			/*按下抖动*/
			#100 Key_in[Key] = 0;
			#200 Key_in[Key] = 1;
			#300 Key_in[Key] = 0;
			#400 Key_in[Key] = 1;
			#500 Key_in[Key] = 0;
			#600 Key_in[Key] = 1;
			#700 Key_in[Key] = 0;
			#800 Key_in[Key] = 1;
			#900 Key_in[Key] = 0;
			
			/*稳定期*/
			#22000000;
			
			/*释放抖动*/
			#100 Key_in[Key] = 1;
			#200 Key_in[Key] = 0;
			#300 Key_in[Key] = 1;
			#400 Key_in[Key] = 0;
			#500 Key_in[Key] = 1;
			#600 Key_in[Key] = 0;
			#700 Key_in[Key] = 1;
			#800 Key_in[Key] = 0;
			#900 Key_in[Key] = 1;
		end
	endtask

endmodule [/mw_shl_code]
		


testben中使用了一个任务(task),该任务模拟按键抖动的过程,给按键按下和释放时增加抖动,调用时只需要输入需要按下的按键编号,该任务便可自动完成按下抖动、稳定、松开抖动的过程。


整个工程的testbench与消抖模块的testbench一样,只需要在例化部分将消抖模块替换为顶层模块,同时将每个按键的任务由一次调用该为两次调用即可,详细请参考附件代码。


一、        仿真分析


由上图仿真结果可知,当有按键按下时,需要较长一段时间后,Key_Flag会有一个高电平脉冲,同时Key_Value更新为输入按键的反码。

为了确定消抖是成功的,这里再附上按键松开时的抖动细节图:

由图可知,松开按键时,该按键IO不断的检测到高电平和低电平,直到一段时间和,抖动方停止,稳定为按键没有按下时的状态

下图为整个工程的仿真结果,由图可知,每按下一次按键0key_in[0],led[0]的状态便翻转一次。


一、        下板验证

手头暂无开发板,板级验证略。

 

二、        总结

本文档对按键消抖的原理进行了分析,并对消抖核心模块的设计进行了仿真,通过modelsim仿真验证了消抖模块设计的正确性。

具体的控制模块这里因为篇幅和时间关系暂不介绍,也因为没有开发板,暂时无法录制演示视频,等录制视频时,我会对整个系统的架构设计,代码设计进行详细的分析和讲解。以前没有做过不知道,写了两三次后才发现,原来文档的编写和整理比编写代码要的时间要多的多。不过,我总还是会坚持做下去的,希望我能有足够的时间来做这些事。

src.rar

2.89 KB, 下载次数: 755

http://xiaomeige.taobao.com。做最用心的FPGA学习板和教程资料
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2014-10-23 22:53:58 | 显示全部楼层
不错,谢谢分享。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

16

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
140
金钱
140
注册时间
2013-8-10
在线时间
0 小时
发表于 2014-10-24 12:15:04 | 显示全部楼层
楼主有FPGA建工程的资料吗?发我一份  谢谢啦!正在学习中  睿智开发板  看的是特权同学的视频  15572508115@qq.com
回复 支持 反对

使用道具 举报

58

主题

499

帖子

4

精华

金牌会员

Rank: 6Rank: 6

积分
1920
金钱
1920
注册时间
2013-11-18
在线时间
268 小时
发表于 2014-10-24 12:20:56 | 显示全部楼层
回复【3楼】Naga1991:
---------------------------------
特权哥的视频里最初篇就是讲了平台的搭建还有Quarter软件的使用等最基础的内容
已经放下多年的FPGA,要重新再拾起来,却是如此的陌生
回复 支持 反对

使用道具 举报

0

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2013-6-11
在线时间
16 小时
发表于 2014-10-24 14:00:14 | 显示全部楼层
上传了源代码,很给力……
回复 支持 反对

使用道具 举报

9

主题

61

帖子

0

精华

初级会员

Rank: 2

积分
187
金钱
187
注册时间
2014-9-25
在线时间
23 小时
发表于 2014-10-24 21:13:41 | 显示全部楼层
发的不错哦 ,果然是廖老师的门徒啊
回复 支持 反对

使用道具 举报

4

主题

12

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2014-3-14
在线时间
0 小时
发表于 2014-12-16 00:36:13 | 显示全部楼层
跟着学学 我也想开个板块边学边走
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2015-3-24
在线时间
0 小时
发表于 2015-3-24 16:21:59 | 显示全部楼层
确实是这样子,把整个资料整理好,确实是一件不容易的事、
努力是必须的,不能停下~!!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 16:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表