用户工具

站点工具


icore3l_fpga_11
银杏科技有限公司旗下技术文档发布平台
技术支持电话0379-69926675-801
技术支持邮件Gingko@vip.163.com
版本 日期 作者 修改内容
V1.0 2020-11-25 zgf 初次建立

实验十一:GPIO输入实验——识别按键输入

一、 实验目的与意义

  1. 了解按键特征和应用。
  2. 学习按键动作的识别和判断。
  3. 学习按键消抖的处理方法。

二、 实验设备及平台

  1. iCore3L 双核心板。
  2. XiST USB Cable(或相同功能)仿真器。
  3. Micro USB线缆。
  4. 装有HqFpga开发软件的电脑一台。

三、 实验原理

  • SL2S-25E的I/O单元包含1个双向I/O换从器和三个寄存器;可以使用I/O单元用于输入、输出或双向数据路径。
  • iCore3L上有一个按键和FPGA相连,原理图如图11-1中所示。从原理图中可以看到,按键未按下时,FPGA引脚接3.3V,引脚电平为高。当按键按下后,FPGA引脚与地导通,此时FPGA引脚电平为低。那么,判断按键是否按下的方法就是将与按键相连的引脚作为输入引脚,并检测此引脚的电平,当电平为低时,表示按键按下。

图 11-1 按键及FPGA_LED原理图

  • 当检测到按键按下,设计代码功能为控制与LED相连的引脚电平为低,此时点亮LED。从而实现按键控制LED状态的功能。即通过检测FPGA·KEY引脚的电平变化,判断按键的状态,继而控制LED的亮灭。
  • 在按键按下和松开的过程,电平并不是理想的立即从高到低或者从低到高变化的。在跳变的过程中,是有抖动的,持续大概10ms左右。抖动会影响FPGA对按键状态的正确判断,因此在设计中要对按键动作做消抖处理。处理方式分物理消抖和软件消抖。物理消抖则是通过并联电容,消除抖动噪声。软件处理则是通过延时处理,跳过抖动阶段,再读取按键状态,从而实现按键消抖操作。

图11-2 按键动作过程电平变化示意图

  • 如图11-2中所示,在实际的按键动作中,按下和松开的瞬间,电平跳变的过程中是有抖动存在的;在硬件设计中可以通过并联电容削减抖动造成的影响。在软件设计中可以采用延时消抖的方式进一步消除抖动的影响。
  • 延时消抖的实现方式也较为简单,当FPGA检测到与按键相连的引脚出现下降沿之后开始计时,约40ms后再次检测与按键相连引脚的电平;如果电平与之前不同,则判别为有按键按下。这样通过延时的方式跳过抖动阶段,检测稳定后的电平状态,从而降低抖动对电平判断的影响,识别真正的按键动作。
  • 同理,按键松开的动作也可以通过这种方式进行检测。在按键按下的状态,检测电平的上升沿,待出现上升沿后,开始计时;延时40ms后检测电平状态,从而判断按键是否松开。

四、 代码实现

  • 本实验代码较为简单,首先是对输入信号进行延迟1拍处理,是高低电平数字量处于稳定状态,便于进行沿跳变检测。检测到下降沿后开始计数,然后对时钟计数持续40ms后,采集按键输入引脚的电平,如果为低电平,表示按键按下,则控制三色LED颜色切换。这里请注意对延时计数器的控制,使其在按键按下期间持续计数。按键未按下时进行清零。代码如下:
//---------------------按键动作检测---------------------------//
	reg key_r;
	reg	key_rr;
 
	always@(posedge fpga_clkor negedge rst_n)
		if(!rst_n)
			begin
				key_r<=1'b0;
				key_rr<=1'b0;
			end
		else
			begin
				key_r<=key;			//输入信号延迟1拍
				key_rr<=key_r;		//输入信号延迟2拍
			end
 
	reg 	[19:0]cnt;
	reg		flag;
	always@(posedge fpga_clk or negedge rst_n)
		if(!rst_n)
			flag<=1'd1;
		else if((key_r==1'd0)&&(key_rr==1'd1))			//下降沿检测
				flag<=1'd0;
			else if((key_r==1'd1)&&(key_rr==1'd0))		//上升沿检测
				flag<=1'd1;
 
	always@(posedge fpga_clk or negedge rst_n)
		if(!rst_n)
			cnt<=20'd0;
		else if((cnt<20'd1000_000)&&(flag==1'b0))		//约40ms
			cnt<=cnt+1'd1;
		else if(flag==1'b1)
			cnt<=20'd0;
			else
				cnt<=20'd1000001;
 
	reg	[2:0]	led_r;
	always@(posedge fpga_clk or negedge rst_n)			//LED 状态切换
		if(!rst_n)
			led_r<=3'b110;
		else if(cnt==20'd1000_000)
			led_r<={led_r[1],led_r[0],led_r[2]};		//循环左移,三色LED颜色循环切换

五、 实验步骤

  • 1、新建工程,点击左侧栏中“新建工程”按钮,弹出“设置(S)”窗口中填写工程名称,选择目标器件为SL2S-25E8U213C,设置输入类型为RTL描述,然后点击“下一步”,弹出“RTL输入”界面,直接点击“完成”。
  • 2、点击左侧栏“设计管理”按钮,新建源文件,或者通过点击左侧边栏的“工程属性”按钮,将例程下的源文件添加到工程中,并将key模块设置成顶层模块。

11-3 添加源文件及设置顶层模块

  • 3、然后点击“RTL综合”按钮,进行初步编译;无报错后点击左侧栏里的“物理约束”按钮,将按键绑定到相应的引脚;然后点击保存并退出。

图 11-4	添加物理约束,绑定引脚信息

  • 4、然后点击左侧栏“全部运行”按钮,进行全编译,生成下载用的bit文件;并将下载器连接到iCore3L双核心板上,给板子上电。
  • 5、点击“下载/编程”按钮,将编译好的bit文件下载到FPGA中。
  • 6、按下按键,观察LED状态的切换。

六、 实验现象

  • 按动iCore3L上的FPGA按键,iCore3L双核心板上的 FPGA·LED在每次按键按下后切换亮灭状态。
icore3l_fpga_11.txt · 最后更改: 2022/03/19 15:27 由 sean