目录<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
一.方案分析与对比································2
1.1方案分析······································2
1.2方案对比······································2
二.整体设计论述··································3
三.单元模块设计与仿真····························6
3.1时钟分频模块·································6
3.2交通灯控制及计时模块··························7
3.3扫描显示译码模块······························9
3.4顶层文件的编写·······························10
四.硬件实验方案及实验结果·······················13
4.1硬件实验方案·································13
4.2实验结果·····································15
五.收获和体会···································15
六.参考文献·····································13
附录(程序代码)··································17
一.方案分析与对比
§1.1方案分析
通过分析可以知道,所要设计的交通信号灯控制电路要能够适用于由一条主干道和一条支干道的汇合点形成的十字交叉路口。能够做到主、支干道的红绿灯闪亮的时间不完全相同,在绿灯跳变红灯的过程中能够用黄灯进行过渡,使得行驶过程中的车辆有足够的时间停下来。还要求在主、支干道各设立一组计时显示器,能够显示相应的红、黄、绿倒计时。可以利用VHDL语言合理设计系统功能,使红黄绿灯的转换有一个准确的时间间隔和转换顺序。
§1.2方案对比
实现路口交通灯系统的控制方法很多,可以用标准逻辑器件、可编程序控制器和单片机等方案来实现。
若用单片机方案来实现的话,模型可以由电源电路、单片机主控电路、无线收发控制电路和显示电路四部分组成。在电源电路中,需要用到+5V的直流稳压电源,无线收发控制电路和显示电路应由编码芯片和数据发射模块两部分组成,主控电路的主要元件为AT89C51。硬件设计完成后还要利用计算机软件经行软件部分的设计才能够实现相应的功能。
虽然利用单片机系统设计的交通灯控制器相对来说较稳定,能够完成较多功能的实现,但这些控制方法的功能修改及调试都需要硬件电路的支持,在一定程度上增加了功能修改及系统设计与调试的困难。
相反,使用基于FPGA的设计方法具有周期短,设计灵活,易于修改等明显的的优点。而且,随着FPGA器件、设计语言和电子设计自动化工具的发展和改进,越来越多的电子系统采用FPGA来设计。未来,使用FPGA器件设计的产品将出现在各个领域里。因此,此次的交通信号灯控制器的设计将采用基于FPGA的设计方案来实现所要求的功能。
二.整体设计论述
根据设计要求和系统所具有的功能,并参考相关的文献资料,经行方案设计,可以画出如下图所示的交通信号灯控制器的系统框图。<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
CLK |
时钟分频模块 |
交通灯控制及计时模块 |
扫描显示译码模块 |
CAR |
1kHZ 数码管及LED信号
数码管段码 |
数码管位码 |
LED显示 |
系统的状态图如下所示
CAR='0'
S0 |
CAR='1' c="1001111"
CAR='0'
S1 |
S4 |
c="1001111" CAR='1'
c="0101100" c="1001010"
S3 |
S2 |
c="0110001"
S0:支干道没有车辆行驶,支干道绿灯,支干道红灯
S1:支干道有车辆行驶,支干道绿灯,支干道红灯
S2:主干道黄灯,支干道绿灯
S3:主干道红灯,支干道绿灯
S4:主干道红灯,支干道黄灯
根据以上设计思路,可以得到如下的顶层文件原理图
顶层文件的实体图:
三.单元模块设计与仿真
§3.1时钟分频模块
系统的动态扫描需要1HZ的脉冲,而系统时钟计时模块需要1HZ的脉冲。分频模块主要为系统提供所需的时钟计时脉冲。该模块将1kHZ的脉冲信号进行分频,产生1S的方波,作为系统时钟计时信号。其实体模块如下:
将END TIME改为5S
CLK采用系统的1KHZ的时钟脉冲
仿真波形如下:
可以看到能够得到1s的时钟脉冲
§3.2交通灯控制及计时模块
控制模块根据外部输入信号和计时模块产生的输出信号,产生系统的状态机,控制其他部分协调工作。计时模块用来设定主干道和支干道计时器的初值,并为扫描显示译码模块提供倒计时时间。
控制及计时模块采用状态机进行设计,可以定义出5种状态,分别为S0:主干道绿灯,支干道红灯且没有车辆行驶;S1:主干道绿灯,支干道红灯或支干道有车辆驶入;S2:主干道黄灯,支干道红灯;S3:主干道红灯,支干道绿灯;S4:主干道红灯,支干道黄灯。利用CASE语句定义状态的转换方式及时间的变换方式,达到主干道绿灯亮45秒,支干道绿灯亮25秒,黄灯亮5秒的设计要求。
其实体模块如下:
CAR为支干道车辆检测开关
在支干道有车的情况下,模块可以进行减计时
CLK1S为1S的时钟脉冲
TIME1H、TIME1L、TIME2H、TIME2L分别为主干道时钟高位、主干道时钟低位、支干道时钟高位、支干道时钟低位
LED为LED灯发光情况,分别为主干道绿灯、主干道黄灯、主干道红灯、支干道绿灯、主干道黄灯、主干道红灯
Count的总的系统时间,用来改变系统的状态
仿真波形如下:
通过仿真可以看到:
当主干道绿灯,支干道红灯时,主干道倒计时高位置数0100,低位置数0101;支干道高位置数0101,低位置数0000;
当主干道黄灯,支干道红灯时,主干道黄灯倒计时置数0101;支干道继续刚才的减计数;
当主干道红灯,支干道绿灯时,主干道倒计时高位置数0011,低位置数0000;支干道高位置数0010,低位置数0101;
当主干道红灯,支干道黄灯时,支干道黄灯倒计时置数0101;主干道继续刚才的减计数。
在S4状态结束后,自动跳回到S0状态,继续判断支干道是否有车行驶,若有车行驶,则跳转到S1状态,给高、低位置数,继续进行减计时。
系统根据COUNT的变化自动在各状态下跳变,当count为45时,跳变到S2状态;当count为50时,跳变到S3状态;当count为75时,跳变到S4状态;当count为80时,若支干道没有车跳变到S0状态,有车则跳变到S1状态。
§3.3扫描显示译码模块
扫描显示译码模块可以根据控制信号,驱动交通信号灯以及倒计时数码管的显示,其中数码管的显示采用动态扫描显示。其实体模块如下:
CLK为1KHZ的系统时钟脉冲
CLK1S为1S时钟脉冲
CAR为支干道车辆检测开关
SEL为数码管位码扫描
SEG为数码管段码
TIME1H、TIME1L、TIME2H、TIME2L为数码管计时的时间,由控制及计时模块为其赋值
仿真波形如下:
通过仿真可以看到:
给CLK一个时钟脉冲,数码管的位码随CLK时钟的变化而进行扫描,由于CLK的频率较高,人的眼睛会有短暂的视觉停留,所以会看到4个数码管都在显示时间。
§3.4顶层文件的编写
将以上各个单元模块仿真成功后,再进行顶层文件的编写。将各个单元模块的变量赋值给顶层文件,从而将各个单元模块连接起来,统一调配。得到顶层文件的实体模块:
CLK为1KHZ系统时钟脉冲
CAR为支干道车辆行驶情况,高电平为有车行驶,低电平为无车行驶
LED为交通灯发光情况
SEL为数码管位码扫描
SEG为数码管段码
仿真波形如下:
仿真后可以得到最终的结果:
开始时,支干道没有车辆行驶。主干道处于常通行状态,支干道处于禁止状态;当支干道有车来时,主干道亮绿灯,经行45秒倒计时,支干道亮红灯,经行50秒倒计时;
主干道45秒倒计时结束后跳变到黄灯,进行5秒倒计时,支干道继续亮红灯,进行倒计时;
主干道5秒倒计时结束后跳变到红灯,经行30秒倒计时,支干道跳变到绿灯,进行25秒倒计时;
支干道25秒倒计时结束后跳变到黄灯,进行5秒倒计时,主干道继续亮红灯,进行倒计时;
支干道5秒倒计时结束后,判断支干道是否有车,若有车跳变到S1状态,没有车跳变到S0状态
四.硬件实验方案及实验结果
将程序进行编译后,就可以把管脚绑定后把程序下载到实验板上进行调试了。
§4.1硬件实验方案
管脚绑定如下所示
| TO | Location | I/O Bank |
1 | CLK | PIN_152 | 3 |
2 | CAR | PIN_160 | 3 |
3 | SEG[0] | PIN_175 | 3 |
4 | SEG[1] | PIN_176 | 3 |
5 | SEG[2] | PIN_177 | 3 |
6 | SEG[3] | PIN_178 | 3 |
7 | SEG[4] | PIN_179 | 3 |
8 | SEG[5] | PIN_180 | 3 |
9 | SEG[6] | PIN_1 | 1 |
10 | SEL[0] | PIN_3 | 1 |
11 | SEL[1] | PIN_4 | 1 |
12 | SEL[2] | PIN_5 | 1 |
13 | LED[0] | PIN_170 | 3 |
14 | LED[1] | PIN_173 | 3 |
15 | LED[2] | PIN_174 | 3 |
16 | LED[3] | PIN_165 | 3 |
17 | LED[4] | PIN_166 | 3 |
18 | LED[5] | PIN_167 | 3 |
注:
CLK绑定时钟1KHZ
CAR绑定DK4
LED[0]绑定LED6;--支干道红灯
LED[1]绑定LED7;--支干道黄灯
LED[2]绑定LED8;--支干道绿灯
LED[3]绑定LED1;--主干道红灯
LED[4]绑定LED2;--主干道黄灯
LED[5]绑定LED3;--主干道绿灯
SEL[0]绑定LI0;
SEL[1]绑定LI1;
SEL[2]绑定LI2。
SEG[0]绑定G8;
SEG[1]绑定F8;
SEG[2]绑定E8;
SEG[3]绑定D8;
SEG[4]绑定C8;
SEG[5]绑定B8;
SEG[6]绑定A8;
将管脚按上图绑定后就可以下载到实验板上进行调试了
§4.2实验结果
将程序下载到实验板后,CAR置于低电平后,可以看到LED灯的显示情况为主干道亮绿灯,支干道亮红灯,主干道数码管显示45秒,支干道数码管显示50秒。但支干道有车时,把CAR置于高电平,可以看到主、支干道的数码管开始倒计时;主干道倒计时结束后再进行5秒倒计时,并且交通灯变为黄灯;当主干道倒计时结束后,主干道数码管显示30,支干道数码管显示25,主干道变为红灯,支干道变为绿灯,继续进行倒计时;支干道倒计时结束后再经行5秒倒计时,交通灯变为黄灯;支干道倒计时结束后再回到初始状态。
从实验板上可以看出硬件测试下的效果达到了设计的要求,能够实现交通信号灯控制器的基本功能。但是,由于实验板的系统时钟不稳定,导致数码管的扫描有时会出现闪动的现象,在更换了实验板后可以看出,数码管的扫描基本稳定,在视觉上不会出现闪动的情况。或者可以将系统的时钟频率改为2KHZ,更改分频模块后再进行编译下载,这样可以加快数码管扫描的速度,从而达到消除视觉上闪动的现象。
五.收获和体会
短短十天是EDA课程设计很块就结束了,虽然在之前的学习过程中还存在着没有弄懂的问题,但是通过这次设计,进一步加深了对EDA的了解,让我对它有了更加浓厚的兴趣。
在拿到题目后,首先进行了单元模块的设计,将每一个单元模块设计完成后再经行仿真,仿真成功后就可以进行顶层文件的编写了,在顶层文件的编写过程中遇到了一些问题,特别是各模块之间的连接,以及信号的定义,总是有错误。有的时候信号的定义容易出现混淆,在反复的修改过后,顶层文件终于能够编译成功了。
在波形仿真的过程中,同样遇到了困难,有的时候,由于END TIME的时间修改的太大,会出现仿真时间过长的问题,这个时候应该要把END TIME的时间相应的改小,或是修改系统时钟的频率。
在设计的过程中还应该多联系下实际情况,要了解实际情况下交通信号灯的工作情况,才能更好的完成此次的课程设计。在今后的工作和学习中,我们不能仅仅把目光停留在课本上,要多理论联系实际。有的时候,理论上是正确的东西放到现实中去,可能由于种种因素的制约,并不能达到实际的效果,还需要我们进行相应的修改才能完成要求。这次的课程设计使我巩固了以前学习到的知识,还使我掌握了以前没有掌握的知识,同时锻炼了自己的能力。
六.参考文献
【1】EDA技术与VHDL 清华大学出版社 潘松 黄继业
【2】数字电路EDA入门------VHDL程序实例集 北京邮电大学出版社
张亦华
【3】VHDL应用与开发实践 科学出版社 甘历
【4】CPLD/FPGA应用开发技术与工程实践 人民邮电出版社
【5】FPGA系统设计与实践 电子工业出版社 黄智伟
附录(程序代码)
时钟分频模块:
LILIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY fp IS
PORT(clk:IN STD_LOGIC;
CLK1S:OUT STD_LOGIC);
END fp;
ARCHITECTURE one OF fp IS
SIGNAL N: STD_LOGIC_VECTOR(9 DOWNTO 0);
BEGIN
PROCESS (clk)
BEGIN
IF clk'EVENT AND clk='1' THEN N<=N+1;
END IF;
END PROCESS;
CLK1S<=N(9);
END one;
交通灯控制及计时模块:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY kz IS
PORT (CLK1S,car:IN STD_LOGIC;--1S脉冲,支干道车辆检测
TIME1H,TIME1L:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--主干道计时
TIME2H,TIME2L:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--支干道计时
count:OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --系统总计时
led:OUT STD_LOGIC_VECTOR(5 DOWNTO 0)); --交通灯显示
END kz;
ARCHITECTURE one OF kz IS
TYPE states IS (s0, s1, s2,s3, s4); --状态初始化
SIGNAL current_state,next_state : states;
SIGNAL c:STD_LOGIC_VECTOR(6 DOWNTO 0);
BEGIN
REG:PROCESS(CLK1S,car,current_state,c)
BEGIN
IF car = '0' THEN current_state <= s0 ;
c<="0000000";
ELSE
IF CLK1S'EVENT AND CLK1S = '1' THEN --支干道有车开始计数
c <= c +1;
current_state <= next_state;
END IF;
END IF;
CASE current_state IS--状态转换
WHEN s0 => LED <= "100001"; --支干道无车不减计时
TIME1H<="0100";TIME1L<="0101";
TIME2H<="0101";TIME2L<="0000";
IF car = '1' THEN next_state <= s1;
ELSE next_state <= s0;
END IF;
WHEN s1 => LED <= "100001"; --主干道绿灯,支干道红灯
IF c="0101100" THEN next_state <= s2;
ELSE next_state <= s1;
END IF;
WHEN s2 => LED <= "010001"; --主干道黄灯,支干道红灯
IF c="0110001" THEN next_state <= s3;
ELSE next_state <= s2;
END IF;
WHEN s3 => LED <= "001100"; --主干道红灯,支干道绿灯
IF c="1001010" THEN next_state <= s4;
ELSE next_state <= s3;
END IF;
WHEN s4 => LED <= "001010"; --主干道红灯,支干道黄灯
IF c="1001111" THEN next_state <= s1;
ELSE next_state <= s4;
END IF;
WHEN OTHERS => LED <= "100001";next_state <= s0;
END CASE;
IF c="0101101" THEN TIME1H<="0000";TIME1L<="0101";--系统时间为45,主干道黄灯计时5秒
END IF;
IF c="0110010" THEN TIME1H<="0011";TIME1L<="0000";TIME2H<="0010";TIME2L<="0101";--系统时间为50,支干道计时30秒。支干道计时25秒
END IF;
IF c="1001011" THEN TIME2H<="0000";TIME2L<="0101";--系统时间为75,支干道黄灯计时5秒
END IF;
IF c="1010000" THEN TIME1H<="0100";TIME1L<="0101";TIME2H<="0101";TIME2L<="0000";--系统时间为80,主干道计时45,支干道计时50
END IF;
IF c="1010000" THEN c<="0000000";--系统时间清零
END IF;
END PROCESS REG;
count <= c;
END one;
扫描显示译码模块:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY xs IS
PORT(clk,CLK1S,car:IN STD_LOGIC;
TIME1H,TIME1L:IN STD_LOGIC_VECTOR(3 DOWNTO 0); --主干道置数
TIME2H,TIME2L:IN STD_LOGIC_VECTOR(3 DOWNTO 0); --支干道置数
count:IN STD_LOGIC_VECTOR(6 DOWNTO 0); --计数信号
sel:OUT STD_LOGIC_VECTOR(2 DOWNTO 0);--数码管位码
seg:OUT STD_LOGIC_VECTOR(6 DOWNTO 0));--数码管段码
END xs;
ARCHITECTURE one OF xs IS
SIGNAL num:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL numsel:STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL numseg:STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL Q1,Q2,Q3,Q4:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
SM:PROCESS (clk,num,numsel) --扫描
BEGIN
IF clk'EVENT AND clk='1' THEN numsel<=numsel+1;
IF numsel="011" THEN numsel<="000";
END IF;
END IF;
END PROCESS SM;
WX:PROCESS (numsel,Q1,Q2,Q3,Q4) --位选
BEGIN
CASE numsel IS
WHEN "000" =>num<=Q4;
WHEN "001" =>num<=Q3;
WHEN "010" =>num<=Q2;
WHEN "011" =>num<=Q1;
WHEN OTHERS =>NULL;
END CASE;
END PROCESS WX;
ZS:PROCESS(CLK1S,car,Q1,Q2,Q3,Q4,num,TIME1H,TIME1L,TIME2H,TIME2L)--数码管置数
BEGIN
IF car ='1' THEN
IF CLK1S'EVENT AND CLK1S = '1' THEN
IF Q2>"0000" THEN Q2<=Q2-1;
ELSE
IF Q1>"0000" THEN Q1<=Q1-1;Q2<="1001";
--减计时 END IF;
END IF;
IF Q4>"0000" THEN Q4<=Q4-1;
ELSE
IF Q3>"0000" THEN Q3<=Q3-1;Q4<="1001";
END IF;
END IF;
END IF;
IF Q1="0000" AND Q2="0000" THEN
Q1<=TIME1H;Q2<=TIME1L;
END IF;
IF Q3="0000" AND Q4="0000" THEN
Q3<=TIME2H;Q4<=TIME2L;
END IF;
ELSE Q1<=TIME1H;Q2<=TIME1L; --支路无车辆不减计时
Q3<=TIME2H;Q4<=TIME2L;
END IF;
END PROCESS ZS;
YM:PROCESS (num,numseg)
BEGIN
CASE num IS
WHEN "0000"=>numseg<="1111110";
WHEN "0001"=>numseg<="0110000";
WHEN "0010"=>numseg<="1101101";
WHEN "0011"=>numseg<="1111001";
WHEN "0100"=>numseg<="0110011";
WHEN "0101"=>numseg<="1011011";
WHEN "0110"=>numseg<="1011111";
WHEN "0111"=>numseg<="1110000";
WHEN "1000"=>numseg<="1111111";
WHEN "1001"=>numseg<="1111011";
WHEN OTHERS=>NULL;
END CASE;
END PROCESS YM;
sel<=numsel;
seg<=numseg;
END one;
顶层文件:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY jtd IS
PORT (clk:IN STD_LOGIC; --动态扫描时钟
car:IN STD_LOGIC; --支路车辆传感信号
led:OUT STD_LOGIC_VECTOR(5 DOWNTO 0); --交通灯信号
sel:OUT STD_LOGIC_VECTOR(2 downto 0); --数码管位码
seg:OUT STD_LOGIC_VECTOR(6 downto 0)); --数码管段码
END jtd;
ARCHITECTURE one OF jtd IS
COMPONENT fp --分频
PORT(clk: IN STD_LOGIC;
CLK1S: OUT STD_LOGIC);
END COMPONENT;
COMPONENT kz
PORT (
CLK1S,car:IN STD_LOGIC;
TIME1H,TIME1L:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
TIME2H,TIME2L:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
count:OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
led:OUT STD_LOGIC_VECTOR(5 DOWNTO 0));
END COMPONENT;
COMPONENT xs --倒计时显示
PORT(clk,CLK1S,car:IN std_logic;
TIME1H,TIME1L:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
TIME2H,TIME2L:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
count:IN STD_LOGIC_VECTOR(6 DOWNTO 0);
sel:OUT std_logic_vector(2 DOWNTO 0);
seg:OUT std_logic_vector(6 DOWNTO 0));
END COMPONENT;
SIGNAL CLK1S: std_logic;
SIGNAL count: STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL TIME1H,TIME1L,TIME2H,TIME2L: STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
U1: fp PORT MAP (clk=>clk,CLK1S=>CLK1S);
U2: kz PORT MAP (CLK1S=>CLK1S,car=>car,count=>count,led=>led,TIME1H=>TIME1H,TIME1L=>TIME1L,TIME2H=>TIME2H,TIME2L=>TIME2L);
U3: xs PORT MAP (clk=>clk,CLK1S=>CLK1S,car=>car,count=>count,sel=>sel,seg=>seg,TIME1H=>TIME1H,TIME1L=>TIME1L,TIME2H=>TIME2H,TIME2L=>TIME2L);
END ;
用户570876 2010-4-27 17:12
用户302218 2010-4-20 13:27