本文主要是介绍05. 基于Verilog的呼吸灯程序设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
05_led_breath_v0
一个基于Verilog的呼吸灯程序示例,该程序通过PWM(脉冲宽度调制)技术来模拟呼吸灯的效果,逐渐变亮再逐渐变暗的LED灯,给人一种灯光在“呼吸”的感觉。
原理解释:
-
PWM(脉冲宽度调制):通过改变输出信号的占空比来模拟不同亮度的LED灯。
-
呼吸灯周期:呼吸灯的周期由breathing_cnt控制,这里假设周期为1/4秒钟。
-
呼吸灯亮度变化:呼吸灯的亮度变化通过改变占空比的值来模拟。
- 当pwm_cnt小于当前pwm_duty时,LED亮;
- 当pwm_cnt大于pwm_duty时,LED不亮。
知识点:
- PWM(脉冲宽度调制)
- Duty(占空比)
- 位宽确定可表达的最大整数值
- 位拼接语法
assign led = {6{led_breathing}};
module led_breath #(parameter CLK_FREQ = 50000000,parameter LED_ON = 1'b0
)(input wire clk, input wire rst_n, output wire [5:0] led
);// 定义一个计数器用于产生PWM波形
reg [11:0] pwm_cnt;
reg [11:0] pwm_duty;reg [31:0] breath_cnt;// 呼吸灯周期,假设为1秒钟4个周期
localparam CYCLE = CLK_FREQ/4;always @(posedge clk) beginif (!rst_n) breath_cnt <= 0;else beginbreath_cnt <= breath_cnt + 1'b1;if (breath_cnt == CYCLE-1) breath_cnt <= 0;end
endwire breath_done = (breath_cnt == CYCLE-1);//PWM CNT
always @(posedge clk) beginif (!rst_n) pwm_cnt <= 0;else pwm_cnt <= pwm_cnt + 1'b1;
end//PWM Duty
//light to off
always @(posedge clk) beginif (!rst_n) pwm_duty <= 12'hFFF;else if(breath_done) beginif(pwm_duty == 0) pwm_duty <= 12'hFFF;else pwm_duty <= {1'b0,pwm_duty[11:1]};end//else pwm_duty <= pwm_duty;
end/*
//off to light on
always @(posedge clk) beginif (!rst_n) pwm_duty <= 12'b0;else if(breath_done) beginif(pwm_duty == 12'hFFF) pwm_duty <= 12'b0;else pwm_duty <= {pwm_duty[10:0],1'b1};end//else pwm_duty <= pwm_duty;
end
*/// 根据PWM计数器的值和呼吸灯的亮度变化来控制LED的亮度
reg led_breathing;
//parameter LED_ON = 1'b0; //led active low on our board
localparam LED_OFF = ~LED_ON;always @(posedge clk) beginif (!rst_n) led_breathing <= LED_OFF;else if (pwm_cnt < pwm_duty) beginled_breathing <= LED_ON;end else led_breathing <= LED_OFF;
endassign led = {6{led_breathing}};endmodule
扩展思维
-
学习了点亮LED、LED闪烁、LED跑马灯和LED呼吸灯这样多种模式LED效果,思考如何将这些不同的效果在一个工程里全部实现,并利用DIP开关选择不同的运行模式,呈现不同的效果。
-
尝试修改代码实现6个LED分为两组,每组以不同的频率呼吸。
这篇关于05. 基于Verilog的呼吸灯程序设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!