FPGA-DE2-115-实验一-亮度可调流水灯

前言:
本文主要介绍了集成电路EDA这门课程的相关实验及代码。使用的软件是Quartus Ⅱ,该实验使用fpga芯片为cyclone IV EP4CE115F29C7。

(一)实验目的

(1)熟悉流水灯的工作原理;
(2)了解设计中的优化方案;
(3)进一步掌握PWM信号的设计;

(二)设计要求

利用FPGA板及4个LED发光二极管,设计一个亮度可调流水灯程序:
其中流水灯亮度使用PWM驱动,并且可以使用按键切换不同亮度。

(三)实验原理

流水灯的实质是FPGA板各引脚在规定的时间逐个上电,使LED灯能逐个亮起来但过了该引脚通电的时间后便灭灯的过程,至于亮度可调则是使用PWM产生一定占空比的方波,实现输出电压变化,并可以通过调节占空比的大小改变输出电压值即LED灯的亮度。
实验中使用了单片机的P1端口和P4端口,对4个LED灯进行控制,要实现逐个亮灯即将各端口逐一置零,中间使用延时函数调用隔开各灯的亮灭。
本次实验先令四个灯全亮,延时500ms后再令四个灯全灭,之后点亮P4.7,P1.7两个灯,延时500ms后熄灭,之后依次点亮P4.7,P4.6,P1.7,P1.6,(一个灯点亮500ms后熄灭,第二个灯再点亮),然后反向,按照P1.6,P1.7,P4.6,P4.7顺序点亮一遍,如此往复循环。

(四)实验设备

(1)DE2-115型号FPGA板
(2)PC电脑

(五)实验结果

仿真图:
在这里插入图片描述

PWM波形使用cnt_1ms与tim变量大小来产生,当cnt_1ms<=tim时低电平否则高电平,图中可以看到,初始值tim=0,此时当cnt_1ms>tim时第一个灯亮,按下一次按键后,time自加8,此时当cnt_1ms<=8时,灯灭,否则第一个灯亮。
在这里插入图片描述

如上图所示,可以看到当cnt计数达到999时,由第二个灯亮变成第三个灯亮,证明完成了灯的流水操作。
实物图:
初始流水灯:
在这里插入图片描述

按下按键调节亮度后:
在这里插入图片描述

(六)结果分析

本次实验为了完成可调节亮度的流水灯的设计,首先产生0.5s脉冲使得每0.5s更改亮灯的位置,之后通过按键更改PWM产生波形中的占空比,从而调节灯的亮度。

代码:
1.顶层模块water_led

//4个led_out_reg灯,依次点亮,间隔0.5s   50Mhz-20ns	25000000次-25位
module	water_led
(
	input	wire				sys_clk     ,
	input	wire				sys_rst_n   ,
    input   wire                key1        ,
	output	reg	[3:0]		    led_out      	
);

parameter	CNT_MAX=25'd24_999_999  ;   //0.5s
parameter	CNT_1US_MAX=6'd49       ;	//1个时钟20ns,50个即1us
parameter	CNT_1MS_MAX=10'd999     ;	//计满1000个即1ms

wire            key1_flag;
reg			    cnt_flag;
reg  [9:0]      tim;
reg [24:0]	    cnt;
reg	[5:0]		cnt_1us;
reg	[9:0]		cnt_1ms;
reg	[9:0]		cnt_1s;
reg [3:0]       i;
//0.5s间隔闪烁
always @(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
		cnt<=25'd0;
	else if(cnt==CNT_MAX)
		cnt<=25'd0;
	else
		cnt<=cnt+25'd1;
//计数满0.5s标志位
always @(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
		cnt_flag<=1'd0;
	else if(cnt==CNT_MAX-1)
		cnt_flag<=1'd1;
	else
		cnt_flag<=1'd0;
        
//亮度变量调整
always @(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
        tim <= 10'd0;
    else if(tim >= 10'd999)
        tim <= 10'd0;
    else if(key1_flag)
        tim <= tim + 10'd80;
    else
        tim <= tim;

//cnt_1us
always@(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
		cnt_1us<=6'd0;
	else if(cnt_1us==CNT_1US_MAX)
		cnt_1us<=6'd0;
	else
		cnt_1us<=cnt_1us+6'd1;
//cnt_1ms
always@(posedge sys_clk or negedge sys_rst_n)
	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;
//每0.5s,i自加1,即更改亮灯位置
always @(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
        i <= 3'd0;
    else if((cnt_flag == 1'd1)&&(i == 3))
        i <= 3'd0;
    else if(cnt_flag == 1'd1)
        i <= i + 1'd1;
    else
        i <= i;      

//输出控制		
always @(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
		led_out <= 4'b0001;
    else    
        begin
            if(cnt_1ms<=tim)  
                led_out <= 4'b0000;  
            else
                case(i)
                    3'd0: led_out <= 4'b0001;   
                    3'd1: led_out <= 4'b0010;      
                    3'd2: led_out <= 4'b0100;       
                    3'd3: led_out <= 4'b1000;         
                    default: led_out <= 4'b0000;
                endcase
        end   
//按键滤波模块,按下按键后模块输出一个时钟周期的高脉冲
key_filiter key_filiter_inst
(
	.sys_clk   (sys_clk  )  ,
	.sys_rst_n (sys_rst_n)  ,
	.key_in    (key1      )  ,
	.key_flag  (key1_flag)
);
        
endmodule

2.按键模块key_filiter

//按键滤波器,按下按钮后即低电平输入,经过该模块输出一个系统时钟周期的高脉冲
module	key_filiter
(
	input		sys_clk     ,
	input		sys_rst_n   ,
	input		key_in      ,
	output	reg	key_flag
);

reg	[19:0]	cnt_20ms;
parameter	CNT_MAX=20'd999999;

always@(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
		cnt_20ms<=20'd0;
	else	if(key_in)
		cnt_20ms<=20'd0;
	else	if(cnt_20ms==CNT_MAX)	//最大值保持
		cnt_20ms<=CNT_MAX;
	else
		cnt_20ms<=cnt_20ms+1'd1;
		
always@(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
		key_flag<=1'b0;
	else	if(cnt_20ms==CNT_MAX-20'd1)
		key_flag<=1'b1;
	else
		key_flag<=1'b0;
		
endmodule

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值