LED灯闪烁拓展实验——单按键控制LED灯不同闪烁方式

这篇具有很好参考价值的文章主要介绍了LED灯闪烁拓展实验——单按键控制LED灯不同闪烁方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、说明

实现平台:Vivado2018.3

二、内容

1. 使用按键KEY0和KEY_1分别控制LED0和LED1两个LED灯的闪烁方式;

2. 当没有按键按下时,两个LED灯均不亮;

3. 当按键KEY0按下后,LED0灯闪烁,当按键KEY0再次按下后则LED1灯闪烁,如此循环往复;

4. 当按键KEY1按下后,LED0和LED1交替闪烁,当按键KEY1再次按下后则LED0和LED1同时闪烁,如此循环往复;

5. 在内容3中若按键KEY1按下,则执行内容4操作;在内容4中若按键KEY0按下,则执行内容3操作。

三、步骤

(1)设计要求

  •    时钟频率为50MHZ;
  •    按键KEY0和KEY1;
  •    LED灯LED0和LED1。

(2)设计思路

本实验设计可分为四个模块:

  •    计数器模块:用于计数LED灯闪烁间隔;
  •    LED闪烁状态控制模块:用于改变LED灯状态;
  •   按键边缘检测模块:用于检测按键按下的状态;
  •   按键控制闪烁实现模块:使用两个状态机,分别实现KEY0和KEY1的LED灯闪烁控制。

(3)具体实现

0.相关信号声明:

module key_led(
	input  				sys_clk,
	input  				sys_rst_n,
	
	input      [1:0]	key,
	output reg [1:0] 	led
    );
	
reg  [24:0] cnt; 
reg  		led_ctrl;

reg  [1:0]	key_edg0;				//边缘检测
reg  [1:0]	key_edg1;

reg  [1:0]	state_key0;				//按键状态
reg  [1:0]  state_key1;

wire [1:0]	key_en;					//控制小灯闪烁

1. 计数器模块实现:

其中cnt计满为25_000_000,时钟频率为50MHZ,25_000_000/50_000_000 = 0.5s=500ms

//计数器
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)
		cnt <= 25'd0;
	else if(cnt < 25'd25_000_000)	//计数500ms
//	else if(cnt < 25'd25)			//仿真用
		cnt <= cnt + 1'b1;
	else	
		cnt <= 0;
end

2. LED闪烁状态控制模块:

//每隔500ms就更改LED的闪烁状态
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)
		led_ctrl <= 1'b0;
	else if(cnt == 25'd25_000_000)
//	else if(cnt == 25'd25)			//仿真用
		led_ctrl <= ~led_ctrl;
end

3.按键边缘检测模块:

其中使用该模块的原因主要是实现按键仅按一下即实现相关操作的功能,而无需一直按住按键才能执行相关操作。代码中检测上升沿或下降沿均可。

assign key_en[0] = (~key_edg0[0]) & key_edg1[0]; //按键0下降沿检测
assign key_en[1] = (~key_edg0[1]) & key_edg1[1]; //按键1下降沿检测

//PL_KEY边缘检测
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)begin
		key_edg0 <= 0;
		key_edg1 <= 0;
	end
	else begin
		key_edg0 <= key;
		key_edg1 <= key_edg0;
	end
end

4.按键控制闪烁实现模块:

此处使用两个状态机,状态机1控制KEY0实现对应的LED灯闪烁;状态机2控制KEY1实现对应的LED灯闪烁。

//两个状态机,根据按键KEY0来控制LED的闪烁
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)begin
		state_key0 <= 2'd0;
		state_key1 <= 2'd0;
		led <= 0;
	end
	else begin
		case(state_key0)								//状态机1
			2'd0 : begin
				led <= led;								//默认保持原状态
				state_key0 <= (key_en[0]) ? 2'd1:2'd0;
			end
			2'd1 : begin
				led[0] <= (led_ctrl) ? 1'b1:1'b0; 		//LED0闪烁
				led[1] <= 0;							//LED1不亮	
				if (key_en[0])
					state_key0 <= 2'd2;					//切换到下一状态
				else if(key_en[1])  					//若按键1按下,则返回状态机2
					state_key1 <= 2'd1;
				else
					state_key0 <= 2'd1;
			end
			2'd2 : begin
				led[1] <= (led_ctrl) ? 1'b1:1'b0; 		//LED1闪烁
				led[0] <= 0;							//LED0不亮
				if (key_en[0])
					state_key0 <= 2'd1;					//返回上一状态
				else if(key_en[1])  					//若按键1按下,则返回状态机2
					state_key1 <= 2'd1;
				else
					state_key0 <= 2'd2;
			end
			default:state_key0 <= 2'd0;
		endcase
		case(state_key1)								//状态机2
			2'd0 : begin
				state_key1 <= (key_en[1]) ? 2'd1:2'd0;
			end
			2'd1 : begin
				led <= (led_ctrl) ? 2'b01:2'b10; 		//LED0和1交替闪烁
				state_key1 <= (key_en[1]) ? 2'd2:2'd1;	//切换到下一状态
				if (key_en[1])
					state_key1 <= 2'd2;					//切换到下一状态
				else if(key_en[0])begin  				//若按键0按下,则返回状态机1
					state_key0 <= 2'd1;
					state_key1 <= 2'd0;
				end
				else
					state_key1 <= 2'd1;	
			end
			2'd2 : begin
				led <= (led_ctrl) ? 2'b11:2'b00; 		//LED0和1同时闪烁
				if (key_en[1])
					state_key1 <= 2'd1;					//切换到上一状态
				else if(key_en[0])begin  				//若按键0按下,则返回状态机1
					state_key0 <= 2'd1;
					state_key1 <= 2'd0;
				end
				else
					state_key1 <= 2'd2;
			end
			default:state_key1 <= 2'd0;	
		endcase
	end
end	

5.testbenc仿真测试程序

此处我们模拟按键操作,分别按一下KEY0,再按一下KEY0,查看是否实现了LED0和LED1的切换闪烁操作;之后按KEY1,再按一下KEY1,查看时候实现了两个LED灯的交替以及同时闪烁;最后再仿真按下两次KEY0操作,查看是否实现了按键切换的操作。

其中为了防止仿真时间过长,主程序文件的cnt计数可以改的小一些,方便仿真。

`timescale 1ns / 1ns
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;
    #200
    sys_rst_n = 1'b1;
	#200
	key = 2'b10;
	#100
	key = 2'b11;
	#2000
	key = 2'b10;
	#100
	key = 2'b11;
	#2000
	key = 2'b01;
	#100
	key = 2'b11;
	#2000
	key = 2'b01;
	#100
	key = 2'b11;
	#2000
	key = 2'b10;
	#100
	key = 2'b11;
	#2000
	key = 2'b10;
	#100
	key = 2'b11;
	#2000
	$finish;
end

//生成时钟
always #10 sys_clk = ~sys_clk;

//例化待测设计
key_led  u_key_led(
    .sys_clk         (sys_clk),
    .sys_rst_n       (sys_rst_n),
    .key             (key),
	.led			 (led)
    );

endmodule

四、仿真结果

当按键key0按下后,led0灯闪烁,当按键key0再次按下后则led1灯闪烁,如此循环往复,ZYNQ/FPGA开发,fpga开发

 从仿真图可以看出,左边白框部分实现了LED0(01,00,01,00)和LED1(00,10,00,10)的闪烁功能;中间框部分则实现了LED等交替闪烁和同时闪烁的功能;最后右边蓝框部分,其实现功能和白框部分一样,实现了按键的切换实现LED灯闪烁功能,表明实验成功。文章来源地址https://www.toymoban.com/news/detail-817925.html

五、完整程序代码

//`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/20 08:28:10
// Design Name: 
// Module Name: key_led
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description:使用PL_KEY0和PL_KEY_1来控制底板上的PL_LED0和PL_LED1两个LED的闪烁方式。 
// 没有按键按下时,两个LED不亮,若按键0按下,则LED0闪烁,若再次按下则LED1闪烁,再按
// 下则LED0闪烁,如此交替;若1按下,则两个LED交替闪烁,再次按下则两个LED同时闪烁,如此反复。
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module key_led(
	input  				sys_clk,
	input  				sys_rst_n,
	
	input      [1:0]	key,
	output reg [1:0] 	led
    );
	
reg  [24:0] cnt; 
reg  		led_ctrl;

reg  [1:0]	key_edg0;				//边缘检测
reg  [1:0]	key_edg1;

reg  [1:0]	state_key0;				//按键状态
reg  [1:0]  state_key1;

wire [1:0]	key_en;					//控制小灯闪烁

//计数器
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)
		cnt <= 25'd0;
	else if(cnt < 25'd25_000_000)	//计数500ms
//	else if(cnt < 25'd25)			//仿真用
		cnt <= cnt + 1'b1;
	else	
		cnt <= 0;
end

//每隔500ms就更改LED的闪烁状态
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)
		led_ctrl <= 1'b0;
	else if(cnt == 25'd25_000_000)
//	else if(cnt == 25'd25)			//仿真用
		led_ctrl <= ~led_ctrl;
end

assign key_en[0] = (~key_edg0[0]) & key_edg1[0]; //按键0下降沿检测
assign key_en[1] = (~key_edg0[1]) & key_edg1[1]; //按键1下降沿检测

//PL_KEY边缘检测
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)begin
		key_edg0 <= 0;
		key_edg1 <= 0;
	end
	else begin
		key_edg0 <= key;
		key_edg1 <= key_edg0;
	end
end

//两个状态机,根据按键KEY0来控制LED的闪烁
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)begin
		state_key0 <= 2'd0;
		state_key1 <= 2'd0;
		led <= 0;
	end
	else begin
		case(state_key0)								//状态机1
			2'd0 : begin
				led <= led;								//默认保持原状态
				state_key0 <= (key_en[0]) ? 2'd1:2'd0;
			end
			2'd1 : begin
				led[0] <= (led_ctrl) ? 1'b1:1'b0; 		//LED0闪烁
				led[1] <= 0;							//LED1不亮	
				if (key_en[0])
					state_key0 <= 2'd2;					//切换到下一状态
				else if(key_en[1])  					//若按键1按下,则返回状态机2
					state_key1 <= 2'd1;
				else
					state_key0 <= 2'd1;
			end
			2'd2 : begin
				led[1] <= (led_ctrl) ? 1'b1:1'b0; 		//LED1闪烁
				led[0] <= 0;							//LED0不亮
				if (key_en[0])
					state_key0 <= 2'd1;					//返回上一状态
				else if(key_en[1])  					//若按键1按下,则返回状态机2
					state_key1 <= 2'd1;
				else
					state_key0 <= 2'd2;
			end
			default:state_key0 <= 2'd0;
		endcase
		case(state_key1)								//状态机2
			2'd0 : begin
				state_key1 <= (key_en[1]) ? 2'd1:2'd0;
			end
			2'd1 : begin
				led <= (led_ctrl) ? 2'b01:2'b10; 		//LED0和1交替闪烁
				state_key1 <= (key_en[1]) ? 2'd2:2'd1;	//切换到下一状态
				if (key_en[1])
					state_key1 <= 2'd2;					//切换到下一状态
				else if(key_en[0])begin  				//若按键0按下,则返回状态机1
					state_key0 <= 2'd1;
					state_key1 <= 2'd0;
				end
				else
					state_key1 <= 2'd1;	
			end
			2'd2 : begin
				led <= (led_ctrl) ? 2'b11:2'b00; 		//LED0和1同时闪烁
				if (key_en[1])
					state_key1 <= 2'd1;					//切换到上一状态
				else if(key_en[0])begin  				//若按键0按下,则返回状态机1
					state_key0 <= 2'd1;
					state_key1 <= 2'd0;
				end
				else
					state_key1 <= 2'd2;
			end
			default:state_key1 <= 2'd0;	
		endcase
	end
end			

endmodule

到了这里,关于LED灯闪烁拓展实验——单按键控制LED灯不同闪烁方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【stm32----按键中断实验,按键控制LED灯】

    1、按下KEY1,LED1亮,再次按下KEY1,LED1灭; 2、按下KEY2,LED2亮,再次按下KEY2,LED2灭; 3、按下KEY3,LED3亮,再次按下KEY3,LED3灭; 一、头文件 1、gpio.h 2、key.h 二、初始化函数及功能函数 1、gpio.c 2、key.c 三、中断处理函数 do_irq.c 四、主函数 main.c 依次按下key3、key2、key1、key2

    2024年02月04日
    浏览(40)
  • 驱动——按键中断控制LED灯实验

    要求:按键按一下灯亮,再按一下灯灭 注:由于开发板位置,为了方便一一对应观察,采用key1控制LED3,key2控制LED2,key3控制LED1 0、添加相关设备树节点信息 ①按键相关引脚,通过原理图可得: key1------gpiof9; key2------gpiof7; key3------gpiof8 ②LED灯相关引脚: led1-----gpioe10; led2---

    2023年04月18日
    浏览(26)
  • 单片机实验三 独立按键控制LED实验

    1.熟悉实验软件和硬件,进行正确的接线; 2.8个不同的按键对应不同的8个灯,按下按键对应的灯就会亮。 1.Keil uVision4 2.PZISP自动下载软件 3.HC6800S开发板 按键实物图 按键按下就会产生一个脉冲信号,检测脉冲信号就可以知道是否有按键被按下去。 按键原理图 按键之间相互独

    2024年02月08日
    浏览(30)
  • 初识FreeRTOS入门,对FreeRTOS简介、任务调度、内存管理、通信机制以及IO操作,控制两个led不同频率闪烁

    当代嵌入式系统的开发越来越复杂,实时性要求也越来越高。为了满足这些需求,开发者需要使用实时操作系统(RTOS),其中一个流行的选择是FreeRTOS(Free Real-Time Operating System)。本篇博客将详细介绍FreeRTOS的特性、任务调度、内存管理、通信机制以及一些示例代码。 FreeR

    2024年02月14日
    浏览(26)
  • verilog学习笔记- 10)按键控制 LED 灯实验

    目录 简介: 实验任务: 硬件设计: 程序设计: 下载验证 : 总结与反思: 按键开关是一种电子开关,属于电子元器件类。我们的开发板上有两种按键开关:第一种是本实验所使用的轻触式按键开关,使用时以向开关的操作方向施加压力使内部电路闭合接通,当撤销压力时

    2023年04月16日
    浏览(37)
  • 【STM32】按键控制LED亮灭实验——GPIO、LED、KEY、SYS

    无锁存时:当按下独立按钮时LED亮,松开LED灭。 锁存时:当按下独立按钮时LED亮,松开LED仍亮,再按下独立按钮时LED熄灭。 硬件部分 软件部分 1、引入头文件 2、主函数 首先时钟、led、按键初始化 锁存时:当按下独立按钮时LED亮,松开LED仍亮,再按下独立按钮时LED熄灭。常

    2024年02月08日
    浏览(80)
  • 【STM32】控制LED灯和蜂鸣器的按键实验

    🐱作者:一只大喵咪1201 🐱专栏:《STM32学习》 🔥格言: 你只管努力,剩下的交给时间! 本喵这次介绍的实验是按键实验,同样使用STM32F103ZE型号的芯片,在开发板上有4个按键,实验目的是每按一个按键就会让LED灯或者是蜂鸣器的工作状态发生反转,下面本喵来详细介绍。

    2024年02月03日
    浏览(46)
  • 2.外部中断方式检测按键输入并控制LED示例

    打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行,就叫中断。 其中,系统中断表 及对应的说明 如下图所示: 我们可以按住 Ctrl 点击中断向量表中的 ISR 函数名,可以进入该函数,可以发现,这些系统函数虽然都定义了,但是没有编写其工作方式

    2024年04月13日
    浏览(30)
  • stm32按键实现LED的闪烁

    首先,需要准备如下硬件设备: STM32F103C8T6单片机开发板 4个LED灯 4个220欧姆电阻 4个按键 接下来,我将讲解如何连接硬件设备。 将4个LED灯连接到STM32单片机的PB0、PB1、PB2、PB3引脚上。 将4个220欧姆电阻连接到PB0、PB1、PB2、PB3引脚上,防止电流过大损坏LED灯。 将4个按键连接到

    2024年02月08日
    浏览(34)
  • 用STM32单击按键实现LED闪烁和双击按键实现LED呼吸灯效果

    在嵌入式系统中,按键和LED是最常见的外设之一。本文将介绍如何使用STM32微控制器实现按键的单击和双击检测,并通过控制LED的闪烁和呼吸灯效果来呈现按键的触发效果。 第一部分:硬件准备 准备一块STM32开发板,如STM32F103C8T6。 连接一个按键到开发板上的GPIO引脚,并通过

    2024年02月05日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包