呼吸灯实现

一、呼吸灯简介

呼吸灯:由灭渐亮,再由亮渐灭,模仿人呼吸方式的LED灯。

呼吸灯原理:PWM(Pulse Width Modulation),脉冲宽度调制。

在一定周期内改变高低电平占空比达到亮度渐变效果,高电平占比越多,LED灯越亮。(由亮渐灭为相反过程)

二、实验任务

本节实验任务是使用正点原子FPGA开发板上的LED,实现呼吸灯效果,即由灭渐亮,再由亮渐灭(渐亮和渐灭的时间为2s)。

三、程序设计

1.思维导图

2.波形图

3.代码编写

module breath_led(
    input        sys_clk,
    input        sys_rst_n,
    output   reg led   
    );

parameter   CNT_2US_MAX = 7'd100;
parameter   CNT_2MS_MAX = 10'd1000;
parameter   CNT_2S_MAX = 10'd1000;


    
reg  [6:0]  cnt_2us;
reg  [9:0]  cnt_2ms;
reg  [9:0]  cnt_2s;
reg         inc_dec_flag;   //亮度递增/递减标志位 0:递增 1:递减
  
//计数器计时2us
always @(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        cnt_2us <= 7'b0;
    else if(cnt_2us == (CNT_2US_MAX - 7'b1))
        cnt_2us <= 7'b0;
    else
        cnt_2us <= cnt_2us + 7'b1;
end

//计数器计时2ms
always @(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        cnt_2ms <= 10'b0;
    else if(cnt_2us == (CNT_2US_MAX - 7'b1) 
    && cnt_2ms == (CNT_2MS_MAX - 10'b1))
        cnt_2ms <= 10'b0;
    else if(cnt_2us == (CNT_2US_MAX - 7'b1))
        cnt_2ms <= cnt_2ms + 10'b1;
end

//计数器计时2s
always @(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        cnt_2s <= 10'b0;
    else if(cnt_2us == (CNT_2US_MAX - 7'b1) 
    && cnt_2ms == (CNT_2MS_MAX - 10'b1)
    && cnt_2s == (CNT_2S_MAX - 10'b1))
        cnt_2s <= 10'b0;
    else if(cnt_2us == (CNT_2US_MAX - 7'b1)
    && cnt_2ms == (CNT_2MS_MAX - 10'b1))
        cnt_2s <= cnt_2s + 10'b1;
end
  
//亮度递增/递减标志位
always @(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        inc_dec_flag <= 1'b0;
    else if(cnt_2us == (CNT_2US_MAX - 7'b1) 
    && cnt_2ms == (CNT_2MS_MAX - 10'b1)
    && cnt_2s == (CNT_2S_MAX - 10'b1))
        inc_dec_flag <= ~inc_dec_flag;
    else
        inc_dec_flag <= inc_dec_flag;
end

//控制LED灯PWM输出
always @(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        led <= 1'b0;
    else if(inc_dec_flag == 1'b0 && cnt_2ms <= cnt_2s)
        led <= 1'b1;
    else if(inc_dec_flag == 1'b1 && cnt_2ms >= cnt_2s)
        led <= 1'b1;
    else
        led <= 1'b0;
    
end
  

endmodule

4.实验仿真

编写tb_breath_led文件

'timescale  1ns/1ns  //仿真单位/仿真精度

module tb_breath_led();

parameter CLK_PERIOD = 20;

parameter   CNT_2US_MAX = 7'd1;
parameter   CNT_2MS_MAX = 10'd10;
parameter   CNT_2S_MAX = 10'd10;

reg        sys_clk;   //周期20ns
reg        sys_rst_n;

wire       led;

initial begin
    sys_clk <= 1'b0;
    sys_rst_n <= 1'b0;   
    #200
    sys_rst_n <= 1'b1;
    
end

always #(CLK_PERIOD/2) sys_clk = ~sys_clk;

breath_led #(
    .CNT_2US_MAX    (CNT_2US_MAX),
    .CNT_2MS_MAX    (CNT_2MS_MAX),
    .CNT_2S_MAX     (CNT_2S_MAX )
    )
    u_breath_led(
    .sys_clk        (sys_clk  ),
    .sys_rst_n      (sys_rst_n),
    .led            (led      ),
    );

endmodule

在modulesim仿真,以500ns为周期(减少仿真时间),下图为部分放大后仿真结果。

cnt_2s缩小后为2000ns。

cnt_2ms缩小后为200ns。

实验验证为预期输出。

四、下载验证

通过vivado创建工程,配置IO口和约束文件。

编译之后下载到开发板。

显示编译成功。

通过open target自动连接开发板再选择到指定文件(代码)下载

开发板实现控制效果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值