FPGA(三):使用Verilog实现呼吸灯

工程教育中级课上老师把这道题作为延伸拓展题,在讲解了大致思路后我对呼吸灯也有了一定的了解,最开始尝试自己编写了一部分,但是并没有完全实现,后来想想还是自己对于概念上理解不够透彻,后面在网上参考别人优秀的代码和说明后渐渐明白了其中的机制,以下是自己写的呼吸灯代码以及一些思路过程。

实现流程

1、
呼吸灯分为两个部分,一个部分是 由亮变暗,
一个部分是 由暗变亮。

2、
当由亮变暗,也就是:
首先,占空比100%为零,
然后,占空比99%为零,1%为1;等于占空比100%
然后,占空比98%为零,2%为1;等于占空比100%

然后,占空比2%为零,98%为1;等于占空比100%
然后,占空比1%为零,99%为1;等于占空比100%

3、
当由暗变亮,也就是:
首先,占空比100%为1,
然后,占空比99%为1,1%为零;等于占空比100%
然后,占空比98%为1,2%为零;等于占空比100%

然后,占空比2%为1,98%为零;等于占空比100%
然后,占空比1%为1,99%为零;等于占空比100%

功能分解

1、定义:一个完整的呼吸灯时间为2s,也就是,由亮变暗需要1s,由暗变亮需要1s;
2、将1s分为1000等份,也就是 由亮变暗,需要100次的变化,每次为1ms;
3、将1ms分为1000等份,占空比100%过渡到0%,需要1000次的变化,每次为1us。

硬件开发板说明:

1、cyclone III:EP3C5E144C8
2、时钟24M

代码实现

module	breath_light(
	input clk,  // 24M
	output reg [2:0]led
	);

// 寄存器
reg	[9:0]	cnt_s;
reg	[9:0]	cnt_ms;
reg	[4:0]	cnt_us;
reg	a;

// 初始化
parameter	T_s = 10'd999;	 // 1000
parameter	T_ms = 10'd999; // 1000
parameter	T_us = 5'd23;   // 1us
initial
	begin
		a <= 1'b0;
		led <= 3'b000;
		cnt_s <= 10'd0;
		cnt_ms <= 10'd0;
		cnt_us <= 5'd0;
	end
	
// 1us
always @ (posedge clk)
	begin 
		if(cnt_us == T_us)
			cnt_us <= 5'd0;
		else 
			cnt_us <= cnt_us +5'd1;
	end
	
// 1ms
always @ (posedge clk )
	begin 
		if(cnt_us == T_us && cnt_ms == T_ms)
			cnt_ms <= 10'd0;
		else if(cnt_us == T_us)
			cnt_ms <= cnt_ms + 10'd1;
	end
	
// 1s
always @ (posedge clk)
	begin 
		if(cnt_us == T_us && cnt_ms == T_ms && cnt_s == T_s)
			cnt_s <= 10'd0;
		else if(cnt_us == T_us && cnt_ms == T_ms)
			cnt_s <= cnt_s + 10'd1;
	end
	
// 标志位
always @ (posedge clk)
	begin  
		if(cnt_us == T_us && cnt_ms == T_ms && cnt_s == T_s)
			a <= ~a;
		else
			a <= a;
		end
		
// 亮灯
always @ (posedge clk )
	begin 
		if(cnt_s > cnt_ms && a ==1'b1)
			led <= 3'b111;
		else if(cnt_s < cnt_ms && a ==1'b1)
			led <= 3'b000;
		else if(cnt_s > cnt_ms && a ==1'b0)
			led <= 3'b000;
		else if(cnt_s < cnt_ms && a ==1'b0)
			led <= 3'b111;
		end
endmodule 

经验证,该代码没有问题,后面有时间会出一篇用modelsim仿真验证的博客,敬请期待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值