Verilog编程学习之—呼吸灯
Verilog编程-呼吸灯
1.设计目标
用FPGA产生占空比变化的PWM波,控制LED灯由暗变亮的变化。
2.设计思路
设置PWM波的步长为2us,周期为2ms,每个周期内LED亮的时间由0增加至999,再从999减少至0,依次循环,就可以看到LED灯由暗变亮再由亮变暗的循环过程。可以设置一个占空比寄存器duty_r和一个标记寄存器sign_r:
1.duty_r在每个周期后都加1,加到999后置0;
2.当sign_r为1时,计数器小于duty_r时LED灯亮,当sign_r为0时,计数器大于duty_r时LED灯亮。
代码如下:
module led(
input clk,
input rst_in,
output reg led
);
reg rst;
reg[6:0] cnt_2us;
reg[9:0] cnt_2ms;
reg[9:0] cnt_2s;
reg inc_dec_flag;
//异步复位
always@(posedge clk or negedge rst_in)begin
if(!rst_in)
rst <= 1'b1;
else
rst <= 1'b0;
end
//计数2us为一个step
always@(posedge clk)
begin
if(rst == 1'd1)
cnt_2us <= 7'd0;
else if(cnt_2us == (7'd100 - 7'd1))
cnt_2us <= 7'd0;
else
cnt_2us <= cnt_2us + 7'b1;
end
//计数2ms为一个周期
always@(posedge clk)
begin
if(rst == 1'b1)
cnt_2ms <= 10'b0;
else if((cnt_2ms == (10'd1000 - 10'b1)) &&(cnt_2us == (7'd100 - 7'b1)))
cnt_2ms <= 10'b0;
else if(cnt_2us == (7'd100 - 7'b1))
cnt_2ms <= cnt_2ms + 10'b1;
end
//计数占空比变化
always@(posedge clk)
begin
if(rst == 1'b1)
cnt_2s <= 10'b0;
else if((cnt_2s == (10'd1000 - 10'b1)) && (cnt_2ms == (10'd1000 - 10'b1)) && (cnt_2us == (7'd100 - 7'b1)))
cnt_2s <= 10'b0;
else if((cnt_2ms == (10'd1000 - 10'b1)) && (cnt_2us == (7'd100 - 7'b1)))
cnt_2s <= cnt_2s + 10'b1;
end
//标志LED变化方向的flag
always@(posedge clk)
begin
if(rst == 1'b1)
inc_dec_flag <= 1'b0;
else if((cnt_2s == (10'd1000 - 10'b1)) && (cnt_2ms == (10'd1000 - 10'b1)) && (cnt_2us == (7'd100 - 7'b1)))
inc_dec_flag <= ~inc_dec_flag;
end
//输出led信号
always@(posedge clk)
begin
if(rst == 1'b1)
led <= 1'b0;
else if( inc_dec_flag ^ (cnt_2ms < cnt_2s))
led <= 1'b1;
else
led <= 1'b0;
end
endmodule
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体