基于FPGA的彩灯控制器设计.docx
《基于FPGA的彩灯控制器设计.docx》由会员分享,可在线阅读,更多相关《基于FPGA的彩灯控制器设计.docx(13页珍藏版)》请在冰豆网上搜索。
![基于FPGA的彩灯控制器设计.docx](https://file1.bdocx.com/fileroot1/2022-12/31/74395291-8401-4428-aa2a-c0b1f4c0b82b/74395291-8401-4428-aa2a-c0b1f4c0b82b1.gif)
基于FPGA的彩灯控制器设计
《EDA原理及应用》
课程设计报告
课题名称:
基于数码管显示的彩灯控制器
院系:
机电工程学院
专业:
电子信息工程
*********************************
学生学号:
************
彩灯及数码管显示控制
摘要
随着科技的发展,在现代生活中,彩灯作为一种景观应用越来越多。
而在电子电路设计领域中,电子设计自动化(EDA)工具已成为主要的设计手段,VHDL语言则是EDA的关键技术之一,它采用自顶向下的设计方法,即从系统总体要求出发,自上至下地将设计任务分解为不同的功能模块,最后将各功能模块连接形成顶层模块,完成系统硬件的整体设计。
本文介绍了基于EDA技的多路彩灯控制器的设计与分析。
在MAX+PLUSII环境下采用VHDL语言实现,论述了基于VHDL语言和FPGA芯片的数字系统设计思想和实现过程。
电子设计自动化技术EDA的发展给电子系统的设计带来了革命性的变化,EDA软件设计工具,硬件描述语言,可编程逻辑器件使得EDA技术的应用走向普及。
FPGA是新型的可编程逻辑器件,采用FPGA进行产品开发可以灵活地进行模块配置,大大缩短了产品开发周期,也有利于产品向小型化,集成化的方向发展。
关键词:
VHDL彩灯仿真
1、概述
1.1、设计目的:
设计一个彩灯控制器,使彩灯(LED管)可以实现彩灯逐渐增多及两种不同频率的闪烁,有复位开关。
整个系统有四个输入信号clk,option,fan,clr,三个输出信号控制俩个八路彩灯及数码管显示。
option的高低电平控制彩灯闪烁的快慢,fan的高低电平控制彩灯的逐渐增多减少。
1.2、设计要求:
◆掌握FPGA的程序设计方法。
◆掌握硬件描述语言语法。
◆程序设计完成后要求在软件中实现功能仿真。
2、系统设计
2.1、设计原理:
整个系统共有四个输入信号:
基准时钟信号clk,系统清零信号(复位信号)clr,彩灯节奏快慢选择开关option;共有3个输出信号ledout[7..0],shuguan[6..0],doubleled[7..0],分别用于控制彩灯及数码管的显示。
据此,我们可将整个彩灯控制器CDKZQ分为四大部分:
彩灯花样控制部分、分频部分、定时部分和计数部分。
当各个模块均完成上述操作之后,形成最后的彩灯显示系统,并且进行仿真。
仿真通过,即可下载到指定的FPGA芯片里面,并进行实际连线,进行最后的硬件测试。
把分频部分的不同频率的时钟信号CP输送到计数部分,从而控制彩灯闪烁速度的快慢,定时部分控制每种速度维持的时间长短。
原理图
模块原理图
管脚图
2.2、设计方案:
在电路中以1代表灯亮,以0代表灯灭,由0、1按不同的规律组合代表不同的灯光图案,同时使其选择不同的频率,从而实现多种图案多种频率的花样功能显示。
在该电路中只需简单的修改程序就可以灵活地调整彩灯图案和变化方式。
下面就以一个彩灯控制系统的实现为例进行简单说明。
此彩灯控制系统设定有两种花样变化。
彩灯图案状态变换的速度有快、慢两种。
3、程序仿真图
startcompilation先编译
generatefunctionalsimulationnetlist然后生成功能仿真网络表
assignments–setting—simulationsetting设置成功能仿真
然后新建一个vectorwaveformfile
通过view—utilitywindows--nodefinder把输入输出管脚添加进波形仿真图里点击startsimulation
得到仿真图WAVEFORM1:
4、实验结果分析
实验表明,此设计方法能够满足多种不同花样彩灯的变化要求,并且该方法便于扩展不同变化模式的彩灯花样,同时又实现了彩灯的两种不同频率的闪烁。
如果不按任何按键时候,灯就按四种花样顺序循环跑,如果按下某个键再松开,比如按下C键然后松开,那么不管之前灯跑到哪个花样,按键后灯就会从C代表的花样处开始跑,然后是D花样,然后是A花样,依次循环。
但是A,B,C,D认为是按下会弹起的按键,因为这个程序里,如果一直按着按键不松手,会导致灯只是反复跑一个花样。
比如按着B键不松手,那么就会反复跑B花样。
还有不能允许同时按下两个键,三个键,4个键,也就是说,同一时刻ABCD只能有一个是高电平,否则会出错,因为这个程序并没有防错机制。
5、心得体会
本次设计的课题是彩灯控制器的设计,当拿到这个课题的时候经过分析就知道关键是计数器和分频器的使用,分频的方法有很多种,对于同一种功能的实现,用VHDL可以采用多种方式进行描述,每种方式之间各有优劣,本次设计只采用了其中较简单的一种,应尽量用最简洁的语言写出所需功能的程序。
通过这次课程设计对EDA技术有了更进一步的熟悉,VHDL 语言和C语言等其他语言还是有很大的区别。
VHDL是EDA技术的重要组成部分,其具有与具体硬件电路无关和与设计平台无关的特性,并且具有良好的电路行为描述和系统描述的能力,并在语言易读性和层次化、结构化设计方面,表现了强大的生命力和应用潜力。
其主要的也是最大的优点就在于设计者可以专心致力于其功能的实现,而不需要对不影响功能的与工艺有关的因素花费过多的时间和精力。
在实际操作中发现设计和课本上的知识有很大联系,但又高于课本,一个简单的原理要把它应用以及和其他功能综合起来就有些困难。
通过设计也巩固了我们的书本知识以及通过借阅书籍和上网查找资料,也丰富了自己对EDA的了解。
6、致谢
7、参考文献
[1]周润景.基于QuartusⅡ的FPGA/CPLD数字系统设计实例[M].电子工业出版社.2007,8
[2]潘松黄继业.EDA技术实用教程(第二版).北京:
科学出版社,2006.9
[3]林明权马维旻VHDL数字控制系统设计范例.电子工业出版社2003,1
[4]褚振勇.FPGA设计及应用(第三版)[M].西安电子科技大学出版社.2012,4
8、附录
彩灯显示控制器的源程序
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
----Uncommentthefollowinglibrarydeclarationifinstantiating
----anyXilinxprimitivesinthiscode.
--libraryUNISIM;
--useUNISIM.VComponents.all;
entitycolorledis
Port(clk:
inSTD_LOGIC;
clr:
inSTD_LOGIC;
option:
inSTD_LOGIC;
fan:
instd_logic;
ledout:
outSTD_LOGIC_VECTOR(7downto0);
shuma:
outstd_logic_vector(6downto0);
doubleled:
outstd_logic_vector(7downto0));
endcolorled;
architecturertlofcolorledis
componenttimeris
port(clk:
instd_logic;
clr:
instd_logic;
option:
instd_logic;
fan:
instd_logic;
fanout:
outstd_logic;
clkout:
outstd_logic);
endcomponenttimer;
componentshoweris
port(clk:
instd_logic;
clr:
instd_logic;
fanin:
instd_logic;
ledout:
outstd_logic_vector(7downto0);
shuma:
outstd_logic_vector(6downto0);
doubleled:
outstd_logic_vector(7downto0));
endcomponentshower;
signalclk_tmp:
std_logic;
signalfan_tmp:
std_logic;
begin
U1:
timerportmap(clk,clr,option,fan,fan_tmp,clk_tmp);
U2:
showerportmap(clk_tmp,clr,fan_tmp,ledout,shuma,doubleled);
endrtl;
以上为顶层文件代码
以下为分频计数模块及彩灯显示控制模块的代码
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
----Uncommentthefollowinglibrarydeclarationifinstantiating
----anyXilinxprimitivesinthiscode.
--libraryUNISIM;
--useUNISIM.VComponents.all;
entitytimeris
Port(clk:
inSTD_LOGIC;--时钟
clr:
inSTD_LOGIC;--复位
fan:
instd_logic;
fanout:
outstd_logic;
option:
inSTD_LOGIC;--快慢分频
clkout:
outSTD_LOGIC);--输出时钟
endtimer;
architecturertloftimeris
signalclk_tmp:
std_logic;
signalfan_tmp:
std_logic;
--signalcounter:
std_logic_vector(1downto0);--计数器
signalcounter:
integerrange0to16000000;
begin
process(clk,clr,option)
begin
ifclr='1'then
clk_tmp<='0';
counter<=0;
elsifclk'eventandclk='1'then
ifoption='0'then--四分频
ifcounter=16000000then
counter<=0;
clk_tmp<=notclk_tmp;
else
counter<=counter+1;
endif;
else--八分频
ifcounter=8000000then
counter<=0;
clk_tmp<=notclk_tmp;
else
counter<=counter+1;
endif;
endif;
endif;
endprocess;
--begin
--ifclr='1'then
--clk_tmp<='0';
--counter<="00";
--elsifclk'eventandclk='1'then
--ifoption='0'then--四分频
--ifcounter="01"then
--counter<="00";
--clk_tmp<=notclk_tmp;
--else
--counter<=counter+'1';
--endif;
--else--八分频
--ifcounter="11"then
--counter<="00";
--clk_tmp<=notclk_tmp;
--else
--counter<=counter+'1';
--endif;
--endif;
--endif;
--endprocess;
clkout<=clk_tmp;--输出分频时钟
fan_tmp<=fan;
fanout<=fan_tmp;
endrtl;
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
----Uncommentthefollowinglibrarydeclarationifinstantiating
----anyXilinxprimitivesinthiscode.
--libraryUNISIM;
--useUNISIM.VComponents.all;
entityshoweris
Port(clk:
inSTD_LOGIC;
clr:
inSTD_LOGIC;
fanin:
instd_logic;
ledout:
outSTD_LOGIC_VECTOR(7downto0);
shuma:
outstd_logic_vector(6downto0);--8位彩灯输出
doubleled:
outstd_logic_vector(7downto0));
endshower;
architecturertlofshoweris
typestatesis
(s0,s1,s2,s3,s4,s5,s6,s7);--Moore状态
signalstate:
states;
begin
process(clk,clr,fanin)
begin
ifclr='1'then
state<=s0;
ledout<="00000000";
doubleled<="00000000";
shuma<="0000000";
elsifclk'eventandclk='1'then
casestateis
whens0=>
iffanin='1'then
state<=s7;
ledout<="11111110";
doubleled<="11111110";
shuma<="1111001";
else
state<=s1;
ledout<="00000000";
doubleled<="00000000";
shuma<="0000000";
endif;
whens1=>
iffanin='1'then
state<=s0;
ledout<="00000000";
doubleled<="00000000";
shuma<="0000000";
else
state<=s2;
ledout<="10000000";
doubleled<="10000000";
shuma<="1111000";
endif;
whens2=>
iffanin='1'then
state<=s1;
ledout<="10000000";
doubleled<="10000000";
shuma<="1111000";
else
state<=s3;
ledout<="11000000";
doubleled<="11000000";
shuma<="0000010";
endif;
whens3=>
iffanin='1'then
state<=s2;
ledout<="11000000";
doubleled<="11000000";
shuma<="0000010";
else
state<=s4;
ledout<="11100000";
doubleled<="11100000";
shuma<="0010010";
endif;
whens4=>
iffanin='1'then
state<=s3;
ledout<="11100000";
doubleled<="11100000";
shuma<="0010010";
else
state<=s5;
ledout<="11110000";
doubleled<="11110000";
shuma<="0011001";
endif;
whens5=>
iffanin='1'then
state<=s4;
ledout<="11110000";
doubleled<="11110000";
shuma<="0011001";
else
state<=s6;
ledout<="11111000";
doubleled<="11111000";
shuma<="0110000";
endif;
whens6=>
iffanin='1'then
state<=s5;
ledout<="11111000";
doubleled<="11111000";
shuma<="0110000";
else
state<=s7;
ledout<="11111100";
doubleled<="11111100";
shuma<="0100100";
endif;
whens7=>
iffanin='1'then
state<=s6;
ledout<="11111100";
doubleled<="11111100";
shuma<="0100100";
else
state<=s0;
ledout<="11111110";
doubleled<="11111110";
shuma<="1111001";
endif;
endcase;
endif;
endprocess;
endrtl;