交通灯实习报告.docx
《交通灯实习报告.docx》由会员分享,可在线阅读,更多相关《交通灯实习报告.docx(25页珍藏版)》请在冰点文库上搜索。
交通灯实习报告
xx学院
数字系统课程设计报告书
课题名称
基于FPGA的交通灯控制电路设计
院系
信息工程学院
姓名学号
xx
专业班级
xx
指导教师
xx
设计时间
2014-2015学年第2学期15、16周
2014年06月18日
目录
摘要………………………………………………………………………………1
1设计目的………………………………………………………………………2
2设计内容及要求………………………………………………………………2
3系统整体方案及设计原理……………………………………………………2
4各模块电路设计与实现………………………………………………………2
4.1分频模块设计与实现……………………………………………………2
4.2三进制计数器设计与实现………………………………………………3
4.3计数器模块设计与实现…………………………………………………5
4.41602显示驱动模块设计与实现…………………………………………7
5系统仿真及硬件下载…………………………………………………………13
5.1系统仿真…………………………………………………………………13
5.2硬件下载…………………………………………………………………20
6设计总结………………………………………………………………………22
参考文献…………………………………………………………………………22
摘要:
交通灯控制器在城市交通监管中起着极其重要的作用。
传统的交通灯控制器基本是通过单片机或者PLC实现。
本文介绍基于FPGA技术和QuartusⅡ开发平台实现十字路口交通灯控制器的一种方案。
利用VHDL硬件描述语言描述各模块程序,并在QuartusⅡ环境下编译、仿真,生成顶层文件后下载在FPGA器件EP2C5T144C8上进行验证。
验证结果表明,设计基本实现了交通灯控制器所要求的控制过程,包括倒计时显示功能、和主、支干道的红、黄、绿灯交替显示功能,表明本文所述的设计方案正确。
本设计采用的VerilogHDL是一种全方位的硬件描述语言具有极强的描述能力能支持系统行为级、寄存器传输级和逻辑门级三个不同层次的设计支持结构、数据流、行为三种描述形式的混合描述、覆盖面广、抽象能力强因此在实际应用中越来越广泛。
而FPGA是特殊的ASIC芯片与其他的ASIC芯片相比它具有设计开发周期短、设计制造成本低、开发工具先进、标准产品无需测试、质量稳定以及可实时在线检测等优点。
关键字:
EDA FPGA QuartusⅡ 交通灯
1、设计目的
电子实习是电类各专业教学中的重要实习环节,是加强专业知识、提高动手能力和激发创新意识的重要途径。
通过该次实习,学生应掌握逻辑电路的分析和综合设计能力,了解常用中规模集成电路的基本知识,培养学生如何利用所学知识解决实际问题的能力,为后续专业课的学习、参加电子设计大赛以及实际工作打下扎实的基础。
2、设计内容及要求
(1)、主道路绿、黄、红灯亮的时间分别为60秒、5秒、25秒;
(2)、次道路绿、黄、红灯亮的时间分别为20秒、5秒、65秒;
(3)、主、次道路时间指示采用倒计时制,用2位数码管显示。
3、系统整体方案及设计原理
交通灯的设计是由软件和硬件相配合使用而实现的,通过FPGA控制实现倒计时显示功能、和主、支干道的红、黄、绿灯交替显示功能。
其原理框图如图3-1所示:
图3-1交通灯原理框图
分频模块可以将晶振产生的4MHz的时钟信号分成适合时钟模块的1Hz信号和适合驱动模块的1000Hz。
三进制加法器产生红、黄、绿灯的显示时间,置数给计数模块,并将灯的状态传到驱动模块。
计数模块主要将上个模块给的数据依次减到零,不断循环。
驱动模块驱动程序运行。
通过Verilog语言编程来实现各个模块的功能,再通过QuartusII软件来画图连接,仿真并生成可下载文件,然后在显示器上显示。
4、各模块电路设计与实现
4.1、分频模块设计与实现
点击菜单“File→New”,在DesignFiles页中选择VerilogHDLFile,为工程新添一个VerilogHDL文件(初始文件名为verilog1.v,在此另存文件名为fp20m.v),并在编辑窗口编辑程序。
用Verilog编写的分频模块程序如下:
//分频器模块
//输入频率:
20MHz
//输出频率:
1Hz,1000Hz
modulefp20m(clk,
clk1,clk1000);
inputclk;
outputclk1,clk1000;
regclk1,clk1000;
reg[25:
0]cnt,cnt1;
always@(posedgeclk)//1Hz分频
begin
if(cnt>=9999999)//从0到9999999总共10000000次
begin
cnt=0;
clk1=~clk1;//每10000000次翻转,周期为20000000次,也就是1S
end
elsecnt=cnt+1;
end
always@(posedgeclk)//1000Hz分频
begin
if(cnt1>=9999)
begin
cnt1=0;
clk1000=~clk1000;
end
elsecnt1=cnt1+1;
end
endmodule
程序写好后,先保存再置顶后编译(Processing→StartCompilation),最后点击File→Create/Update→CreateSymbolFilesforCurrentFile,创建一个模块。
该程序在QuartusII软件上生成的分频模块如图4-1所示:
图4-1分频模块
此模块中管脚中,clk表示时钟信号的输入端口,clk1表示输入信号的1Hz分量(即1秒时钟信号),clk1000表示输入信号的1000Hz分量。
后面几个模块的创建都是如此操作,故不再重复说明。
4.2、三进制加法器模块设计与实现
用Verilog编写的计数器模块程序如下:
modulethree(clk,ena,q,sh,sl,d);
inputclk;
inputena;
output[3:
0]q;
output[5:
0]d;
output[3:
0]sh;
output[3:
0]sl;
reg[3:
0]q;
reg[5:
0]d;
reg[3:
0]sh;
reg[3:
0]sl;
//jishukongzhi
always@(posedgeclk)
begin
if(ena)
if(q==4'h2)//三进制加法循环
q<=4'h0;
else
q<=q+1;
end
always@(ena)
if(q==4'h1&&ena==1'h1)//加法器在1时表示黄灯,亮5秒
begin
sh<=4'h0;
sl<=4'h5;
d=6'b010010;
end
else
if(q==4'h0&&ena==1'h1)//加法器在0时表示红灯,亮30秒
begin
sh<=4'h3;
sl<=4'h0;
d=6'b011000;
end
else//加法器在2时表示绿灯,亮45
begin
sh<=4'h4;
sl<=4'h5;
d=6'b100001;
end
endmodule
该程序在QuartusII软件上生成的三进制模块如图4-2所示:
图4-2三进制加法器模块
此模块中管脚中,clk为时钟输入信号,ena为使能信号,ena=1有效时才正常计数;sh为该状态置数的十位,sl为该状态置数的个位;d为控制颜色的输出。
4.3、计数器模块程序
用Verilog编写的计数器模块程序如下:
moduleaa(clk,reset,load,ena,d,qh,ql,co);
inputclk;
inputreset;
input[7:
0]d;
inputload;
inputena;
output[3:
0]qh;
output[3:
0]ql;
outputco;
reg[3:
0]qh;
reg[3:
0]ql;
regco;
//jishukongzhi
always@(posedgeclkornegedgereset)
begin
if(!
reset)//清零控制
begin
qh<=4'h0;
ql<=4'h0;
end
else
if(load)//置数控制
begin
qh<=d[7:
4];
ql<=d[3:
0];
end
else
begin
if(ena)//正常减法计数控制
if(ql==4'h0)
begin
if(qh==4'h0)
begin
end
else
begin
ql<=4'h9;
qh<=qh-1;
end
end
else
begin
ql<=ql-1;
end
end
end
always@(qhorqlorena)
if(qh==4'h0&&ql==4'h0&&ena==1'h1)//如果见到零时,co端口就输出为1
co<=4'h1;
else
co<=4'h0;
endmodule
该程序在QuartusII软件上生成的减法器模块如图4-3所示:
图4-3计数器模块
此模块中管脚中,clk为输入时钟信号端口,load为置数端口,ena为使能信号端口;d[7..0]表示置入的八位二进制数,qh[3..0]、ql[3..0]表示该状态时的十位和个位,co为减到零时的输出信号。
4.4、1602显示驱动模块
该模块程序如下:
//当修改常量数据时,应重新生成模块,并添加到程序框图中
modulelcd_1602_drive4(clk,//500Hz时钟
state,
zhu_ten,zhu_one,
ci_ten,ci_one,
rs,
rw,
en,
data
);
inputclk;
input[5:
0]state;
input[3:
0]ci_one,ci_ten;
input[3:
0]zhu_one,zhu_ten;
outputrs,rw,en;
regrs,rw,en;
output[7:
0]data;
reg[7:
0]data;
reg[7:
0]seg1,seg2,next;
reg[63:
0]data_time;
reg[127:
0]data_chars;
reg[27:
0]counter,counter1,counter2;
reg[0:
7]m[16:
0];
wire[63:
0]data_temp;
parameterchars="traffic";//一个空格代表一个字符
parameterzhu_R="R";//表示显示R+空格
parameterzhu_Y="Y";//表示显示Y+空格
parameterzhu_G="G";//表示显示G+空格
parameterci_R="R";//表示显示空格+R
parameterci_Y="Y";//表示显示空格+Y
parameterci_G="G";//表示显示空格+G
parameter
state0=8'd0,
camd0=8'd1,
state1=8'd2,
camd1=8'd3,
state2=8'd4,
camd2=8'd5,
state3=8'd6,
camd3=8'd7,
state4=8'd8,
camd4=8'd9,
state5=8'd10,
data0=8'd11,
state6=8'd12,
camd5=8'd13,
state7=8'd14,
data1=8'd15,
state8=8'd16;
initial
begin
m[0]="0";//8'b0011_0000;//字符“0”代码
m[1]="1";//8'b0011_0001;//字符“1”代码
m[2]="2";//8'b0011_0010;//字符“2”代码
m[3]="3";//8'b0011_0011;//字符“3”代码
m[4]="4";//8'b0011_0100;//字符“4”代码
m[5]="5";//8'b0011_0101;//字符“5”代码
m[6]="6";//8'b0011_0110;//字符“6”代码
m[7]="7";//8'b0011_0111;//字符“7”代码
m[8]="8";//8'b0011_1000;//字符“8”代码
m[9]="9";//8'b0011_1001;//字符“9”代码
m[4'ha]="";//字符“”代码//m[4'ha]=8'b0001_0000;//字符“”代码
m[4'hb]="l";//字符“l”
m[4'hc]="i";//字符“i”
m[4'hd]="g";//字符“g”
m[4'he]="h";//字符“h”
m[4'hf]="t";//字符“t”
end
assigndata_temp={4'ha,zhu_ten,zhu_one,40'haabc_defa_aa,ci_ten,ci_one,4'ha};//第二行显示“light”
always@(posedgeclk)
begin
case(next)
//初始化
//*************************************************************************************************************************
state0:
beginrs<=0;rw<=0;data<=8'h38;en<=1;next<=camd0;//8位总线,显示2行5*7
seg1<=8'b1000_0000;//第一行首地址
seg2<=8'b1100_0000;//第二行首地址
end
camd0:
beginen<=0;rw<=1;next<=state1;end
state1:
beginrs<=0;rw<=0;data<=8'h0c;en<=1;next<=camd1;end//显示器打开,无光标,光标不闪烁
camd1:
beginen<=0;rw<=1;next<=state2;end
state2:
beginrs<=0;rw<=0;data<=8'h06;en<=1;next<=camd2;end//写入新数据光标右移,写入新数据后显示屏不移动
camd2:
beginen<=0;rw<=1;next<=state3;end
state3:
beginrs<=0;rw<=0;data<=8'h01;en<=1;next<=camd3;end//清屏
camd3:
beginen<=0;rw<=1;next<=state4;end
//**************************************************************************************************************************
//第一行,显示CLOCK
//**************************************************************************************************************************
state4:
begin
rs<=0;
rw<=0;
data<=seg1;
en<=1;
next<=camd4;
//if(seg1==8'b1000_0101)seg1=8'b1000_0111;//可在此处,设置让CLOCLK动态显示
//elseseg1<=seg1-1'b1;
end
camd4:
begin//将第一行的字符数据赋值给data_chars,以供显示
en<=0;
rw<=1;
next<=state5;
case(state[5:
3])//根据状态,显示不同的字符:
3'b100显示R,3'b010显示Y,3'b001显示G
3'b100:
data_chars[127:
112]<=zhu_R;
3'b010:
data_chars[127:
112]<=zhu_Y;
3'b001:
data_chars[127:
112]<=zhu_G;
default:
;
endcase
case(state[2:
0])
3'b100:
data_chars[15:
0]<=ci_R;
3'b010:
data_chars[15:
0]<=ci_Y;
3'b001:
data_chars[15:
0]<=ci_G;
default:
;
endcase
data_chars[111:
16]<=chars;//将"traffic"赋值给data_chars[111:
16]
end
state5:
begin
rs<=1;
rw<=0;
data<=data_chars[127:
120];
en<=1;
next<=data0;
end
data0:
begin
if(counter1==16)beginnext<=state6;counter1=0;end
elsebeginen<=0;rw<=1;counter1=counter1+1;
data_chars<=(data_chars<<8);next<=state5;end
end
//**********************************************************************************************************
//第二行显示,时间
//**********************************************************************************************************
state6:
begin
rs<=0;
rw<=0;
data<=seg2;
en<=1;
next<=camd5;
//if(seg1==8'b1000_0101)seg1=8'b1000_0111;//可在此处,设置让CLOCLK动态显示
//elseseg1<=seg1-1'b1;
end
camd5:
begin
en<=0;
rw<=1;
next<=state7;
data_time<=data_temp;
end
state7:
begin
rs<=1;
rw<=0;
data<=m[data_time[63:
60]];
en<=1;
next<=data1;
end
data1:
begin
if(counter2==16)beginnext<=state8;counter2=0;end
elsebeginen<=0;rw<=1;counter2=counter2+1;
data_time<=(data_time<<4);next<=state7;end
end
//******************************************************************************************************
//延迟处理
//******************************************************************************************************
state8:
begin
if(counter==100)begincounter=0;next<=state3;end
elsecounter=counter+1;
end
//*******************************************************************************************************
endcase
end
endmodule
该程序在QuartusII软件上生成的驱动模块如图4-4所示:
图4-4驱动模块
此模块中,管脚的作用如下:
state[5..0]表示控制主次干道灯的颜色;zhu_ten[3..0],zhu_one[3..0],
ci_ten[3..0],ci_one[3..0]分别表示主干道和次干道的十位和个位;rs,rw,en,date[7..0]分别表示输出和要显示的状态时间。
5、系统仿真及硬件下载
5.1、系统仿真
完成新建项目后,可按以下步骤实行。
(1)设计输入–原理图文件输入法
1)点击菜单“File→New”,在DesignFiles页中选择Block/Diagram/SchematicFile,为工程新添一个原理图文件(初始文件名为Block1.bdf,在此另存文件名为jc.bdf),如图5-1所示。