按键控制led灯


前言

  在按键控制蜂鸣器发声章节中我们学习了按键消抖,以及在流水灯章节中学习了控制led的亮灭。本章节将结合前面两章的内容,使用按键控制四个led的状态。


一、按键分类

轻触式按键

图1. 轻触式按键

自锁式按键

图2. 自锁式按键

  “自锁”是指开关能通过锁定机构保持某种状态(通或断),“轻触”是说明操作开关使用的力量大小。cyclone IV开发板上的按键属于轻触式按键。

二、实验任务

  使用开发板上的四个按键控制四个LED灯。按下不同的按键时,四个LED灯显示不同效果。
任务描述

表1. 状态对照表

三、按键原理图

在这里插入图片描述

四、系统框图

  四个按键外加时钟和复位信号作为输入,两个计数器模块分别用于0.2s时间的计数和状态的计数。led模式选择模块根据状态计数器的改变,来改变四个led的状态,形成不同的样式。

系统框图

图3. 系统框图

五、项目代码

module key_led(
	input 				clk  ,//时钟50MHz
	input 				rst_n,//复位信号,下降沿有效negtive
	input 	[3:0]		key  ,//四个按键
	
	output 	reg [3:0]	led   //四个led灯
	
);

parameter TIME = 24'd10_000_000;//0.2S
reg [23:0]	cnt ;//计数器0.2S
reg [1:0]	state;//记录四个led状态

//0.2s计数器模块
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin//复位
		cnt <= 24'd0;//计数器清0
	end 
	else if(cnt == TIME - 1)begin//记满10_000_000,0~9_999_999
		cnt <= 24'd0;//计数器清0
	end 
	else begin
		cnt <= cnt + 1'd1;//其他情况下计数器加1
	end 
end 

//状态计数模块
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin//复位信号
		state <= 2'd0;//状态清0
	end 
	else if(cnt == TIME - 1)begin//记满10_000_000,0~9_999_999 0.2s
		state <= state + 2'd1;//状态加1
	end 
	else begin
	state <= state;//其他情况状态保持不变
	end 
end 

//状态控制led模块
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin//复位信号
		led <= 4'b0000;//led全灭
	end 
	else if(key[0] == 0)begin//右边第1个按键按下,按键低电平0有效
		case(state)//判断状态的值
			2'd0: led <= 4'b0001;//右边第1个led灯亮
			2'd1: led <= 4'b0010;//右边第2个led灯亮
			2'd2: led <= 4'b0100;//右边第3个led灯亮
			2'd3: led <= 4'b1000;//右边第4个led灯亮
			default:;//默认情况不能忘,可以不写,但是要把stat情况考虑完
		endcase 
	end 
	else if(key[1] == 0)begin//右边第2个按键按下,按键低电平0有效
		case(state)//判断状态的值
			2'd0: led <= 4'b1000;//左边第1个led灯亮
			2'd1: led <= 4'b0100;//左边第2个led灯亮
			2'd2: led <= 4'b0010;//左边第3个led灯亮
			2'd3: led <= 4'b0001;//左边第4个led灯亮
		default:;
		endcase 
	end 
	else if(key[2] == 0)begin//右边第3个按键按下,按键低电平0有效
		case(state)
			2'd0: led <= 4'b1111;//全亮
			2'd1: led <= 4'b0000;//全灭
			2'd2: led <= 4'b1111;//全亮
			2'd3: led <= 4'b0000;//全灭
		default:;
		endcase 
	end
	else if(key[3] == 0)begin//右边第4个按键按下,按键低电平0有效
		case(state)
			2'd0: led <= 4'b1111;//全亮
			2'd1: led <= 4'b1111;//全亮
			2'd2: led <= 4'b1111;//全亮
			2'd3: led <= 4'b1111;//全亮
		default:;
		endcase 
	end
	else begin
		led <= 4'b0000;//其他情况默认4个led灯全灭
	end 
end 
endmodule 

  代码部分没有对4个按键进行消抖,最后代码上板后,并没有达到我们想要得效果。按键必须按住不放led才会显示对应的状态。感兴趣的朋友们可以想一想,怎么编写一个消抖模块对4个按键进行消抖。


六、仿真代码

`timescale 1ns/1ns//单位/精度
module key_led_tb();

reg 		clk  ;//时钟信号
reg 		rst_n;//复位信号
reg	 [3:0]	key  ;//按键信号

wire [3:0]	led  ;//led灯信号

parameter TIME  = 10;//间隔时间,由10_000_000变为10,便于仿真观察
parameter CYCLE = 20;//周期20ns
always #(CYCLE/2) clk = ~clk;//每10ns翻转一次,刚好模拟时钟周期50MHz

initial begin
	clk   = 1'b0;//初始时钟为低电平
	rst_n = 1'b0;//复位信号置0,下降沿有效,初始化
	#(CYCLE);//时钟20ns
	rst_n = 1'b1;//复位信号置1
	#(CYCLE * TIME * 4);//4个led灯,4个间隔,所以乘以4
	key   = 4'b1110;//按下右边第1个按键
	#(CYCLE * TIME * 4);
	key   = 4'b1101;//按下右边第2个按键
	#(CYCLE * TIME * 4);
	key   = 4'b1011;//按下右边第3个按键
	#(CYCLE * TIME * 4);
	key   = 4'b0111;//按下右边第4个按键
	#(CYCLE * TIME * 4);
	$stop;//停止
end 

//实例化模块
key_led	 #(.TIME (TIME)) u_key_led

(
.clk  		(clk)  ,//时钟50MHz
.rst_n		(rst_n),//复位信号,下降沿有效
.key  		(key)  ,//按键信号
             
.led		(led)//led灯
); 
endmodule 

modelsim仿真

图4. modelsim 仿真

七、管脚分配

元件管脚
LED0G15
LED1F16
LED2F15
LED3D16
KEY0E15
KEY1E16
KEY2M16
KEY3M15
COLOCK(时钟)E1
表2. 管脚信息表

pin planner

图5. pin planner

八、运行效果

按键控制led灯


总结

  以上就是今天要讲的内容,本文结合之前所学内容,使用4个按键控制4个led灯的状态。在按键部分,没有对按键进行消抖,感兴趣的朋友们可以评论区附上你们的按键消抖代码。

在这里插入图片描述

  • 7
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值