呼吸灯记录

呼吸灯

  1. 如何通过高低电平-数字信号输出实现呼吸灯的效果?
    灯“呼吸”的效果分为两部分,一个过程是从灭到亮,另一个过程是从亮到灭。 led 灯供的电压越大 led 灯也就越亮,通过改变led灯的电压来控制亮度,但I/O口是输出数字信号,所以这里通过控制 PWM 的占空比来实现 led 灯呼吸的效果。

PWM
PWM详解

脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM就是在合适的信号频率下,通过一个周期里改变占空比的方式来改变输出的有效电压。
要输出不同的模拟电压,就要用到PWM,通过改变IO口输出的方波的占空比从而获得使用数字信号模拟成的模拟电压信号。比如下图
在这里插入图片描述

  1. 怎么改变占空比?
    在本次实验中取 n 个相同的时间段,然后让高电平的持续时间按照相等的时间间隔逐渐增多,这样子我们看上去的 led 灯就会越来越亮了。相反,让低电平的持续时间按照相等的时间间隔逐渐增多,led等就会越来越暗。

  2. 对于亮暗怎么区分这两个过程?
    为了区分从灭到亮和从亮到灭两个过程我们使用一个模式(标志)信号,这个模式信号不是脉冲,而是一个电平,更准确的来讲应该叫使能信号。在高低电平期间实现两个过程。

  3. 代码

module	breath_led
#(
	parameter CNT_MAX1us = 6'd49,
	parameter CNT_MAX1ms = 10'd999,
	parameter CNT_MAX1s = 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			mode;
//cnt_1us:1us 计数器
always@(posedge	sys_clk or negedge	sys_rst_n)
	if (sys_rst_n == 0 )
		cnt_1us <= 6'd0;
	else	if (cnt_1us == CNT_MAX1us)
		cnt_1us <= 6'd0;
	else	
		cnt_1us <= cnt_1us + 1;
 //cnt_1ms:1ms 计数器
always@(posedge	sys_clk or negedge	sys_rst_n)
	if (sys_rst_n == 0)
		cnt_1ms <= 10'b0;
	else	if (cnt_1us == CNT_MAX1us)
		cnt_1ms <= cnt_1ms + 10'b1;
	else	if (cnt_1ms == CNT_MAX1ms && cnt_1us == CNT_MAX1us )
		//这里并不是1ms计数到最大值就归0,而是要1us也到最大值才能清零,
		//否则最后一个1ms会很短
		cnt_1ms <= 10'b0;
		
//cnt_1s:1s 计数器
always@(posedge	sys_clk or negedge	sys_rst_n)
	if (sys_rst_n == 0 )
		cnt_1s <= 10'd0;
	else if (cnt_1ms == CNT_MAX1ms && cnt_1us == CNT_MAX1us)
		cnt_1s <= cnt_1s + 10'd1;
	else	if (cnt_1s == CNT_MAX1s && cnt_1ms == CNT_MAX1ms && cnt_1us == CNT_MAX1us )
		cnt_1s <= 10'd0;
		
//mode:1s 计数器标志信号
always@(posedge	sys_clk or negedge	sys_rst_n)
	if (sys_rst_n == 0 )
		mode<= 1'd1;
	else if (cnt_1s == CNT_MAX1s  && cnt_1ms == CNT_MAX1ms && cnt_1us == CNT_MAX1us)
		mode <= ~mode;
		
//led_out:输出信号连接到外部的 led 灯
always@(posedge	sys_clk or negedge	sys_rst_n)
	if (sys_rst_n == 0 )
		led_out <= 1'd0;
	else if ((mode == 1'b1 && cnt_1ms <= cnt_1s) || (mode == 1'b0 && cnt_1ms >= cnt_1s))
		led_out <= 1'b1;
	else 
		led_out <= 1'b0;

endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值