按键控制LED闪烁实验

一、要求

两个按键KEY0、KEY1控制LED0、LED1的闪烁。

功能定义:
无按键按下:两个LED全亮;
按下KEY0:交替闪烁
按下KEY1:同时闪烁

二、实现

1.原理

把电路分成三个部分:计数器、控制器、LED灯

50MHZ时钟的周期为20ns,每0.5秒改变一次LED的状态,闪烁一次(两个状态)需要1秒,0.5秒需要2500_0000个时钟周期,2500_0000需要25位二进制数表示。

通过计数器来实现,定义一个25位的计数器cnt[24:0],每个clk上升沿计数一次。

同时定义控制信号led_ctrl,用于控制LED灯。当计数器完成一轮计数,将led_ctrl取反,完成第二轮计数时,再将led_ctrl取反,以此类推,那么led_ctrl每变化一次,灯会变更一次状态。

考虑计数器,当:

cnt < 2500_0000时,有cnt = cnt + 1;

cnt ≥ 2500_0000时,有cnt = 0,led_ctrl取反,进行下一轮计数。

考虑控制信号,当:

KEY = 10(即按下LED0)时,LED应该交替闪烁,闪烁周期为led_ctrl的周期,令:

        led_ctrl = 0时,led = 01;

        led_ctrl = 1时,led = 10;

KEY = 01(即按下LED1)时,LED应该同时闪烁,令:

        led_ctrl = 0时,led = 11;

        led_ctrl = 1时,led = 00;

2.代码

/*
-----------------------
功能定义:
无按键按下:两个LED全亮;
按下KEY0:交替闪烁
按下KEY1:同时闪烁
-----------------------
输入:时钟、复位、KEY0、KEY1
输出:LED0、LED1
-----------------------
为便于仿真,将计数周期调整为25
-----------------------
*/
module key_led(
	input		 sys_clk,
	input 		 sys_rst_n,
	input 	 	 [1:0] key, //[key1,key0],按下为低电平
	output reg	 [1:0] led	//亮起为高电平
    );
	
reg [24:0] cnt; //2500_0000需要25位表示
reg led_ctrl;

/*计数器*/
always @(posedge sys_clk or negedge sys_rst_n) begin

	if(!sys_rst_n)
		cnt <= 25'd0;
	else if(cnt < 25/*2500_0000*/)
		cnt <= cnt + 1'b1;
	else
		cnt <= 25'd0;
end

/*控制信号*/
always @(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		led_ctrl <= 1'b0;
	else if(cnt == 25/*2500_0000*/)
		led_ctrl = ~led_ctrl;
end

/*按键和led_ctrl对LED闪烁的控制*/	
always @(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		led <= 2'b11;
	else case(key)
			2'b10: 
				if(led_ctrl == 1'b0)
					led <= 2'b01;
				else
					led <= 2'b10;
			2'b01:
				if(led_ctrl == 1'b0)
					led <= 2'b11;	
	            else
	            	led <= 2'b00;
			2'b11:
				led <= 2'b11;
			default: /*led <= 2'b11*/;
		endcase
end	
	
endmodule

 testbench:

`timescale 1ns / 1ps

module tb_key_led();
reg			sys_clk;
reg 		sys_rst_n;
reg  [1:0] 	key;
wire [1:0] 	led;

initial begin
			sys_clk 	= 1'b0;
			sys_rst_n 	= 1'b0;
			key 		= 2'b11;
	#60 	sys_rst_n	= 1'b1; 
	#40 	key 		= 2'b10;//按下KEY0:	交替闪烁
	#2000 	key 		= 2'b11;//无按键按下:	两个灯全亮
	#100 	key 		= 2'b01;//按下KEY1:	同时闪烁
	#2000 	key 		= 2'b11;//无按键按下:	两个灯全亮
end

always #10 sys_clk = ~sys_clk; //5mhz时钟 0.05*1000 = 50MHZ

key_led u_key_led(

	.sys_clk(sys_clk),
    .sys_rst_n(sys_rst_n),
	.key(key),
	.led(led)
);

endmodule

3.仿真

 可见在按下KEY0时,LED实现交替闪烁;按下KEY1时,LED实现同时闪烁;同时按下两个键时,LED全亮。

我好菜啊好菜好菜,菜到抠脚。

 md一定要好好学习

2022/1/18 17:03

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bluebub

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值