资源描述
《 CPLD/FPGA设计及应用课程设计》
课程设计报告
题 目: 基于FPGA的交通信号灯设计
院 (系): 信息科学与工程学院
专业班级: 通信工程
学生姓名:
20 16 年 03 月 14 日至20 16 年 04 月 8 日
目 录
一 设计目的 1
1.交通灯介绍 2
2. EDA技术的发展 2
3. 基于FPGA的交通灯的优点 3
二 设计过程 4
1.总体设计思路 4
2.总体设计模块 5
3. 控制电路的模块VHDL设计实现 6
3.1分频模块 6
3.2定时模块 7
3.3状态转换模块 8
3.4 禁止通行模块 12
3.5显示模块 14
4.硬件电路设计与调试 16
三 实验总结 17
参考文献 17
附录一(程序代码) 18
一 设计目的
引言:随着社会和汽车工业的快速发展,近几年机动车辆急剧增加,道路超负荷承载现象日趋严重,致使交通事故逐年增加。交通信号灯是城市交通有序、安全、快速运行的重要保障,而交通信号灯的正常工作就成了保障交通有序、安全、快速运行的关键。如何实现人、车、路三者关系的协调,已成为交通管理部门需要切实解决的问题。该设计分析了现代城市交通控制与管理问题的现状,结合城乡交通的实际情况阐述了交通灯控制系统的工作原理,采用了层次化的设计方法,基于VHDL语言实现红绿灯的自动指挥的硬件实现方法。通过电路优化设计,可以使用规模更小的可编程逻辑芯片,从而降低系统成本。
该设计是针对交通信号灯控制器的设计问题,采用EDA技术实现的交通灯控制电路的设计方案。本设计有效的克服了传统的交通灯控制的缺点而采取自上而下的设计思路。该设计在软件QuartusⅡ11.0下应用硬件描述语言VHDL语言完成设计文件,并对其进行了功能仿真和时序仿真,且给出了相应的仿真结果,绘制出了具体的逻辑电路,最后将其下载到Alter公司生产的CycloneⅡ系列的EP2C8Q208开发板上进行逻辑验证,实现软件和硬件的安全连接,达到了对交通灯的自动安全控制的目的。
关键字:交通灯控制;EDA; VHDL;QuartusⅡ;EP2C8Q208
1.交通灯介绍
当今,红绿灯安装在各个道口上,已经成为疏导交通车辆最常见和最有效的手段。但这一技术在19世纪就已出现了。1858年,在英国伦敦主要街头安装了以燃煤气为光源的红,蓝两色的机械扳手式信号灯,用以指挥马车通行。这是世界上最早的交通信号灯。1868年,英国机械工程师纳伊特在伦敦威斯敏斯特区的议会大厦前的广场上,安装了世界上最早的煤气红绿灯。1914年由红绿黄三色圆形的投光器组成的红绿灯始安装于纽约市5号大街的一座高塔上。1918年,又出现了带控制的红绿灯和红外线红绿灯。
信号灯的出现,使交通得以有效管制,对于疏导交通流量、提高道路通行能力,减少交通事故有明显效果。1968年,联合国《道路交通和道路标志信号协定》对各种信号灯的含义作了规定。绿灯是通行信号,面对绿灯的车辆可以直行,左转弯和右转弯,除非另一种标志禁止某一种转向。左右转弯车辆都必须让合法地正在路口内行驶的车辆和过人行横道的行人优先通行。红灯是禁行信号,面对红灯的车辆必须在交叉路口的停车线后停车。黄灯是警告信号,面对黄灯的车辆不能越过停车线,但车辆已十分接近停车线而不能安全停车时可以进入交叉路口。
2. EDA技术的发展
EDA是电子设计自动化(Electronic Design Automation)的缩写,是指以计算机为工作平台,融合应用电子技术、计算机技术、智能化技术最新成果而研制成的电子CAD通用软件包,主要能辅助进行三方面的设计工作,即IC设计、电子电路设计和PCB设计。是从计算机辅助设计(CAD)、计算机辅助制造(CAM)、计算机辅助测试(CAT)和计算机辅助工程(CAE)的概念发展而来的。EDA技术就是以计算机为工具,设计者在EDA软件平台上,用硬件描述语言HDL完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真,直至对于特定目标芯片的适配编译、逻辑映射和编程下载的高层次的电子设计方法。EDA技术的出现,极大地提高了电路设计的效率和可用性,减轻了设计者的劳动强度。EDA技术是电子设计领域的一场革命,代表了当今电子设计技术的最新发展方向,目前正处于高速发展阶段,每年都有新的EDA工具问世。
3. 基于FPGA的交通灯的优点
传统的交通灯控制系统多数由单片机或PLC实现,基于EDA技术FPGA的设计方法设计交通灯系统就是使用硬件描述语言(HDL)来完成系统的设计文件,应用VHDL的数字电路实验降低了数字系统的设计难度,这在电子设计领域已得到设计者的广泛采用。具有周期短,设计灵活,易于修改等明显的优点,而且随着FPGA器件、设计语言和电子设计自动化工具的发展和改进,越来越多的电子系统采用FPGA来设计,还有,通过FPGA设计电子系统,一旦该系统可以达到一定规模的量产,很容易转化为ASIC芯片设计。相信在将来,FPGA设计方法将更大规模的应用于各种类型的电子系统设计中。
本设计就是针对交通信号灯控制器的设计问题,并采用自顶向底的设计思路。提出了基于VHDL语言的交通信号灯系统的硬件实现方法。通过对系统进行结构分析,采用了层次化的设计方法,给出了各个模块的VHDL程序,并且利用Quartus Ⅱ对应用程序进行了仿真,并给出了相应的仿真结果。在用VHDL语言进行电路设计时,应充分认识到VHDL语言的特点,从设计思想、语句运用及描述方法上等多方面对电路进行优化设计。通过电路优化设计,可以使用规模更小的可编程逻辑芯片,从而降低系统成本。
二 设计过程
1.总体设计思路
所要设计的交通信号灯控制电路,要能够适用于由一条主干道和一条支干道的汇合点形成的十字交叉路口,主、支干道的红绿灯闪亮时间不完全相同。具体的设计要求如下:实现控制一条主干道和一条次干道汇合组成的十字交叉路口,使主、支干道上的车辆行人交替通行,其中主干道车辆行人通行35秒,此时支干道上车辆行人禁止通行;支干道车辆通行25秒,同样此时主干道上车辆禁止通行。每当信号灯由绿灯转换成红灯之前,黄灯要先亮5秒,此时另一个干道红灯不变,禁止通行。在黄灯亮点亮5秒,以提示车辆行人。在主干道上安装有数码管,用来显示本道各信号灯闪亮的剩余时间。
外观示意图如图1所示:
主干道
红 黄 绿 计时器
灯 灯 灯 倒计时
支 红 灯
干 黄 灯
道 绿 灯
图1
1.在十字路口的两个方向上各设一组红黄绿灯,显示顺序其中一方向是绿灯、黄灯、红灯,另一方向是红灯、绿灯、黄灯。
2.设置一组数码管,以倒计时的方式显示允许通行或禁止通行时间,其中主
干道绿灯亮的时间是35s,支干道绿灯亮的时间是30s,黄灯亮的时间都是5s。
3.扩展:当紧急情况出现时,按下手动开关,两条道路都显示红灯,此时禁止通行,倒计时停止;按下控制开关,恢复正常。
2.总体设计模块
1.把由50M的有源晶振产生的现场可编程逻辑器件FPGA的系统时钟输入到分频模块,经分频模块分频产生频率为1Hz的时钟脉冲,作为控制定时模块、控制模块、紧急模块、计数模块的时钟信号,然后再由定时模块来控制紧急模块和控制模块,按照交通管理规则控制交通工作状态的切换,最后,由系统时钟和计数模块以及控制模块来共同控制计数器控制模块,计数器的时钟为1Hz,再把计数器控制模块送出的BCD码送给译码器译码后,送给数码管显示各方向直行绿灯的倒计时。
模块图如图2所示:
交 通 灯
状
态
转
换
模
块
计数模块
数 码 管
控制模块
分频模块
图2 控制系统模块图
2.CycloneⅡ系列的EP2C8Q208的脉冲为50MHZ,为了保证设计的精度,在设计的过程中采用两次分频,同时在设计过程中为了防止出现意外情况的发生,加入了一个控制信号控制交通灯的启用或停止,
交通信号实现原理如图3所示:
图3 交通灯实现模块图
3. 控制电路的模块VHDL设计实现
3.1分频模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity jiao_tong is
port(clk:in std_logic); --20MHz晶振时钟
end jiao_tong;
architecture fenpin of jiao_tong is
signal clk1khz,clk1hz:std_logic; ---分频信号包含1hz和1khz
begin
p1:process(clk)
variable count:integer range 0 to 9999;
begin
if clk'event and clk='1' then
if count=9999 then clk1khz<=not clk1khz;count:=0;
else count:=count+1;
end if;
end if;
end process p1;
p2:process(clk1khz) -------------------------1hz分频---
variable count:integer range 0 to 499;
begin
if clk1khz'event and clk1khz='1' then
if count=499 then clk1hz<=not clk1hz;count:=0;
else count:=count+1;
end if;
end if;
end process p2;
end fenpin;
3.2定时模块
p3:process(clk1hz)
variable a:std_logic; ---倒计时赋值标志位
variable qh:std_logic_vector(3 downto 0); ---计数的高位和低位
variable ql:std_logic_vector(3 downto 0);
begin
if clk1hz'event and clk1hz='1' then ----如果是下降延
if jin='0' then ---状态st1,主干道通行35s
if a='0' then
qh:="0011"; ql:="0100";
a:='1';
elsif qh=0and ql=1 then --如果倒计时结束,则转到st2状态
a:='0';
qh:="0000";
ql:="0000";
elsif ql=0 then ---实现倒计时35s
ql:="1001";
qh:=qh-1;
else
ql:=ql-1;
end if;
end if;
end if;
end if;
end p3;
3.3状态转换模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity jiao_tong is
port(
clk:in std_logic; --20MHz晶振时钟
jin:in std_logic); --禁止通行信号
end jiao_tong;
architecture one of jiao_tong is
type states is(st1,st2,st3,st4); ---4种状态
signal clk1khz,clk1hz:std_logic; ---分频信号包含1hz和1khz
signal one,ten:std_logic_vector(3 downto 0); --倒计时的个位和十位
signal cnt:std_logic_vector(1 downto 0);
signal data:std_logic_vector(3 downto 0); ---数码管扫描计数信号
signal seg7_temp:std_logic_vector(6 downto 0);
signal r1,r2,y1,y2,g1,g2:std_logic;
begin
p3:process(clk1hz) ------交通状态转换
variable stx:states;
variable a:std_logic; ---倒计时赋值标志位
variable qh:std_logic_vector(3 downto 0); ---计数的高位和低位
variable ql:std_logic_vector(3 downto 0);
begin
if clk1hz'event and clk1hz='1' then ----如果是下降延
case stx is
when st1=>if jin='0' then -------状态st1,主干道通行35s
if a='0' then
qh:="0011";
ql:="0100";
a:='1';
r1<='0';
y1<='0';
g1<='1';
r2<='1';
y2<='0';
g2<='0';
else
if qh=0 and ql=1 then --如果倒计时结束,则转到st2状态
stx:=st2;
a:='0';
qh:="0000";
ql:="0000";
elsif ql=0 then ---实现倒计时35s
ql:="1001";
qh:=qh-1;
else
ql:=ql-1;
end if;
end if;
end if;
when st2=>if jin='0' then ------状态st2,主干道黄灯倒计时5s
if a='0' then
qh:="0000";
ql:="0100";
a:='1';
r1<='0';
y1<='1'; ----主干道黄灯点亮
g1<='0';
r2<='1'; ----支干道红灯点亮
y2<='0';
g2<='0';
else
if ql=1 then ---如果倒计时结束,则转到st3状态
stx:=st3;
a:='0';
qh:="0000";
ql:="0000";
else
ql:=ql-1;
end if;
end if;
end if;
when st3=>if jin='0' then ----状态st3,支干道通行25S
if a='0' then
qh:="0010";
ql:="0100";
a:='1';
r1<='1'; ----主干道红灯点亮
y1<='0';
g1<='0';
r2<='0';
y2<='0';
g2<='1'; ----支干道绿灯点亮
else
if qh=0 and ql=1 then ----如果倒计时结束,则转到st4状态
stx:=st4;
a:='0';
qh:="0000";
ql:="0000";
elsif ql=0 then ----实现倒计时25S
ql:="1001";
qh:=qh-1;
else
ql:=ql-1;
end if;
end if;
end if;
when st4=>if jin='0' then ---状态st4,支干道黄灯倒计时5s
if a='0' then
qh:="0000";
ql:="0100";
a:='1';
r1<='1'; ---主干道红灯点亮
y1<='0';
g1<='0';
r2<='0';
y2<='1'; ---支干道黄灯点亮
g2<='0';
else
if ql=1 then -----如果倒计时结束,则转到st1状态
stx:=st1;
a:='0';
qh:="0000";
ql:="0000";
else
ql:=ql-1;
end if;
end if;
end if;
end case;
end if;
one<=ql;ten<=qh;
end process p3;
3.4 禁止通行模块
entity jiao_tong is
port(
clk:in std_logic; --20MHz晶振时钟
jin:in std_logic; --禁止通行信号
ra,ya,ga:out std_logic; --主干道红黄绿灯
rb,yb,gb:out std_logic); --支红黄绿灯
end jiao_tong;
architecture one of jiao_tong is
type states is(st1,st2,st3,st4); ---4种状态
signal clk1khz,clk1hz:std_logic; ---分频信号包含1hz和1khz
signal one,ten:std_logic_vector(3 downto 0); --倒计时的个位和十位
signal cnt:std_logic_vector(1 downto 0);
signal data:std_logic_vector(3 downto 0); ---数码管扫描计数信号
signal seg7_temp:std_logic_vector(6 downto 0);
signal r1,r2,y1,y2,g1,g2:std_logic;
begin
p4:process(jin,clk1hz,r1,r2,g1,g2,y1,y2,seg7_temp) -禁止通行信号数码管闪烁显示
begin
if jin='1' then
ra<=r1 or jin; ---主干道红灯点亮
rb<=r2 or jin; ---支干道红灯点亮
ga<=g1 and (not jin);
gb<=g2 and (not jin);
ya<=y1 and (not jin);
yb<=y2 and (not jin);
seg7(0)<=seg7_temp(0) and clk1hz; ------实现数码管闪烁显示
seg7(1)<=seg7_temp(1) and clk1hz;
seg7(2)<=seg7_temp(2) and clk1hz;
seg7(3)<=seg7_temp(3) and clk1hz;
seg7(4)<=seg7_temp(4) and clk1hz;
seg7(5)<=seg7_temp(5) and clk1hz;
seg7(6)<=seg7_temp(6) and clk1hz;
else
seg7<=seg7_temp;
ra<=r1;
rb<=r2;
ga<=g1;
gb<=g2;
ya<=y1;
yb<=y2;
end if;
end process p4;
3.5显示模块
p5:process(clk1khz) --------数码管动态扫描计数---
begin
if clk1khz'event and clk1khz='1' then
if cnt="01" then cnt<="00";
else cnt<=cnt+1;
end if;
end if;
end process p5;
p6:process(cnt,one,ten) ---------数码管动态扫描-----
begin
case cnt is
when "00"=>data<=one;scan<="01";
when "01"=>data<=ten;scan<="10";
when others=>null;
end case;
end process p6;
p7:process(data) --------------7段译码---
begin
case data is
when "0000" =>seg7_temp<="1000000"; --0
when "0001" =>seg7_temp<="1111001"; --1
when "0010" =>seg7_temp<="0100100"; --2
when "0011" =>seg7_temp<="0110000"; --3
when "0100" =>seg7_temp<="0011001"; --4
when "0101" =>seg7_temp<="0010010"; --5
when "0110" =>seg7_temp<="0000010"; --6
when "0111" =>seg7_temp<="1111000"; --7
when "1000" =>seg7_temp<="0000000"; --8
when "1001" =>seg7_temp<="0010000"; --9
when others=>seg7_temp<="1001111";
end case;
end process p7;
4.硬件电路设计与调试
本系统的主要逻辑设计由一片EP2C8Q208芯片完成,编写的VHDL源程序在Altera公司的逻辑综合工具 QuartusⅡ下经过编译和功能仿真测试后,针对下载芯片进行管脚配置,下载到EP2C8Q208芯片中,进行相应的硬件调试,调试结果与软件仿真的结果相吻合,验证了设计完成了预定功能。
以下是芯片引脚图图4和管脚配置图图 5:
EP2C8Q208芯片图4
引脚配置图5
三 实验总结
1.芯片的选取必须要于实验箱相一致,否则将会有硬件无法连接的错误。
2.引脚分配时要注意引脚的输入输出关系,否则将无法正常的进行数据传输
3.我用的是睿智基于EP2C8Q208芯片的FPGA开发板,数码管的硬件原理图只用到16个管脚,程序逻辑上用到了位选和段选的思想。开始写的程序直接对应每个数码管的端口,配置时发现有问题。
本次设计利用硬件描述语言VHDL编程,借助Altera公司的QuartusⅡ11.0软件环境下进行了编译及仿真测试,通过FPGA芯片实现了一个实用的交通信号灯控制系统,设计由于采用了EDA技术,不但大大缩短了开发研制周期,提高了设计效率,而且使系统具有设计灵活,实现简单,性能稳定的特点。实现了交通信号灯的安全控制。
参考文献
[1]孟庆辉.EDA技术实用教程[M].国防工业出版社,2008:99~167.
[2]谢自美.电子线路综合设计(第二版)[M].华中科技大学出版社,2006.
[3]马玲 彭敏.CPLD/FPGA设计及应用.华中科技大学出版,2005.7.
[4]俞一鸣.Altera可编程逻辑器件的应用与设计[M].机械工业出版社,2007.
附录一(程序代码)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity jiao_tong IS
port (
clk:in std_logic;--50MHZ晶振时钟
jin:in std_logic;--禁止通行信号
scan:out std_logic_vector(1 downto 0);
seg7:out std_logic_vector(6 downto 0);--段选
ra,ya,ga:out std_logic;--红黄绿
rb,yb,gb:out std_logic);--红黄绿
end jiao_tong;
architecture one of jiao_tong IS
type states is (st1,st2,st3,st4);
signal clk1khz,clk1hz:std_logic;--分频信号1HZ和1KHZ
signal one,ten:std_logic_vector(3 downto 0);
signal cnt:std_logic_vector(1 downto 0);
signal data:std_logic_vector(3 downto 0);--数码管扫描计数信号
signal seg7_temp:std_logic_vector(6 downto 0);
signal r1,r2,y1,y2,g1,g2:std_logic;
begin
p1:process(clk)
variable count : integer range 0 to 4999;
begin
if clk='1'and clk'event then
if count=4999 then clk1khz<=not clk1khz;count:=0;
else
count:=count+1;
end if;
end if;
end process p1;
p2:process (clk1khz)
variable count : integer range 0 to 2499;
begin
if clk1khz='1'and clk1khz'event then
if count=2499
then clk1hz<=not clk1hz;
count:=0;
else
count:=count+1;
end if;
end if;
end process p2;
p3: process(clk1hz) --交通状态转换
variable stx:states;
variable a:std_logic;--倒计时赋值标志位
variable qh:std_logic_vector(3 downto 0);--计数高位低位
variable ql:std_logic_vector(3 downto 0);
begin
if clk1hz'event and clk1hz='1' then--如果是上升沿
case stx is
when st1=>if jin='1' then --状态s1主干道通行35s
if a='0' then
qh:="0011";--3
ql:="0100";--4
a:='1';
r1<='1';--110 011
y1<='1';
g1<='0';
r2<='0';
y2<='1';
g2<='1';
else
if qh=0 and ql=1 then --如果倒计时结束,则转到st2状态
stx:=st2;
a:='0';
qh:="0000";--0
ql:="0000";--0
elsif ql=0 then --实现倒计时35s
ql:="1001";--低位减到9,高位自减1位
qh:=qh-1;
else
ql:=ql-1;--否则低位自减1
end if;
end if;
end if;
when st2=>if jin='1' then--状态st2主干道黄灯倒计时5s
if a='0' then
qh:="0000";--0
ql:="0100";--4s
a:='1';
r1<='1';--101 011
y1<='0';--主干道黄灯点亮
g1<='1';
r2<='0';--支干道红灯点亮
y2<='1';
g2<='1';
else
if ql=1 then--如果倒计时结束,则转到st3状态
stx:=st3;
a:='0';
qh:="0000";
ql:="0000";
else
ql:=ql-1;
end if;
end if;
end if;
when st3=>if jin='1' then--状态st3,支干道通行25s
if a='0' then
qh:="0010";--2
ql:="0100";--4s
a:='1';
r1<='0';--主干道红灯点亮 011 110
y1<='1';
g1<='1';
r2<='1';
y2<='1';
g2<='0';--支干道绿灯点亮
else
if qh=0 and ql=1 then--如果倒计时结束转到st4
stx:=st4;
a:='0';
qh:="0000";
ql:="0000";
elsif ql=0 then--实现倒计时25s
ql:="1001";
qh:=qh-1;
else
ql:=ql-1;
end if;
end if;
end if;
when st4=>if jin='1' then--状态st4支干道黄灯倒计时5s
if a='0' then
qh:="0000";--0
ql:="0100";--4s
a:='1';
r1<='0';--主干道红灯点亮 011 101
y1<='1';
g1<='1';
r2<='1';
y2<='0';--支干道黄灯点亮
g2<='1';
else
if ql=1 then--如果倒计时结束则转到st1
stx:=st1;
a:='0';
qh:="0000";
ql:="0000";
else
ql:=ql-1;
展开阅读全文