#4_PWM实现呼吸灯_FPGA的零基础入门学习与开发实践

 注:学习笔记主要参考:

  1.  【野火】FPGA系列教学视频,真正的手把手教学,“波形图”教学法,现场画波形图写代码,硬件基于野火FPGA EP4CE10征途系列开发板,已完结
  2. 《Verilog HDL数字系统设计及实践》刘睿强等编著
  3. 工程及代码文件都会开源在本人的GitHub仓库,对大家有帮助的话,麻烦点个Star。
  4. 章节内容有一定编程语言基础的门槛,我也尽可能的对内容写的详细简单。如果不出意外,栏目会持续更新到FPGA的图像处理领域。目前FPGA发展情况来看,将来的潜力很大。大家积极留言交流

在这个教学内容中,我们将通过实现一个呼吸灯来学习如何使用Verilog HDL进行FPGA开发,并了解PWM(脉冲宽度调制)的使用。

呼吸灯原理

呼吸灯的效果是通过逐渐增加和减少LED的亮度来实现的。在硬件上,这可以通过调整LED的供电时间来实现,即调整脉冲宽度调制(PWM)信号的占空比

PWM简介

PWM是一种通过调整脉冲的宽度(即占空比)来控制模拟电路的一种方法。占空比是指脉冲高电平的时间与整个脉冲周期的比例。通过调整占空比,我们可以控制LED的亮度。

实现步骤

  1. 生成PWM信号:首先,我们需要生成一个PWM信号。通常,这可以通过一个计数器实现,计数器的最大值决定了PWM信号的周期,而比较值则决定了占空比。当计数器的值小于比较值时,PWM输出为高电平;否则为低电平。这里我们使用3个计数器来实现,核心就是将50MHZ的时钟频率怎么换算成1s,然后前0.5s从熄灭到点亮,后0.5s从点亮到熄灭,通过占空比来调整灯的亮暗程度

  2. 调整占空比:为了实现呼吸效果,我们需要逐渐增加和减少占空比。这可以通过逐渐增加和减少比较值来实现。通常,我们可以设置一个方向标志,用于控制比较值是增加还是减少。

  3. 连接到LED:将生成的PWM信号连接到LED的控制引脚上,就可以看到呼吸灯效果了。

波形图绘制

示例代码

程序运行代码如下,代码进行绑定引脚后进行编译烧录,如何操作可以查看我的一片文章#1_按键点亮一个LED_FPGA的零基础入门学习与开发实践-CSDN博客

module breath_led
#(
    parameter CNT_1US_MAX = 6'd49,
    parameter CNT_1MS_MAX = 10'd999,
    parameter CNT_1S_MAX = 10'd999

)
(
    input   wire        sys_clk,
    input   wire        sys_rst_n,

    output  reg         led_out
);

reg [9:0]       cnt_1s;
reg [9:0]       cnt_1ms;
reg [5:0]       cnt_1us;
reg             cnt_en;

// 1us的计时器设置
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        cnt_1us <= 6'd0;
    else if(cnt_1us == CNT_1US_MAX) begin
        cnt_1us <= 6'd0;
    end
    else
        cnt_1us <= cnt_1us + 6'd1;
end
// 1ms的计时器设置
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        cnt_1ms <= 10'd0;
    else if((cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))
        cnt_1ms <= 10'd0;
    else if(cnt_1us == CNT_1US_MAX)
        cnt_1ms <= cnt_1ms + 10'd1;
    else
        cnt_1ms <= cnt_1ms;
end
// 1s计时器的设置
always@(posedge sys_clk or negedge sys_rst_n)begin 
    if(!sys_rst_n)
        cnt_1s <= 10'd0;
    else if((cnt_1s == CNT_1S_MAX) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))
        cnt_1s <= 10'd0;
    else if((cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))
        cnt_1s <= cnt_1s + 10'd1;
    else
        cnt_1s <= cnt_1s;
end
// 使能信号的设置
always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        cnt_en <= 1'b0;
    else if((cnt_1s == CNT_1S_MAX) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))
        cnt_en <= ~cnt_en;
    else
        cnt_en <= cnt_en;
end

// 输出信号的编写
always@(posedge sys_clk or negedge sys_rst_n)
    if(!sys_rst_n)
        led_out <= 1'b1;
    else if(((cnt_en == 1'b0)&&(cnt_1ms<=cnt_1s))
            || ((cnt_en == 1'b1)&&(cnt_1ms>cnt_1s)))
        led_out <= 1'b0;
    else
        led_out <= 1'b1;


endmodule

PWM呼吸灯,FPGA实现

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值