呼吸灯--FPGA

目录

1.breath_led.v

2.tb_breath_led.v


呼吸灯就是从完全熄灭到完全点亮,再从完全点亮到完全熄灭。具体就是通过控制PWM的占空比控制亮灭程度。

绘制PWM波的步骤就是,首先灯是在第一个时钟周期保持高电平熄灭状态,在第二个时钟周期保持1/10个时钟周期的低电平,其余都是高电平。在第3个时钟周期保持2/10的低电平,剩余都是高电平,依次绘制下去直到第11个时钟周期在一个周期内都是低电平点亮状态。然后下一个周期还是点亮状态,之后开始逐渐熄灭的波形图的绘制。首先1/10的高电平其余全是低电平...

首先要知道从完全熄灭到完全点亮的时间是多少,定义为1S。声明一个1S的计数器。初识状态不在周期里面因此设置为10个周期,把1S分成1000份,1S/1000=0.001s=1ms,每个T就是1ms。为什么要分成1000份呢,因为分的份数越大,看起来就越细腻,呼吸效果就越好。再把T分成1000份,每次增加一小份。1ms/1000=0.001ms=1us。因此这里就有3个计数器,我们可以先从1us绘制波形图,当满足1000份就是1ms,这样比全部用时钟信号计数可以节约逻辑资源,最大计数都是999。

50Mhz,一个时钟周期就是20ns,那么1us/20ns=1000ns/20ns=50,因此1us要计数50个时钟周期,最大值就是49。当us计数器从0计数到49的时候,ms计数器加1,目的是为了计算1ms计数器的数量,当ms计数器计数到999的时候,s计数器就加1。当s计数器计数到999的时候,此时就花了1s,就表示走过了从全暗到全亮的一个过程。

完整的波形图如下:

以上的波形图还不对,因为还有完全点亮到逐渐熄灭的逆过程,可以通过对led_out取反获得

增加了一个cnt_en使能信号,前1s是低电平,后1s是高电平。

以上是从亮变暗的过程。当cnt_en为低电平并且cnt_1ms<=cnt_1s时,或者cnt_en为高电平并且cnt_1ms>cnt_1s时,输出led_out为低电平,反之为高电平。

1.breath_led.v

复制代码
module breath_led#(
	parameter CNT_1US_MAX=6'd49,
	parameter CNT_1MS_MAX=10'd999,
	parameter CNT_1S_MAX=10'd999

)
(
	input wire 			sys_clk		,
	input wire     		sys_rst_n	,
	
	output 	reg		led_out
);


reg [9:0]cnt_1s	;
reg [9:0] cnt_1ms;
reg [5:0] cnt_1us;
reg       cnt_en;

always@(posedge sys_clk or negedge sys_rst_n)
	if (sys_rst_n==1'b0)
		cnt_1us<=6'd0;
	else if(cnt_1us==CNT_1US_MAX)
		cnt_1us<=6'd0;
	else
		cnt_1us<=cnt_1us+1'd1;
		
always@(posedge sys_clk or negedge sys_rst_n)
	if (sys_rst_n==1'b0)
		cnt_1ms<=10'd0;
	else if((cnt_1us==CNT_1US_MAX)&&(cnt_1ms==CNT_1MS_MAX))
		cnt_1ms<=10'd0;
	else if(cnt_1us==CNT_1US_MAX)
		cnt_1ms<=cnt_1ms+1'd1;
	else
		cnt_1ms<=cnt_1ms;
		
always@(posedge sys_clk or negedge sys_rst_n)
	if (sys_rst_n==1'b0)
		cnt_1s<=10'd0;
	else if((cnt_1s==CNT_1S_MAX)&&(cnt_1ms==CNT_1MS_MAX)&&(cnt_1us==CNT_1US_MAX))
		cnt_1s<=10'd0;
	else if((cnt_1us==CNT_1US_MAX)&&(cnt_1ms==CNT_1MS_MAX))
		cnt_1s<=cnt_1s+1'd1;
	else
		cnt_1s<=cnt_1s;
		
always@(posedge sys_clk or negedge sys_rst_n)
	if (sys_rst_n==1'b0)
		cnt_en<=1'b0;
	else if ((cnt_1s==CNT_1S_MAX)&&(cnt_1ms==CNT_1MS_MAX)&&(cnt_1us==CNT_1US_MAX))
		cnt_en=~cnt_en;
	else 
		cnt_en<=cnt_en;
		
always@(posedge sys_clk or negedge sys_rst_n)
	if (sys_rst_n==1'b0)
		led_out<=1'b1;
	else if(((cnt_en==1'b0)&&(cnt_1ms<=cnt_1s))||((cnt_en==1'b1)&&(cnt_1ms>cnt_1s)))
		led_out<=1'b0;
	else 
		led_out=1'b1;

endmodule

2.tb_breath_led.v

复制代码
`timescale 1ns/1ns

module tb_breath_led();

reg sys_clk;
reg sys_rst_n;

wire led_out;

initial 
	begin
	sys_clk=1'b1;
	sys_rst_n<=1'b0;
	#20
	sys_rst_n<=1'b1;	
	end
	
always #10 sys_clk=~sys_clk;

breath_led
#(
	.CNT_1US_MAX (6'd4),
    .CNT_1MS_MAX (10'd9),
	.CNT_1S_MAX  (10'd9)
  ) 
breath_led_inst
(
	.sys_clk	(sys_clk)	,
	.sys_rst_n	(sys_rst_n),
				
	.led_out    (led_out)
);
endmodule
相关推荐
Terasic友晶科技4 小时前
【教程】Agilex 5 SoC 的两种启动模式的开发演示(一)(FPGA Configuration First)
fpga开发·agilex 5 soc
ALINX技术博客4 小时前
【黑金云课堂】FPGA技术教程Vitis开发:SD卡WAV文件读取音频播放实验
fpga开发·音视频
仲南音2 天前
Xilinx FPGA——时钟IP核MMCM、PLL
fpga开发
I'm a winner3 天前
基于Xilinx FPGA的LVDS高速串行通信系统(三)--数据训练及握手机制【文末源码】
fpga开发
upper20203 天前
coremark移植坑之-nostartfiles -nostdlib参数
学习·fpga开发·coremark移植·riscv设计
Eloudy3 天前
Vivado 纯命令行构建 FPGA 项目教程
fpga开发
Rambo.xia3 天前
AXI跨时钟域与数据一致性——CDC FIFO深度不够、写后读冒险、多Master仲裁、乱序返回,出了Bug根本查不出来
fpga开发·bug
upper20203 天前
FPGA部署卷积神经网络识别MINST图片
fpga开发·卷积神经网络·minst·minst识别·部署神经网络·神经网络识别图片
你是我的解忧王子4 天前
嵌入式 ADC采样 原始数据分析上层(平均值 波动率 正态分布 线性补偿 系统误差)
fpga开发·数据挖掘·数据分析
9527华安4 天前
FPGA纯verilog代码ISP图像处理培训教程,基于IMX214,提供工程源码+视频教程+FPGA开发板
图像处理·fpga开发·isp·imx214·mipi