[原创] 基于FPGA的呼吸灯

一纸玫瑰   2016-10-26 15:06 楼主

基于FPGA的呼吸灯

一、目标

1、占空比(pwm)的理解。

2、计数器的应用。

3、分频的应用。

二、要求

四个LED灯从暗逐渐变亮,然后从亮逐渐变暗形成呼吸的效果。

三、思路导航

    要做出呼吸的led(初始值为高电平)要求led的低电平逐渐积累至完全为低电平,然后将生成的改波形取反即可。我们要求LED灯从亮到暗需要2s,期间我们要进行1000份,故每一份为2ms,因此低电平时间为20us,系统时钟为50MHz

四、思路框架

  
file:///C:/Users/wwt/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png
  


五、代码

  
module led_breath(
  
    input       wire            sclk,//50MHz
  
    input       wire            rst_n,//系统复位
  
   
  
    output      wire    [3:0]    led//输出的led
  
);
  
  
parameter   CNT_2US_MAX = 7'd99;//计数20us
  
parameter   CNT_2MS_MAX = 10'd999;//计数2ms
  
parameter   CNT_2S_MAX = 10'd999;//计数2s
  
  
  
reg [6:0]       cnt_2us ;
  
reg              cnt_2us_flag;
  
reg [9:0]       cnt_2ms ;
  
reg              cnt_2ms_flag;
  
reg [9:0]       cnt_2s;
  
reg              cnt_4s;
  
  
reg             pwm;
  
wire            pwm_r;
  
wire            pwm_led;
  
  
assign          pwm_r = ~pwm;
  
  
//计数2us进程
  
always@(posedge sclk or negedge rst_n)
  
    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;      
  
  
//产生2us标志信号
  
always@(posedge sclk or negedge rst_n)
  
    if(!rst_n)
  
         cnt_2us_flag <= 1'b0    ;
  
    else if(cnt_2us == CNT_2US_MAX)
  
         cnt_2us_flag <= 1'b1    ;   
  
    else
  
         cnt_2us_flag <= 1'b0    ;   
  
         
  
//计数2ms进程
  
always@(posedge sclk or negedge rst_n)
  
    if(!rst_n)
  
         cnt_2ms <= 10'd0        ;
  
    else if((cnt_2ms == CNT_2MS_MAX) && (cnt_2us_flag))
  
         cnt_2ms <= 10'd0        ;
  
    else if(cnt_2us_flag)
  
         cnt_2ms <= cnt_2ms + 1'b1;      
  
         
  
//产生2ms标志信号
  
always@(posedge sclk or negedge rst_n)
  
    if(!rst_n)
  
         cnt_2ms_flag <= 1'b0    ;
  
    else if((cnt_2ms == CNT_2MS_MAX) && (cnt_2us_flag))
  
         cnt_2ms_flag <= 1'b1    ;
  
    else
  
         cnt_2ms_flag <= 1'b0    ;           
  
         
  
//计数2s进程
  
always@(posedge sclk or negedge rst_n)
  
    if(!rst_n)
  
         cnt_2s <= 10'd0;
  
    else if((cnt_2s == CNT_2S_MAX) && (cnt_2ms_flag))
  
         cnt_2s <= 10'd0;
  
    else if(cnt_2ms_flag)
  
         cnt_2s <= cnt_2s + 1'b1;
  
         
  
//4s产生标志信号
  
always@(posedge sclk or negedge rst_n)
  
    if(!rst_n)
  
         cnt_4s <= 1'b0;
  
    else if((cnt_2s == CNT_2S_MAX) && (cnt_2ms_flag))
  
         cnt_4s <= ~cnt_4s;                  
  
  
//产生呼吸灯效果
  
always@(posedge sclk or negedge rst_n)
  
    if(!rst_n)
  
         pwm <= 1'b0;
  
    else if(cnt_2ms >= cnt_2s)  
  
         pwm <= 1'b1;
  
    else
  
         pwm <= 1'b0;
  
                        
  
assign pwm_led = (cnt_4s == 1'b0) ? pwm : pwm_r;        
  
assign led = {pwm_led,pwm_led,pwm_led,pwm_led};
  
  
endmodule
  
  

六、仿真图

  
file:///C:/Users/wwt/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg
  

由仿真图和我们的思路框架相对比可得,两者一样。




回复评论 (7)

多谢楼主分享
training
点赞  2016-10-26 15:57
顶一下
点赞  2016-10-26 16:23
顶一个,以前想自己写一个,结果效果不是很理想,等着试试楼主的程序
点赞  2016-10-26 16:26
引用: hljjxzhla 发表于 2016-10-26 16:26
顶一个,以前想自己写一个,结果效果不是很理想,等着试试楼主的程序

可以   ,如果实现不了   可以交流
点赞  2016-10-26 17:27
顶一下
点赞  2016-10-31 12:29
用16M的时钟实现了一下
点赞  2016-11-1 17:19
谢谢分享,正准备开始pwm
点赞  2016-11-14 11:11
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复