12 FPGA pwm呼吸灯

一、呼吸灯
能够产生呼吸灯有两种方式,第一种是通过调节电压的改变从而达到改变led灯的亮度,使其产生呼吸灯的效果,第二种是采取pwm波的形式,通过改变亮灭的占空比从而产生呼吸灯的效果。在fpga中改变电压控制led不太现实,所以就目前的学习程度来说还是采用pwm的形式。

二、实现
1.波形
在这里插入图片描述

(1)从亮到灭
在这里插入图片描述

由于板子上面的led是低电平点亮,所以此波形图主要是从亮慢慢变灭。但是另外一种情况由灭到亮也是通过led_out来输出,因此需要一个标志位cnt_led_en的低电平表示从亮到灭的过程,这个过程持续一秒钟,根据根据三个计数器的值计算可得。cnt_1us计满49向进1,而 cnt_1ms计满999向cnt_1s进1,直到cnt_1s计到999时,此时正好计数49999999共1s,对标志位取反进入由灭到亮的过程,从而循环往复。

(2)从灭到亮
在这里插入图片描述

(3)仿真波形
在这里插入图片描述

(4)输出条件

led_out的值时根据标志位以及cnt_1ms 和cnt_1s的大小共同确定输出时高电平还是低电平。其判断条件如下
在这里插入图片描述

2、程序
module breath_led
#(
parameter CNT_MAX_1US = 6’d49,
parameter CNT_MAX_1MS = 10’d999,
parameter CNT_MAX_1S = 10’d999

)
(
input wire sys_clk,
input wire sys_rst_n,

output reg led_out

);

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

always@(posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1’b0)
cnt_1us <= 6’d0;
else if (cnt_1us == CNT_MAX_1US)
cnt_1us <= 6’d0;
else
cnt_1us <= cnt_1us + 6’d1;

always@(posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1’b0)
cnt_1ms <= 10’d0;
else if ((cnt_1us == CNT_MAX_1US)&&(cnt_1ms == CNT_MAX_1MS))
cnt_1ms <= 10’d0;
else if (cnt_1us == CNT_MAX_1US)
cnt_1ms <= cnt_1ms + 10’d1;
else
cnt_1ms <= cnt_1ms;

always@(posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1’b0)
cnt_1s <= 10’d0;
else if ((cnt_1us == CNT_MAX_1US)&&(cnt_1ms == CNT_MAX_1MS)&&(cnt_1s == CNT_MAX_1S))
cnt_1s <= 10’d0;
else if ((cnt_1us == CNT_MAX_1US)&&(cnt_1ms == CNT_MAX_1MS))
cnt_1s <= cnt_1s + 10’d1;
else
cnt_1s <= cnt_1s;

always@(posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1’b0)
cnt_1s_en <= 1’b0;
else if ((cnt_1s == CNT_MAX_1S)&&(cnt_1ms == CNT_MAX_1MS)&&(cnt_1us == CNT_MAX_1US))
cnt_1s_en <= ~cnt_1s_en;
else
cnt_1s_en <= cnt_1s_en;

always@(posedge sys_clk or negedge sys_rst_n)
if (sys_rst_n == 1’b0)
led_out <= 1’b0;
else if (((cnt_1ms <= cnt_1s)&&(cnt_1s_en == 1’b1))
||((cnt_1ms >= cnt_1s)&&(cnt_1s_en == 1’b0)))
led_out <= 1’b0;
else if (((cnt_1ms > cnt_1s)&&(cnt_1s_en == 1’b1))
||((cnt_1ms < cnt_1s)&&(cnt_1s_en == 1’b0)))
led_out <= 1’b1;
else
led_out <= led_out;

endmodule

仿真程序
`timescale 1ns/1ns
module tb_breath_led ();

reg sys_clk;
reg sys_rst_n;

wire led_out;

initial
begin
sys_clk = 1’b0;
sys_rst_n <= 1’b0;
#20
sys_rst_n <= 1’b1;

end

always #10 sys_clk = ~sys_clk;

breath_led
#(
.CNT_MAX_1US(6’d20) ,
.CNT_MAX_1MS(10’d24) ,
.CNT_MAX_1S (10’d24)

)
breath_led_inst
(
.sys_clk (sys_clk ) ,
.sys_rst_n (sys_rst_n) ,

.led_out (led_out)

);

endmodule

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值