理工实验,Verilog HDL写一个程序让白色LED渐亮渐灭,需要用到PWM,最后通过FPGA演示

2025-04-14 12:00:37
推荐回答(1个)
回答(1):

我给你写了一个代码,没有仿真,里面有简单注释,要是调试出了什么问题或者看不懂可以继续追问,如果没问题请采纳!
module LED
(
input clk_33,
input reset_n,
input switch,
output led_red,
output led_yellow,
output led_bule
);
// 假设PWM的频率为1k:T = 1/1k = 1ms;
// 这个频率可以根据你自己的需要设定然后修改num和t的值即可,不过要注意将相关寄存器的位数做对应修改
// 将1ms再分为256个份,每一份:t = T/256 = 3.9us;
// 以33MHz时钟产生3.9us的定时:N = 3.9*10E(-6)/(1/33000000) = 128.7,取129;
// ==============================
parameter t = 8'd128;
parameter num = 8'd255;
// ==============================
reg [1:0] i;//0:等待用户按键;1:等待完成信号,切换至状态0;
reg iscount;//开始计数信号
reg isdone;//完成信号
// --- --- ---
always @ ( posedge clk_33 or negedge reset_n )
if( !reset_n )
begin
i <= 1'b0;
iscount <= 1'b0;
end
else
case( i )
2'd0:
if( switch )
begin
i <= i + 1'b1;
iscount <= 1'b1;
end
else
begin
i <= i;
iscount <= iscount;
end
2'd1:
if( isdone )
begin
i <= 2'd0;
iscount <= 1'b0;
end
else
begin
i <= i;
iscount <= iscount;
end
endcase
// ==============================
reg [7:0] count1;//产生3.9us
// --- --- ---
always @ ( posedge clk_33 or negedge reset_n )
if( !reset_n )
count1 <= 8'd0;
else if( iscount )
count1 <= count1 + 1'b1;
else if( count1 == t )
count1 <= 8'd0;
else
count1 <= 8'd0;
// ==============================
reg [7:0] count2;//产生1ms
reg [8:0] length;//控制PWM中高电平的时间
reg [1:0] step;//0:等待开始信号;1:渐亮;2:渐暗;3:切换至状态0等待开始信号
// --- --- ---
always @ ( posedge clk_33 or negedge reset_n )
if( !reset_n )
begin
count2 <= 8'd0;
length <= 9'd1;
step <= 2'd0;
isdone <= 1'b0;
end
else
case( step )
2'd0:
if( iscount )
step <= step + 1'b1;
else
step <= step;
2'd1:
if( count2 == 8'd255 )
begin
if( length == 8'd255 )
begin
length <= length - 1'b1;
count2 <= 8'd0;
step <= step + 1'b1;
end
else
begin
length <= length + 1'b1;
count2 <= 8'd0;
end
end
else if( count1 == t )
count2 <= count2 + 1'b1;
else ;
2'd2:
if( count2 == 8'd255 )
begin
if( length == 8'd0)
begin
step <= step + 1'b1;
count2 <= 8'd0;
isdone <= 1'b1;
end
else
begin
length <= length - 1'b1;
count2 <= 8'd0;
end
end
else if( count1 == t )
count2 <= count2 + 1'b1;
else ;
2'd3:
begin
isdone <= 1'b0;
step <= 2'd0;
end
endcase
// ==============================
assign led_red = ( length > count2 ) ? 1'b1 : 1'b0;
assign led_yellow = ( length > count2 ) ? 1'b1 : 1'b0;
assign led_bule = ( length > count2 ) ? 1'b1 : 1'b0;
// ==============================
endmodule