电子课程设计_交通灯
十字路口交通管理信号灯设计与制作
一、课程设计的性质、目的和任务
创新精神和实践能力二者之中,实践能力是基础和根本。这是由于创新基于实践、源于实践,实践出真知,实践检验真理。实践活动是创新的源泉,也是人才成长的必由之路。
通过课程设计的锻炼,要求学生掌握电路的一般设计方法,具备初步的独立设计能力,提高综合运用所学的理论知识独立分析和解决问题的能力,培养学生的创新精神。
二、课题设计基本要求
掌握现代大规模集成数字逻辑电路的应用设计方法,进一步掌握电子仪器的正确使用方法,以及掌握利用计算机进行电子设计自动化(EDA)的基本方法。能熟练运用EDA 软件和HDL 语言来设计电子电路,对电路进行仿真,模拟数字电路的电路基础知识,进而加深对课本知识的理解。
带有整点报时的数字钟的设计与制作的设计要求:
设计要求:
主干道绿灯亮的时间为8秒,闪烁3秒,黄灯亮的时间为2秒,红灯亮的时间为11秒。主干道上绿灯亮和闪烁、黄灯亮共13秒,这时支干道上的红灯一直亮着。
图 十字路口交通管理信号灯
支干道绿灯亮的时间为6秒,闪烁3秒,黄灯亮2秒,红灯亮的时间为13秒。支干道上的绿灯亮6秒、闪烁3秒及黄灯亮2秒,主干道上的红灯亮11秒。
三、课程设计内容
1、概述
a .主干道上绿灯亮的时间为8秒,数码管显示起始时间7秒,然后依次递减至0,绿灯闪烁3秒,黄灯亮的时间为2秒(这段时间数码管不显示) 。支干道红灯亮的时间为13秒,数码管显示起始时间为12秒,然后依次递减至0。
b .支干道上绿灯亮的时间为6秒,数码管显示起始时间5秒,然后依次递减至0,绿灯闪烁3秒,黄灯亮的时间为2秒(这段时间数码管不显示) ,主干道红灯亮的时间为11秒,数码管显示起始时间为10秒,然后依次递减至0。
2、程序设计流图与思路:
3、方案设计与论证
该任务主要由控制器模块,分频模块、计数模块、按键消抖模块、数码管选
择控制模块,顶层模块组成。
1、 分频模块:
因为自带的开发板的晶振频率为50MHz ,而我们设计数字钟的频率为1Hz ,所以我们必须要进行分频,分成1Hz 与50Hz 。
2、 计数模块:
利用我们分得的1Hz 的频率来产生整数的显示,进行交通灯的控制。
3、 按键的消抖模块:
因为按键在人为按下的时候会产生人为抖动,再者如果我们按下一次的话电脑不会自动自动检测我们是按下了一次还是好多次,所以我们就需要一个延迟程序来进行消抖。
4、 数码管选择控制模块:
其实在数字钟的显示中并不是每一个数码管都是一直亮着的,而是借助于人眼的时间有反应
间隔,所以我们利用这一特点给一个信号让数码管来一个动态扫描显示。再者就是在这个模块中来实现抢数字钟中将二进制码转换成7段的功能。
5、 按键控制模块:
在这个模块中主要实现复位设置功能。
4、单元电路设计
(一)各模块的程序(VHDL )
(1) 顶层模块的VHDL 源程序:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity light is
port
(
clk : in std_logic;
rst : in std_logic;
hold_in: in std_logic;
reda,greena,yellowa: out std_logic; ---- 主干方向
redb,greenb,yellowb: out std_logic; ---- 支干方向
sm_seg: out std_logic_vector(7 downto 0);
sm_bit: out std_logic_vector(7 downto 0)
);
end ;
architecture light_top of light is
signal clk50hz : std_logic;
signal countnum: integer range 0 to 24;
signal numa,numb: integer range 0 to 25;
signal flash : std_logic;
signal numa1,numa0,numb1,numb0: integer range 0 to 9;
signal clk1hz : std_logic;
signal reset : std_logic;
signal hold : std_logic;
signal displaya1 : std_logic_vector(7 downto 0);
signal displaya0 : std_logic_vector(7 downto 0);
signal displayb1 : std_logic_vector(7 downto 0);
signal displayb0 : std_logic_vector(7 downto 0);
component key_delay is
port
(
clk :in std_logic;
key_in:in std_logic;
key_out: out std_logic
);
end component;
component counter is
port
(
clk : in std_logic;
reset: in std_logic;
hold : in std_logic;
countnum: buffer integer range 0 to 24
);
end component;
component controller is
port
(
clk : in std_logic;
reset:in std_logic;
hold: in std_logic;
countnum:in integer range 0 to 24;
numa,numb: out integer range 0 to 25;
reda,greena,yellowa: out std_logic;
redb,greenb,yellowb: out std_logic;
flash : out std_logic
);
end component;
component fenwei is
port
(
numin: in integer range 0 to 25 ;
numa,numb: out integer range 0 to 9
);
end component;
component display is
port
(
clk : in std_logic;
flash : in std_logic;
qin : in integer range 0 to 9;
display : out std_logic_vector(7 downto 0)
);
end component ;
component fredevider is
port
(
clk50mhz : in std_logic;
clk1hz : out std_logic;
clk50hz : out std_logic
);
end component;
component scan_led is
port
(
clk :in std_logic;
displaya1 :in std_logic_vector(7 downto 0);
displaya0 :in std_logic_vector(7 downto 0);
displayb1 :in std_logic_vector(7 downto 0);
displayb0 :in std_logic_vector(7 downto 0);
sm_seg: out std_logic_vector(7 downto 0);
sm_bit: out std_logic_vector(7 downto 0)
);
end component ;
---================================----
begin
rst_sys: key_delay
port map
(
clk => clk,
key_in=>rst,
key_out=>reset
);
hold_sys: key_delay
port map
(
clk => clk,
key_in=>hold_in,
key_out=>hold
);
fre: fredevider ---分频
port map
(
clk50mhz => clk,
clk1hz => clk1hz,
clk50hz => clk50hz
);
count : counter ----系统计数器 用来控制交通灯的状态机
port map
(
clk => clk1hz ,
reset => reset,
hold => hold,
countnum => countnum
);
ctl : controller ---交通灯控制
port map
(
clk =>clk,
reset=>reset,
hold=> hold,
countnum=> countnum,
numa=>numa,
numb=>numb,
reda =>reda,
greena=>greena,
yellowa=>yellowa,
redb=>redb,
greenb=>greenb,
yellowb=>yellowb,
flash =>flash
);
fwa : fenwei ---分位模块分出十位和个位 东西分位
port map
(
numin=>numa,
numa=> numa1,
numb=> numa0
);
fwb : fenwei ---分位模块分出十位和个位 南北分位
port map
(
numin=>numb,
numa=> numb1,
numb=> numb0
);
displayaa1: display -----东西个位(带闪烁功能的数码管显示)
port map
(
clk => clk50hz,
flash =>flash,
qin =>numa1,
display =>displaya1
);
displayaa0: display ----东西十位
port map
(
clk => clk50hz,
flash =>flash,
qin =>numa0,
display =>displaya0
);
displaybb1: display ----个位
port map
(
clk => clk50hz,
flash =>flash,
qin => numb1,
display =>displayb1
);
displaybb0: display ----十位
port map
(
clk => clk50hz,
flash =>flash,
qin => numb0,
display =>displayb0
);
scan: scan_led ---动态扫描
port map
(
clk =>clk50hz,
displaya1 =>displaya1,
displaya0 =>displaya0,
displayb1 =>displayb1,
displayb0 =>displayb0,
sm_seg=>sm_seg,
sm_bit=>sm_bit
);
end ;
(2)交通灯控制模块的VHDL 模块:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity controller is
port
(
clk : in std_logic;
reset:in std_logic;
hold: in std_logic;
countnum: in integer range 0 to 24;
numa,numb: out integer range 0 to 25;
reda,greena,yellowa: out std_logic;
redb,greenb,yellowb: out std_logic;
flash : out std_logic
);
end controller;
architecture ctl of controller is
signal next_status:integer;
signal ctl_status:integer ;
constant ctl_green :integer:=0;
constant ctl_yellow:integer:=1;
constant ctl_red :integer:=2;
constant ctl_hold :integer:=3;
begin
process(clk,reset) ------the selection of staues
begin
if reset='1' then
ctl_status
elsif clk'event and clk='1' then
case ctl_status is
when ctl_green => if hold='1' then
ctl_status
elsif countnum= 11 then
ctl_status
end if ;
when ctl_yellow => if hold='1' then
ctl_status
elsif countnum=13 then
ctl_status
end if ;
when ctl_red => if hold='1' then
ctl_status
elsif countnum=0 then
ctl_status
end if ;
when ctl_hold => if hold='0' then
ctl_status
end if ;
when others => ctl_status
end if ;
end process;
--------next_status
process(clk,reset)
begin
if reset='1' then
next_status
elsif clk'event and clk='1' then
if ctl_status=ctl_green then
if countnum
next_status
else
next_status
end if ;
elsif ctl_status=ctl_yellow then
if countnum
next_status
else
next_status
end if ;
elsif ctl_status=ctl_red then
if countnum
next_status
else
next_status
end if ;
--if countnum >24 then -- countnum
--------data
process(clk,reset) begin
if reset='1' then --初始状态 numa
elsif clk'event and clk='1' then if ctl_status=ctl_green then
numa
yellowa
numb
if countnum=10 then greena
elsif ctl_status=ctl_yellow then ---countnum=13 numa
yellowa
greenb
elsif ctl_status=ctl_red then ---countnum=24 numa
if countnum=21 then greenb
elsif countnum
elsif ctl_status=ctl_hold then reda
(3) 按键消抖模块的VHDL :
library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;
---------------------------------按键消抖模块 entity key_delay is port (
clk :in std_logic; key_in:in std_logic; key_out: out std_logic ); end ;
architecture key of key_delay is
signal count : integer range 0 to 1999999; signal key ,key_d : std_logic; begin
key
if clk'event and clk='1' then if key /= key_in then key_d
elsif count=1999999 then ---10ms count
key_out
count
end ;
(4) 分频模块的源程序VHDL : library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;
------------------------------------秒时钟产生模块 entity counter is
port (
clk : in std_logic; reset: in std_logic; hold : in std_logic;
countnum: buffer integer range 0 to 24 ); end ;
architecture count of counter is begin
process(clk,reset) ---1秒一次 begin
if reset='1' then countnum
elsif clk'event and clk='1' then if hold='1' then
countnum
countnum
(5) 分位模块源程序VHDL library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;
----------------------------------整数分位 entity feiwei is port (
numin: in integer range 0 to 25 ; numa,num: out integer range 0 to 9 );
end feiwei;
architecture behavior of feiwei is begin
process(numin) begin
if numin>=20 then
numa=10 then
numa
numa
(6)数码管动态扫描模块: library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;
------------------------------------数码管动态扫描 entity scan_led is port (
clk :in std_logic;
displaya1 :in std_logic_vector(7 downto 0); displaya0 :in std_logic_vector(7 downto 0); displayb1 :in std_logic_vector(7 downto 0); displayb0 :in std_logic_vector(7 downto 0);
sm_seg: out std_logic_vector(7 downto 0); sm_bit: out std_logic_vector(7 downto 0) ); end ;
architecture led of scan_led is signal count1: integer range 0 to 7; begin
process(clk) begin
if clk'event and clk='1' then if count1=7 then count1
count1
end process; process(clk) begin
if clk'event and clk='1' then case count1 is
when 0 =>sm_bit
when 1 =>sm_bit
when 2 =>sm_bitsm_bit
when others=>sm_bit'1'); end case; end if ;
end process;
end ;
5. 调试与仿真结果: (一) 原理图
(二) 编译、管脚分配和下载:
(1) 编译处理:
(2) 将程序下载到芯片EP2C8Q208C8上,引脚图如下
(3) 器件编程与下载
将编译好的模块程序下载到FPGA 中(注:芯片选择要与硬件对应,否则会导致实验失败),连线做硬件实验。
五、调试中遇到的问题及解决的方法:
在调试中曾经遇到过很多关于软件方面的问题,对于VHDL 的编写由于VHDL 语言本身就具有很强的结构和逻辑性,所以呢无论从语法结构还是从编程等方面都出现过好多错误,另外发现在用VHDL 语言编程时由于PROCESS 进程之间程序的并行性,所以我在编程时在不同进程之间对同一变量进行了反复赋值导致一个很难理解的错误,然后曾经问过薛东、朱木等学习挺好的同学,但是他们也没遇到过这类的问题,所以最终请教了我们的“百度和Google ”,终于发现了问题的所在。另外,在控制时间的显示的时候,由于变量太多多因而我发现不能完全的控制住变量,因而导致显示的时候出现了乱码,数码管显示不正常,还有就是,在用QUARTUS 编程时一定要注意工程名字必须与实体名字相同,否则一定会编译报错,等等。。。其实初次编程各方面问题会很多,因此我们必须耐心慢慢来,只有这样,才能成功。
六、心得体会
通过这次对交通灯的设计与实践,让我了解了设计的程序,也让我了解了关于VHDL 的基本原理与设计理念,要设计一个电路总要先用仿真仿真成功之后才实际接线的。但是最后的成品却不一定与仿真时完全一样,因为,再实际接线中有着各种各样的条件制约着。而且,在仿真中无法成功的电路接法,在实际中因为芯片本身的特性而能够成功。所以,在设计时应考虑两者的差异,从中找出最适合的设计方法。通过这次设计,进一步加深了对EDA 的了解,让我对它有了更加浓厚的兴趣。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,
只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。
20