当前位置:   article > 正文

FPGA的呼吸灯设计案例(verilog实现)_fpga呼吸灯verilog

fpga呼吸灯verilog

案例1:呼吸灯0

实现功能:4个LED同时改变,亮度由PWM信号控制。

实验现象:

4个LED,灭→亮,逐渐变亮,到达最亮后熄灭,再从灭→亮,重复进入下一次循环。

代码实现:

module pwm(
    input clk,
    input rst_n,
    
    output reg  [3:0] led
);

reg [15:0] pwm0,count;

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        count <= 16'b0;
    else begin
        count <= count + 1'b1;
        if(count[15]==1)    //打到周期预设定的数值,就清零
           count <= 16'b0;

        if(count < pwm0)        //如果本周期中,周期小于PWM脉宽计数,那么LED就=1
            led <= 4'b1111;
        else 
            led <= 4'b0000;            //PWM的低脉冲时候,就为0
        end
 end
 
 
 always @(posedge count[14]) begin         //一个周期前面一点,产生PWM加/减 信号
 
   pwm0 <= pwm0 + 1'b1;                                //PWM 在一个周期完成之前加1,用于下一个周期的信号宽度
   if(pwm0[13]==1)                               //脉宽达到预设定的数值
    pwm0 <= 16'b0;
    
 end 

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

案例2:呼吸灯1

实现功能:4个LED同时改变,亮度由PWM信号控制。

实验现象:

第1秒:灭→亮,逐渐变亮,达到最亮,

第2秒:亮→灭,逐渐变暗;

……

2s一个周期,重复进入下一次循环。

代码实现:

module breath_led(
   input        clk,
   input        rst_n,
   output  reg [3:0] led
 );
 
 reg flag;
 
 // 计数器cnt_2us循环计数,计到99为2us 
 parameter cnt_2us_max = 7'd100 - 1'b1;
 reg [6:0] cnt_2us;

 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     cnt_2us <= 7'd0;
   else if(cnt_2us == cnt_2us_max)
     cnt_2us <= 7'd0;
   else
     cnt_2us <= cnt_2us + 1'b1;
 end

 // 计数器cnt_2ms循环计数,计到999为2ms 
 parameter cnt_2ms_max = 10'd1000 - 1'b1;
 reg [9:0] cnt_2ms;

 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
      cnt_2ms <= 10'd0;
   else if(cnt_2us == cnt_2us_max && cnt_2ms == cnt_2ms_max)
      cnt_2ms <= 10'd0;
   else if(cnt_2us == cnt_2us_max)
      cnt_2ms <= cnt_2ms + 1'b1;
   else
      cnt_2ms <= cnt_2ms;
 end

 // 计数器cnt_2s循环计数,计到999为2s 
 parameter cnt_2s_max = 10'd1000 - 1'b1;
 reg [9:0] cnt_2s;

 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
      cnt_2s <= 10'd0;
   else if(cnt_2us == cnt_2us_max && cnt_2ms == cnt_2ms_max && cnt_2s == cnt_2s_max)
      cnt_2s <= 10'd0;
   else if(cnt_2us == cnt_2us_max && cnt_2ms == cnt_2ms_max)
      cnt_2s <= cnt_2s + 1'b1;
   else
      cnt_2s <= cnt_2s;
 end
 
 //flag标志
 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
      flag <= 1'd0;
   else if(cnt_2us == cnt_2us_max && cnt_2ms == cnt_2ms_max && cnt_2s == cnt_2s_max)
      flag <= ~flag;
   else 
      flag <= flag;
 end 
 

 //brearh_led控制
 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
      led <= 4'b0000;
   else if(cnt_2s >= cnt_2ms && flag == 1'b0)
      led <= 4'b1111;
   else if(cnt_2s < cnt_2ms && flag == 1'b0)
      led <= 4'b0000; 
    else if(cnt_2s >= cnt_2ms && flag == 1'b1)
      led <= 4'b0000;  
   else if(cnt_2s < cnt_2ms && flag == 1'b1)
      led <= 4'b1111;      
   else 
      led <= 4'b0000;
 end
 
 endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

案例3:呼吸灯2

实现功能:4个LED同时改变,亮度由PWM信号控制。

实验现象:

占空比越大,LED灯越暗;
占空比越小,LED灯越亮。

第1个2秒: pwm_time <= 19’d450_000;//占空比90%

第2个2秒: pwm_time <= 19’d350_000;//占空比70%

第3个2秒:pwm_time <= 19’d250_000;//占空比50%

第4个2秒:pwm_time <= 19’d100_000;//占空比20%

第5个2秒:pwm_time <= 19’d50_000;//占空比10%

第6个2秒: pwm_time <= 19’d5_000;//占空比1%

第7个2秒: pwm_time <= 19’d100_000;//占空比20%

第8个2秒:pwm_time <= 19’d250_000;//占空比50%

第9个2秒:pwm_time <= 19’d350_000;//占空比70%

第10个2秒: pwm_time <= 19’d450_000;//占空比90%

……

20s一个周期,重复进入下一次循环。

代码实现:

module breathing_led(
   input        clk,
   input        rst_n,
   output  reg [3:0] led
 );
 
 reg flag;
 
 // 计数器cnt_10ms循环计数,计到499999为10ms 
 parameter cnt_10ms_max = 19'd500_000 - 1'b1;
 reg [18:0] cnt_10ms;

 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     cnt_10ms <= 19'd0;
   else if(cnt_10ms == cnt_10ms_max)
     cnt_10ms <= 19'd0;
   else
     cnt_10ms <= cnt_10ms + 1'b1;
 end

 // 计数器cnt_2s循环计数,计到199为2s 
 parameter cnt_2s_max = 8'd200 - 1'b1;
 reg [7:0] cnt_2s;

 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
      cnt_2s <= 8'd0;
   else if(cnt_10ms == cnt_10ms_max && cnt_2s == cnt_2s_max)
      cnt_2s <= 8'd0;
   else if(cnt_10ms == cnt_10ms_max)
      cnt_2s <= cnt_2s + 1'b1;
   else
      cnt_2s <= cnt_2s;
 end

 // 计数器cnt_20s循环计数,计到9为20s 
 parameter cnt_20s_max = 4'd10 - 1'b1;
 reg [3:0] cnt_20s;

 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
      cnt_20s <= 4'd0;
   else if(cnt_10ms == cnt_10ms_max && cnt_2s == cnt_2s_max && cnt_20s == cnt_20s_max)
      cnt_20s <= 4'd0;
   else if(cnt_10ms == cnt_10ms_max && cnt_2s == cnt_2s_max)
      cnt_20s <= cnt_20s + 1'b1;
   else
      cnt_20s <= cnt_20s;
 end

 
reg [18:0] pwm_time;

 //pwm控制brearhing_led
 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
      led <= 4'b0000;
   else if(cnt_10ms == pwm_time-1'b1)
      led <= 4'b1111;     
   else if(cnt_10ms == cnt_10ms_max) 
      led <= 4'b0000;
   else
      led <= led;
 end
 
 //改变pwm信号的占空比
 always @(*) begin
   case(cnt_20s)
      4'd0: pwm_time <= 19'd450_000;//90%     
      4'd1: pwm_time <= 19'd350_000;//70% 
      4'd2: pwm_time <= 19'd250_000;//50% 
      4'd3: pwm_time <= 19'd100_000;//20%
      4'd4: pwm_time <= 19'd50_000;//10%
      4'd5: pwm_time <= 19'd5_000;//1%
      4'd6: pwm_time <= 19'd100_000;//20% 
      4'd7: pwm_time <= 19'd250_000;//50% 
      4'd8: pwm_time <= 19'd350_000;//70%  
      4'd9: pwm_time <= 19'd450_000;//90% 
      default: pwm_time <= 19'd0;
 endcase 
 end
 
 endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84

说明:

本文的3个案例,在正点原子FPGA开拓者开发板上亲测有效。

案例中LED的管脚分配如下:
在这里插入图片描述
参考资料0: 最简单的FPGA verilog写的 PWM 例子.

参考资料1: FPGA实现呼吸灯功能实验.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/791167
推荐阅读
相关标签
  

闽ICP备14008679号