数字电路实验交通灯控制器.docx
《数字电路实验交通灯控制器.docx》由会员分享,可在线阅读,更多相关《数字电路实验交通灯控制器.docx(33页珍藏版)》请在冰点文库上搜索。
数字电路实验交通灯控制器
数字电路实验报告
交通灯控制器
一、任务要求
设计制作一个用于十字路口的交通灯控制器。
①南北和东西方向各有一组绿、黄、红灯用于指挥交通,绿灯、黄灯和红灯的持
续时间分别为20秒、5秒和25秒;
②当有特殊情况(如消防车、救护车等)时,两个方向均为红灯亮,计时停止,
③当特殊情况结束后,控制器恢复原来状态,继续正常运行;
④用两组数码管,以倒计时方式显示两个方向允许通行或禁止通行的时间;
·选做:
增加左、右转弯显示控制功能;
·选做:
其它自拟功能。
二、系统设计
利用有限状态机描绘出交通灯的状态转移图,并设置记录东西和南北路口可通行时间的全局变量count1,count2。
状态间的转移以count1,count2的值作为判断条件。
对于两种特殊情况:
当复位信号reset为高电平时,则回到最初状态;当紧急输入信号emergency为高电平时,则转移到一特殊状态,emergency结束后则返回当前状态。
三、总体框图及分块设计
1交通灯控制器的逻辑划分方块图
2交通灯控制器逻辑流程图
3交通灯控制器的状态转移图
其中图中T20T10T5分别是直行,左转和黄灯的时间,通过判断其是否达到所规定的时间来给灯作为改变的条件,程序已交通灯分别初始化为绿灯和红灯。
另外,在reset信号为高电平时,不论其他状态和信号如何,系统回到最初状态。
在reset信号为低电平且emergency为高电平时,两个方向交通灯均为红灯警铃响起,直到emergency恢复低电平时,系统恢复到emergency刚快要出现时系统的状态,并会到之前状态。
2.分块设计
在我的实验设计中,整个交通灯控制器包括5个模块:
①控制器模块control;②计数模块catcontol;③分频模块fenpin1和fenpin2;④点阵DZ;⑤数码管显示译码模块show;⑥警铃控制器bellcontrol;⑦主函数。
现对各个模块的设计作一简要阐述:
①控制器模块control:
这是整个程序的核心模块,控制着交通灯状态的转移和交通灯通行时间count1和count2数值的改变,该模块是交通灯状态转移图的程序实现。
②计数模块catcontrol:
该模块将count1和count2数值转化为二进制信号并以较高频率扫描数码管的共阴极以显示多位数字的通行时间,是一个初级译码模块。
③分频模块fenpin1:
该模块将实验板固有50M晶振时钟频率进行50000000分频,以产生控制器模块所需的1Hz频率。
Fenpin2:
则分成1KHz的供扫频和警铃的响声频率
④点阵DZ:
通过contol里面的返回值来控制其显示,行为低电平有效,列位高电平,从第一行开始扫描到第八行。
⑤数码管显示译码模块show:
该模块通过对每一位数字进行7段数码管译码以显示该数字,实际上我在实验中用的是8位信号。
因为7段数码管实际上有8个输出信号,除了7段数码管,还有小数点显示信号。
⑥警铃控制器bellcontrol:
通过返回的紧急信号值来判断是否给警铃一个高电平的信号。
⑦主函数:
将各个模块连接起来。
3.仿真图
①正常运行下
②加了紧急信号
③复位信号
此次试验实现了交通灯的直行控制以及左转的控制,外加了紧急情况。
并且在此之上附加了点阵显示交通灯的状态以及响铃的警报。
四.故障分析
1.我一开始是用50M的晶振频率扫描的数码管的共阴极,在初次下载好程序后运行时,我发现数码管显示的数字虽然正确,但亮度不一,容易被认为是错误的显示。
后来我将50M晶振分频后产生的一个较低的频率来扫描共阴极,便得到了稳定、均匀、清晰的数码管数字显示。
对于给警铃加的也频率开始也掌握不好,后来改了1KHz才感觉比较合适
2.在宿舍仿真的时候,第一次没改分频,导致机器承受不住,然后改了分频之后,第一次周期设置比较断,观察不到状态的转变,开始以为是代码错了,检查了很久,结果才发现是周期设置为50us比较短,而不是代码的问题,后来设置周期为250us之后就看到状态的转变。
3.在验收的时候由于小喇叭的硬件电路没连接,使得没有响声,本以为是软件代码问题,后来通过仿真观察发现还是有信号过去的。
五.总结
交通灯控制器是数字状态机中较为简单较为基本的一种应用,通过这次实验,我对数字状态机的基本应用和程序实现有了一个更为深刻的认识。
开始第一周先是把书看了一次特别代码部分,首先了解其基本的句式及其基本结构。
后来通过书上的一些例题看出了门道,从而有了些想法。
VHDL语言比较直白,此次试验对于状态机的描述很直白,基本上都是通过状态的判断来制定当前的显示,通过各种case,以及计数器的循环来体现出。
这次实验收获颇多,先是学会了VHDL语言,还对数字电路中各种状态的转变及其转变条件的理解加深。
还深刻意识到我们学的理论知识和实际也能很好的联系。
六.代码源程序
主函数traffic
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entitytrafficis
port(clk,reset,emergency:
instd_logic;
light1,light2:
outstd_logic_vector(2downto0);
cat:
outstd_logic_vector(5downto0);
num_out:
outstd_logic_vector(7downto0);
hang,lie:
outstd_logic_vector(7downto0);
bell_out:
outstd_logic);
endtraffic;
architecturearchoftrafficis
signalclk_a:
std_logic;
signalclk_b:
std_logic;
signalcount_a:
std_logic_vector(5downto0);
signalcount_b:
std_logic_vector(5downto0);
signale:
std_logic;--emergency对应bell信号
signaldz_a:
std_logic_vector(1downto0);
signalshow_num:
std_logic_vector(3downto0);
componentfenpin1is
port(clk:
instd_logic;
clk_out:
outstd_logic);
endcomponent;
componentfenpin2is
port(clk:
instd_logic;
clk_out:
outstd_logic);
endcomponent;
componentcontrolis
port(clk:
instd_logic;
emergency:
instd_logic;
reset:
instd_logic;
light1:
outstd_logic_vector(2downto0):
="001";
light2:
outstd_logic_vector(2downto0):
="100";
counter1:
outstd_logic_vector(5downto0);
counter2:
outstd_logic_vector(5downto0);
bell:
outstd_logic;
dz:
outstd_logic_vector(1downto0));
endcomponent;
componentdzis
port(clk:
instd_logic;
dz:
instd_logic_vector(1downto0);
hang,lie:
outstd_logic_vector(7downto0));
endcomponent;
componentbellcontrolis
port(bell:
instd_logic;
clk1,clk2:
instd_logic;
bell_out:
outstd_logic);
endcomponent;
componentcatcontrolis
port(clk:
instd_logic;
cat:
outstd_logic_vector(5downto0);
num_in:
outstd_logic_vector(3downto0);
counter1:
instd_logic_vector(5downto0);
counter2:
instd_logic_vector(5downto0));
endcomponent;
componentshowis
port
(num_in:
instd_logic_vector(3downto0);
num_out:
outstd_logic_vector(7downto0));
endcomponent;
begin
u1:
fenpin1portmap(clk=>clk,clk_out=>clk_a);
u2:
fenpin2portmap(clk=>clk,clk_out=>clk_b);
u3:
controlportmap(clk=>clk_a,reset=>reset,emergency=>emergency,light1=>light1,light2=>light2,counter1=>count_a,counter2=>count_b,bell=>e,dz=>dz_a);
u4:
dzportmap(clk=>clk_b,dz=>dz_a,hang=>hang,lie=>lie);
u5:
bellcontrolportmap(bell=>e,clk1=>clk_b,clk2=>clk_a,bell_out=>bell_out);
u6:
catcontrolportmap(clk=>clk_b,cat=>cat,num_in=>show_num,counter1=>count_a,counter2=>count_b);
u7:
showportmap(num_in=>show_num,num_out=>num_out);
endarch;
分频器fenpin1(1Hz)
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityfenpin1is
port
(clk:
instd_logic;
clk_out:
outstd_logic);
endfenpin1;
architecturearchoffenpin1is
signaltmp:
integerrange0to49999999;
begin
p1:
process(clk)
begin
ifclk'eventandclk='1'then
iftmp=49999999thentmp<=0;
elsetmp<=tmp+1;
endif;
iftmp<25000000thenclk_out<='0';
elseclk_out<='1';
endif;
endif;
endprocessp1;
endarch;
fenpin2(1KHz)
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityfenpin2is
port
(clk:
instd_logic;
clk_out:
outstd_logic);
endfenpin2;
architecturearchoffenpin2is
signaltmp:
integerrange0to49999;
begin
p1:
process(clk)
begin
ifclk'eventandclk='1'then
iftmp=49999thentmp<=0;
elsetmp<=tmp+1;
endif;
iftmp<25000thenclk_out<='0';
elseclk_out<='1';
endif;
endif;
endprocessp1;
endarch;
控制器control
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entitycontrolis
port(clk:
instd_logic;
emergency:
instd_logic;
reset:
instd_logic;
light1:
outstd_logic_vector(2downto0);
light2:
outstd_logic_vector(2downto0);
counter1:
outstd_logic_vector(5downto0);
counter2:
outstd_logic_vector(5downto0);
bell:
outstd_logic;
dz:
outstd_logic_vector(1downto0));
endcontrol;
architecturearchofcontrolis
signalcount1:
integer:
=20;
signalcount2:
integer:
=35;
signaln_count1:
integer;
signaln_count2:
integer;
typeall_stateis(s0,s1,s2,s3,s4,s5,s6);
signalstate:
all_state:
=s0;
signaltempstate:
all_state:
=s0;
begin
p1:
process(clk,emergency,reset)
begin
if(reset='1')thenstate<=s0;count1<=20;count2<=35;bell<='0';
elsif(emergency='1')thenstate<=s6;count1<=0;count2<=0;bell<='1';
elsif(clk'eventandclk='1')then
casestateis
whens0=>ifcount1>1thentempstate<=s0;count1<=count1-1;count2<=count2-1;n_count1<=count1;n_count2<=count2;elsestate<=s1;count1<=10;count2<=count2-1;bell<='0';
endif;
whens1=>ifcount1>1thentempstate<=s1;count1<=count1-1;count2<=count2-1;n_count1<=count1;n_count2<=count2;elsestate<=s2;count1<=5;count2<=count2-1;bell<='0';
endif;
whens2=>ifcount1>1thentempstate<=s2;count1<=count1-1;count2<=count2-1;n_count1<=count1;n_count2<=count2;elsestate<=s3;count1<=35;count2<=20;bell<='0';
endif;
whens3=>ifcount2>1thentempstate<=s3;count2<=count2-1;count1<=count1-1;n_count1<=count1;n_count2<=count2;elsestate<=s4;count2<=10;count1<=count1-1;bell<='0';
endif;
whens4=>ifcount2>1thentempstate<=s4;count2<=count2-1;count1<=count1-1;n_count1<=count1;n_count2<=count2;elsestate<=s5;count2<=5;count1<=count1-1;bell<='0';
endif;
whens5=>ifcount2>1thentempstate<=s5;count2<=count2-1;count1<=count1-1;n_count1<=count1;n_count2<=count2;elsestate<=s0;count1<=20;count2<=35;bell<='0';
endif;
whens6=>state<=tempstate;count1<=n_count1;count2<=n_count2;
whenothers=>state<=s0;
endcase;
endif;
counter1<=conv_std_logic_vector(count1,6);
counter2<=conv_std_logic_vector(count2,6);
endprocessp1;
p2:
process(emergency,reset,state)
begin
if(reset='0'andemergency='0')then
casestateis
whens0=>dz<="00";
whens1=>dz<="01";
whens3=>dz<="00";
whens4=>dz<="01";
whenothers=>dz<="10";
endcase;
elsedz<="10";
endif;
endprocessp2;
p3:
process(state)
begin
casestateis
whens0=>light1<="001";light2<="100";
whens1=>light1<="001";light2<="100";
whens2=>light1<="010";light2<="100";
whens3=>light1<="100";light2<="001";
whens4=>light1<="100";light2<="001";
whens5=>light1<="100";light2<="010";
whens6=>light1<="100";light2<="100";
endcase;
endprocessp3;
endarch;
cotrol是通过count的递减来判断是否该转状态,并且吧当前的状态保存在n_count里面,在紧急信号返回时候可以会到当前状态。
一共7个状态,s0~s6。
计数器catcontrol
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entitycatcontrolis
port(clk:
instd_logic;
cat:
outstd_logic_vector(5downto0);
num_in:
outstd_logic_vector(3downto0);
counter1:
instd_logic_vector(5downto0);
counter2:
instd_logic_vector(5downto0));
endcatcontrol;
architecturearchofcatcontrolis
signaltemp:
integerrange0to3;
signalcount1:
integerrange0to35;
signalcount2:
integerrange0to35;
signalcount:
integerrange0to35;
signalnum:
std_logic_vector(3downto0);
signalcat_tmp:
std_logic_vector(5downto0):
="011111";
begin
p1:
process(clk)
begin
count1<=conv_integer(counter1);
count2<=conv_integer(counter2);
if(clk'eventandclk='1')then
if(temp=3)then
temp<=0;
else
temp<=temp+1;--使temp实现0~3的计数功能
endif;
endif;
endprocessp1;
p2:
process(temp)
begin
casetempis
when0=>count<=count1;--temp值变化的前半周期count被赋值count1
when1=>count<=count1;
when2=>count<=count2;--temp值变化的前半周期count被赋值coun2
when3=>count<=count2;
endcase;
endprocessp2;
p3:
process(count,temp)
begin
casecountis
when0=>casetempis
when0=>num<="0000";cat_tmp<="011111";--注cat为低电平有效
when1=>num<="0000";cat_tmp<="101111";
when2=>num<="0000";cat_tmp<="111101";
when3=>num<="0000";cat_tmp<="111110";
endcase;
when1=>casetempis
when0=>num<="0000";cat_tmp<="011111";
when1=>num<="0001";cat_tmp<="101111";
when2=>num<="0000";cat_tmp<="111101";
when3=>num<="