PWM呼吸灯verilog实现

一、设计目标

        本次实验要实现的工程,旨在实现控制LED灯亮度的功能,具体要求为:上电后,LED灯显示接近于灭,随后每隔2秒亮度发生一次变化,在前10秒时间内,每隔2秒逐渐变亮。在下一个10秒时间内,每隔2秒,亮度逐渐变暗。简单来说即是以20秒为一次循环,每隔2秒变化一次,前10秒亮度逐渐增大,后10秒亮度逐渐减小。

二、设计实现

        根据PWM的原理,可以得知通过控制PWM的占空比可以实现LED灯的亮度控制。PWM占空比越大(高电平时间越长,低电平时间越低),灯的亮度越暗。可以这样理解:FPGA控制led信号的输出,可以输出为PWM波形并通过调整占比来达到改变LED灯亮度的效果。根据设计目标可以得出设计方案:每20秒一次循环,每隔2秒改变一次led的占空比,前10秒占空比逐渐变大,LED灯逐渐变亮,后10秒占空比逐渐变小,LED灯也随之逐渐变暗。

设计时设定的占空比如下:

第1个2秒内,占空比为95%;

第2个2秒内,占空比为85%;

第3个2秒内,占空比为70%;

第4个2秒内,占空比为50%;

第5个2秒内,占空比为20%;

第6个2秒内,占空比为20%;

第7个2秒内,占空比为50%;

第8个2秒内,占空比为70%;

第9个2秒内,占空比为85%;

第10个2秒内,占空比为95%。

之后以此为规律循环往复。

       根据经验值,建议PWM波周期设为10毫秒,LED灯显示的亮度效果是最好的。在完全掌握了设计原理可以独立完成设计后,可以再进行不同波型以及不同占空比的尝试。

三、代码

(1)顶层模块

module pwm_light(
  clk,
  rst_n,
  led
);

input   clk  ;
input   rst_n;
output  led  ;
 
wire [7:0]    led ;
wire [3:0]    x;
wire          m;

//pwm灯的例化
pwm uut_pwm(
   .clk(clk),
   .rst_n(rst_n),
   .x_in(x), //接收控制占空比的条件
   .m_out(m),//输出计数2s的加一条件
   .led(led)
);

//计数20次的例化
count uut_count(
   .clk(clk),
   .rst_n(rst_n),
   .m_in(m),//接收计数2s的加一条件
   .x_out(x)//输出控制占空比的条件
);                       
endmodule      

(2)pwm模块(用于产生周期10ms的脉冲波)

module pwm(
  clk,
  rst_n,
  m_out,
  x_in,
  led
);

input   clk   ;
input   rst_n ;
input   x_in  ; 
output  m_out ;
output  led   ;

reg  [18:0]  cnt     ;
wire         add_cnt ;
wire         end_cnt ;
wire [3:0]   x_in    ;
reg  [7:0]   led     ;
wire         m_out   ;
reg  [18:0]  f       ;

parameter   TIME_10ms = 500_000;

//计数pwm的10ms周期
always @(posedge clk or negedge rst_n)begin
if(!rst_n) begin
    cnt <= 0;
    end
else if(add_cnt) begin
    if(end_cnt)
        cnt <= 0;
    else
        cnt <= cnt + 1;
    end
end

assign add_cnt = 1;    //加一条件
assign end_cnt = add_cnt && cnt== TIME_10ms - 1;    //结束条件

assign m_out = end_cnt; //赋值2s计数器的加一条件

//led灯
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0) begin
    led <= 8'b00000000;
    end
else if(add_cnt && cnt == f-1) begin
    led <= 8'b11111111;
	 end
else if(end_cnt) begin
    led <= 8'b00000000;
	 end
end

//控制占空比
always@(*) begin
if(x_in==1-1)begin 
  f=475_000;
  end
else if(x_in==2-1)begin 
  f=425_000;
  end
else if(x_in==3-1)begin
  f=350_000;
  end
else if(x_in==4-1)begin 
  f=250_000;
  end
else if(x_in==5-1)begin
  f=100_000;
  end
else if(x_in==6-1)begin
  f=100_000;
  end
else if(x_in==7-1)begin
  f=250_000;
  end
else if(x_in==8-1)begin
  f=350_000;
  end
else if(x_in==9-1)begin
  f=425_000;
  end
else if(x_in==10-1)begin
  f=475_000;
  end
end

endmodule

 (3)count模块(用于led的控制)

module count(
   clk,
	rst_n,
	m_in,
   x_out
);  


input   clk   ;
input   rst_n ;
input   m_in  ;
output  x_out ;

reg  [7:0]   cnt1     ;
wire         add_cnt1 ;
wire         end_cnt1 ;
reg  [3:0]   cnt2     ; 
wire         add_cnt2 ;
wire         end_cnt2 ;
wire [3:0]   x_out    ;
wire         m_in     ;

parameter  TIME_1s = 200;
parameter  TIME_20 = 10;


//计数2s
always @(posedge clk or negedge rst_n)begin
if(!rst_n) begin
    cnt1 <= 0;
    end
else if(add_cnt1) begin
    if(end_cnt1)
        cnt1 <= 0;
    else
        cnt1 <= cnt1 + 1;
    end
end

assign add_cnt1 = m_in;    //加一条件
assign end_cnt1 = add_cnt1 && cnt1== TIME_1s - 1;    //结束条件


//计数10次
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
end

assign add_cnt2 = end_cnt1;    //加一条件
assign end_cnt2 = add_cnt2 && cnt2== TIME_20 - 1;    //结束条件
assign x_out = cnt2; //赋值控制占空比的条件

endmodule

四、仿真代码及图像

(1)仿真代码

`timescale 1 ps/ 1 ps
module pwm_light_vlg_tst();

reg        clk;
reg      rst_n;                                             
wire [7:0] led;

parameter CYCLE=20;

                        
pwm_light i1 ( 
	.clk(clk),
	.led(led),
	.rst_n(rst_n)
);

initial begin
 clk=0;
 forever#(CYCLE/2)begin
   clk=~clk;
	end
end

initial begin
 #1;
 rst_n=0;
 #(CYCLE*10);
 rst_n=1;
end
endmodule

仿真时,更改了计数器的计数次数,为了波形的更快输出。

(2)图像

 五、综合图像

六、上板

pwm呼吸灯

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值