Verilog实现PWM呼吸灯代码 | FPGA呼吸灯控制与占空比调节教程
通过Verilog代码详解PWM呼吸灯的实现原理,提供完整可运行的模块代码(含时钟分频、占空比动态调节功能),适用于FPGA开发板(如Xilinx、Altera)的LED呼吸灯项目。涵盖仿真步骤、关键参数配置及硬件调试技巧,适合FPGA初学者、电子工程师快速掌握PWM波形生成与硬件描述语言应用。
一、设计文件
module breathing_led
//---------------------<端口声明>---------------------------------------
(
input wire clk , //时钟,50Mhz
input wire rst_n , //复位,低电平有效
output wire led //led灯
);
//---------------------<参数定义>---------------------------------------
parameter TIME_2MS = 100_000 ; //2ms时间
parameter TIME_2MS_W = 17 ; //2ms时间位宽
parameter NUM = 1000 ; //2ms到2s为1000份
parameter NUM_W = 10 ; //份数位宽
parameter STEP = 100 ; //2ms也分成1000份,每份为步长100
//---------------------<信号定义>---------------------------------------
reg [TIME_2MS_W-1:0] cnt0 ;
wire add_cnt0 ;
wire end_cnt0 ;
reg [NUM_W:0] cnt1 ;
wire add_cnt1 ;
wire end_cnt1 ;
reg [1:0] cnt2 ;
wire add_cnt2 ;
wire end_cnt2 ;
reg [TIME_2MS_W-1:0] pwm_high ;
//----------------------------------------------------------------------
//-- 2ms时间计时
//----------------------------------------------------------------------
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt0 <= 0;
else if(add_cnt0)begin
if(end_cnt0)
cnt0 <= 0;
else
cnt0 <= cnt0 + 1;
end
else
cnt0 <= cnt0;
end
assign add_cnt0 = 1;
assign end_cnt0 = add_cnt0 && cnt0==TIME_2MS-1 ;
//----------------------------------------------------------------------
//-- 每2ms计1次,计到2秒共需计NUM次
//----------------------------------------------------------------------
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt1 <= 0;
else if(add_cnt1)begin
if(end_cnt1)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
else
cnt1 <= cnt1;
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1==NUM-1 ;
//----------------------------------------------------------------------
//-- 每2秒计1次,计到4秒共需计2次
//----------------------------------------------------------------------
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt2 <= 0;
end
else if(add_cnt2)begin
if(end_cnt2)
cnt2 <= 0;
else
cnt2 <= cnt2 + 1;
end
else
cnt2 <= cnt2;
end
assign add_cnt2 = end_cnt1;
assign end_cnt2 = add_cnt2 && cnt2==2-1 ;
//----------------------------------------------------------------------
//-- 设置pwm的占空比时间
//----------------------------------------------------------------------
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
pwm_high <= 0;
else if(cnt2==0 && end_cnt0)
pwm_high <= pwm_high + STEP;
else if(cnt2==1 && end_cnt0)
pwm_high <= pwm_high - STEP;
else
pwm_high <= pwm_high;
end
//----------------------------------------------------------------------
//-- 输出led灯
//----------------------------------------------------------------------
assign led = (cnt0 < pwm_high) ? 1'b1 : 1'b0;
endmodule
二、仿真文件
`timescale 1ns/1ps //时间精度
`define Clock 20 //时钟周期
module breathing_led_tb;
//---------------------<端口定义>---------------------------------------
reg clk ; //时钟,50Mhz
reg rst_n ; //复位,低电平有效
wire led ;
//----------------------------------------------------------------------
//-- 模块例化
//----------------------------------------------------------------------
breathing_led
#(
.TIME_2MS (1000 ), //2ms时间 100_000
.NUM (100 ), //2ms到2s为1000份
.STEP (10 ) //2ms也分成1000份,每份为步长100
)
u_breathing_led
(
.clk (clk ),
.rst_n (rst_n ),
.led (led )
);
//----------------------------------------------------------------------
//-- 时钟信号和复位信号
//----------------------------------------------------------------------
initial begin
clk = 1;
forever
#(`Clock/2) clk = ~clk;
end
initial begin
rst_n = 0; #(`Clock*20+1);
rst_n = 1;
end
endmodule
三、仿真波形
可以看到led信号的占空比先不断增加后不断减少,循环反复。

四、上板验证
经过上板验证,最终成功!
"愿我的文字能带给您一丝美好"
分享海报
下载海报

042025/04
Verilog实现PWM呼吸灯代码 | FPGA呼吸灯控制与占空比调节教程
通过Verilog代码详解PWM呼吸灯的实现原理,提供完整可运行的模块代码(含时钟分频、占空比动态调…
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
FPGA在线学习平台
评论
A 为本文作者,G 为游客总数:0