呼吸灯设计验证

前言

        呼吸灯是一种常用于电子设备上的指示灯,其特点是灯光呈现渐变的亮灭效果,模拟呼吸的节奏。它的主要作用是提供设备状态的视觉提示,如设备开机、连接状态、通知提醒等,帮助用户了解设备的当前状态。除了实用功能,呼吸灯还具有一定的装饰性,能为设备增添现代感和视觉美感。此外,呼吸灯相比于常亮灯光更为节能,有助于延长设备的电池续航时间。在一些情况下,呼吸灯也可用作警示提醒,提示用户设备需要注意的问题。

正文

一、 呼吸灯设计验证

        1.项目需求

        设计基于FPGA的呼吸灯,实现LED灯光的渐变亮度变化,模拟“呼吸”效果。可以设置不同的呼吸模式,如呼吸频率、亮度范围等。

        2.技术介绍

        使用三个计数器(cnt_1uscnt_1ms 和 cnt_1s)来生成一个较慢的时钟信号。这些计数器分别用于微秒、毫秒和秒级别的时间计算。

cnt_1us 计数器用于生成1微秒的时间脉冲,

cnt_1ms 计数器用于生成1毫秒的时间脉冲,

cnt_1s 计数器用于生成1秒的时间脉冲。

cnt_1s 计数器在cnt_1ms 达到最大值时更新,达到最大值时重置为0。cnt_1ms 计数器在cnt_1us 达到最大值时更新,达到最大值时重置为0。cnt_1us 计数器在每个时钟周期上升沿更新,达到最大值时重置为0。

呼吸灯控制:在cnt_en 为0时,LED在1毫秒内渐变亮度;在cnt_en 为1时,LED在1毫秒内渐变熄灭。cnt_en 信号用于控制LED的开关周期。每当1秒的计数完成,cnt_en 反转,控制LED灯光的亮灭。

LED控制:根据cnt_en 和计数器的状态来控制LED的亮灭。LED的亮度是基于cnt_1ms 的值来渐变的。

        3.顶层架构

        4.端口描述

clk时钟信号(50Mhz)
rst_n复位信号(低电平有效)
ledled输出

二、代码验证

module huxi_led(

	input 		clk,//时钟50Mhz
	input 		rst_n,//复位信号
	
	output reg  led//输出,由于在always模块中赋值,这里需要加reg

);

parameter cnt_1s_max  = 10'd999;//1s最大计数值
parameter cnt_1ms_max = 10'd999;//1ms最大计数值
parameter cnt_1us_max = 6'd49;//1us最大计数值

reg [9:0]cnt_1s;//1s计数器
reg [9:0]cnt_1ms;//1ms计数器
reg [5:0]cnt_1us;//1us计数器
reg cnt_en;

always @(posedge clk,negedge rst_n)//1us计数原理
begin
	if(rst_n == 0)
		cnt_1us <= 6'd0;
	else 
		if(cnt_1us == cnt_1us_max)//到达最大计数值计数器清零
			cnt_1us <= 6'd0;
		else
			cnt_1us <= cnt_1us + 6'd1;
end

always @(posedge clk,negedge rst_n)//1ms计数原理
begin
	if(rst_n == 0)
		cnt_1ms <= 10'd0;
	else //1ms计数器到达最大值时需要等待1us计数器记到最大值时进行清零
		if((cnt_1us == cnt_1us_max)&&(cnt_1ms == cnt_1ms_max))
			cnt_1ms <= 10'd0;//到达最大计数值计数器清零
		else //1us计数器到最大值时进行累加
			if(cnt_1us == cnt_1us_max)
				cnt_1ms <= cnt_1ms + 10'd1;
			else 
				cnt_1ms <= cnt_1ms;
end

always @(posedge clk,negedge rst_n)//1s计数原理
begin
	if(rst_n == 0)
		cnt_1s <= 10'd0;
	else //1s计数器记到最大值且1ms计数器到达最大值,等待1us计数器记到最大值时进行清零
		if((cnt_1s == cnt_1s_max)&&(cnt_1us == cnt_1us_max)&&(cnt_1ms == cnt_1ms_max))
			cnt_1s <= 10'd0;//到达最大计数值计数器清零
		else //1us计数器和1ms计数器到最大值时进行累加
			if((cnt_1us == cnt_1us_max)&&(cnt_1ms == cnt_1ms_max))
				cnt_1s <= cnt_1s + 10'd1;
			else 
				cnt_1s <= cnt_1s;
end

always @(posedge clk,negedge rst_n)
begin
	if(rst_n == 0)
		cnt_en <= 1'b0;
	else //完全点亮或完全熄灭后进行状态反转,模拟出呼吸转换
		if((cnt_1s == cnt_1s_max)&&(cnt_1us == cnt_1us_max)&&(cnt_1ms == cnt_1ms_max))
			cnt_en <= ~cnt_en;
		else
			cnt_en <= cnt_en;
end

always @(posedge clk,negedge rst_n)
begin
	if(rst_n == 0)
		led <= 1'b0;
	else //cnt_en 为1时进行呼吸点亮,为0时进行呼吸熄灭
		if(((cnt_en == 1'b0)&&(cnt_1ms <= cnt_1s))||((cnt_en == 1'b1)&&(cnt_1ms > cnt_1s)))
			led <= 1'b1;
		else
			led <= 1'b0;
end
	
endmodule 

仿真代码

`timescale 1ns/1ps
module huxi_led_tb;

	reg clk;
	reg rst_n;
	
	wire led;
//直接对计数器器最大值进行更改,方便观察仿真信号
huxi_led #(.cnt_1s_max(10),.cnt_1ms_max(10),.cnt_1us_max(5))huxi_led_vist(

	.clk		(clk	),
	.rst_n	(rst_n),
	          
	.led		(led	)

);

initial clk = 1;
always #10 clk = ~clk;

initial begin
   rst_n = 0;
	#50
	rst_n = 1;
	#40000
	$stop;
end
	
endmodule

三、仿真验证

        可以看到数据波形显示于我们理论讲解时绘制波形图相同

放大数据进行观察,发现输出跳变始终是在计数器跳变后的下一个时钟周期进行改变,这是由于在时序模块设计中时钟上升沿检测的是时钟上升沿之前的数据,当前时钟的数据会在下个时钟上升沿进行读取判断,输出。

参考资料

呼吸灯

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

张明阳.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值