课题:交通信号灯
设计题目:
1.由主干道A和支干道B的汇合点形成十字交叉路口,在交叉路口处设有红绿黄三色信号灯。红灯亮禁止通行;绿灯亮允许通行;黄灯亮则让行驶到路口的车辆有时间停靠到禁止线外。用两位数码管显示当前主支干道所处的状态。红黄绿分别用R,Y,G表示。
2.主干道车辆较多,所以绿灯亮灯时间为50S;支干道亮绿灯时间设为30S。当主干道允许通行亮绿灯时则支干道亮红灯;支干道亮绿灯时也相反。每次由绿灯转变为红灯时,期间要亮5S的黄灯。
3.交通灯正常运行时,用四位数码管显示主干道和支干道的倒计时时间。
4.能实现系统总清0,清0后计数器由初始状态开始计数。
5.具有一定的扩展功能。
一.设计思路
1.根据设计题目要求可以得出交通信号灯控制器的设计用“状态法”来实现较好,因此先划分出交通灯显示时的几个较大的状态。设状态用S表示。
S0:主干道亮黄灯 支干道亮红灯 亮灯5S
S1:主干道亮红灯 支干道亮绿灯 亮灯30S
S2:主干道亮红灯 支干道亮黄灯 亮灯5S
S3:主干道亮绿灯 支干道亮红灯 亮灯50S
状态之间应该要能实现循环:
S0=>S1=>S2=>S3=>S0
2.然后再考虑在每个状态下要能够实现的功能。根据题目可知在每个状态下要能实现将交通灯的颜色变换以字母的形式显示在两位数码管上,每位各表示一条道路。在交通灯颜色输出的同时还要能够实现计数的输出,也就是各路灯转换前剩余的时间量。
3.在实现了各个状态下的功能后就要考虑加上清0功能与紧急功能,清0也就是复位功能。在复位时实现系统清0,并且清0后计数器从初始状态开始计时,在此将S0状态视为初始状态。也就是清0完毕后系统进入S0状态。课题中将紧急功能设为两条路都显示红灯,并且计数器全置0。
4.这些实现的功能都加入后就可以对所写的VHDL语言进行测试与仿真了。在其中实现对所写语言的改进和完善,并得到仿真图结合仿真图再进行修改。在得到合理的仿真图后就可以进行分频语言的添加和设计电路图的绘制了。
5.根据所用的电路板的输入频率合理地设置分频数,完成分频语言的编写。然后根据语言生成器件,再按要求连接电路图。完成后按要求添加约束文件后就可以进行下载演示了。
二.VHDL语言及注释
LIBRARY IEEE;
USE IEEE.STD_LOGIC_11.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;--取库
ENTITY JTD IS
PORT(CPIN,R,JJ:IN STD_LOGIC;
SGL,SZL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
ST1C,ST2C:OUT STD_LOGIC_VECTOR(7 DOWNTO 0) --建立输入输出端口
);
END ENTITY;
ARCHITECTURE JGT OF JTD IS
TYPE STATES IS(S0,S1,S2,S3);
SIGNAL S:STATES;
SIGNAL CP:STD_LOGIC;
SIGNAL CPCT:INTEGER RANGE 0 TO 10000000;
SIGNAL C:STD_LOGIC_VECTOR(7 DOWNTO 0);--辅助用十六进制计数
SIGNAL GL,ZL:STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL T1C,T2C:STD_LOGIC_VECTOR(7 DOWNTO 0);--建立影子端口
FUNCTION SAM (BIN:STD_LOGIC_VECTOR(7 DOWNTO 0))
—十六进制与BCD码转换函数
RETURN STD_LOGIC_VECTOR IS
VARIABLE SBCD,ADDBCD :STD_LOGIC_VECTOR(7 DOWNTO 0);
VARIABLE N:INTEGER RANGE 0 TO 8;
BEGIN
N:=0;SBCD:="00000000";
IF BIN<"01100100" THEN --当输入BIN大于十进制100时,输出为0
LOOP
IF BIN(N)='1' THEN --根据BIN的每一位选择加上对应的压缩型BCD码
CASE N IS
WHEN 0=> ADDBCD:="00000001";
WHEN 1=> ADDBCD:="00000010";
WHEN 2=> ADDBCD:="00000100";
WHEN 3=> ADDBCD:="00001000";
WHEN 4=> ADDBCD:="00010110";
WHEN 5=> ADDBCD:="00110010";
WHEN 6=> ADDBCD:="01100100";
WHEN OTHERS=> ADDBCD:="00000000";
END CASE;
SBCD:=SBCD+ADDBCD;
IF SBCD(3 DOWNTO 0)>"1001" THEN --进行BCD码加法调整
SBCD:=SBCD+"0110";
END IF;
END IF;
N:=N+1;
EXIT WHEN N=8;
END LOOP;
RETURN SBCD;
ELSE
RETURN "00000000";
END IF;
END FUNCTION SAM;
BEGIN
PROCESS(CP,R)
BEGIN
IF R='1' THEN S<=S0;C<=X"00"; GL<="100";ZL<="100";T1C<=X"00";T2C<=X"00";
--复位的实现
ELSIF CP='1' AND CP 'EVENT THEN
IF JJ='1' THEN GL<="100";ZL<="100";T1C<=X"00";T2C<=X"00";
--紧急状态的实现
ELSE --状态转换及状态中输出计时的实现
CASE S IS
WHEN S0=>
IF C>1 THEN
C<=C-1;
ELSE
S<=S1;C<=X"1E";GL<="100";ZL<="001";
T1C<=X"23";T2C<=X"1E";
END IF;
IF T1C>1 THEN T1C<=T1C-1;
END IF;
IF T2C>1 THEN T2C<=T2C-1;
END IF;
WHEN S1=>
IF C>1 THEN
C<=C-1;
ELSE
S<=S2;C<=X"05";GL<="100";ZL<="010";
T1C<=X"05";T2C<=X"05";
END IF;
IF T1C>1 THEN T1C<=T1C-1;
END IF;
IF T2C>1 THEN T2C<=T2C-1;
END IF;
WHEN S2=>
IF C>1 THEN
C<=C-1;
ELSE
S<=S3;C<=X"32";GL<="001";ZL<="100";
T1C<=X"32";T2C<=X"37";
END IF;
IF T1C>1 THEN T1C<=T1C-1;
END IF;
IF T2C>1 THEN T2C<=T2C-1;
END IF;
WHEN S3=>
IF C>1 THEN
C<=C-1;
ELSE
S<=S0;C<=X"05";GL<="010";ZL<="100";
T1C<=X"05";T2C<=X"05";
END IF;
IF T1C>1 THEN T1C<=T1C-1;
END IF;
IF T2C>1 THEN T2C<=T2C-1;
END IF;
END CASE;
END IF;
END IF;
END PROCESS;
PROCESS(GL,ZL,T1C,T2C)--影子端口的赋值
BEGIN
SGL<=GL;SZL<=ZL;ST1C<=SAM(T1C);ST2C<=SAM(T2C);
END PROCESS;
PROCESS(CPIN,R)—分频语言
BEGIN
IF R='1' THEN
CPCT<=10000000;
ELSIF CPIN='1' AND CPIN 'EVENT THEN
IF CPCT=0 THEN
CPCT<=10000000;CP<=NOT CP;
ELSE
CPCT<=CPCT-1;
END IF;
END IF;
END PROCESS;
END JGT;
LIBRARY IEEE; --所用的LCD模块的VHDL程序
USE IEEE.STD_LOGIC_11.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
entity JTDLCD is
port (CPIN,R,BUSY :IN STD_LOGIC;
EW,SN :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
EWRYG,SNRYG : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
CLK,RST,STROBE,OUTLINE : OUT STD_LOGIC;
DATA : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
ADDR : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
end entity ;
architecture JGT of JTDLCD is
TYPE STATES IS (S0,S1,S2,S3,S4);
SIGNAL S: STATES;
SIGNAL LCDPT : INTEGER RANGE 0 TO 10;
SIGNAL CPCT : INTEGER RANGE 0 TO 65535;
SIGNAL CP: STD_LOGIC;
SIGNAL ASCEW,ASCSN : STD_LOGIC_VECTOR(7 DOWNTO 0);
begin
PROCESS(CPIN,R)
BEGIN
CLK<=CPIN;
IF R='1' THEN
CPCT<=65535;
ELSIF CPIN='1' AND CPIN 'EVENT THEN
IF CPCT=0 THEN
CPCT<=65535;CP<=NOT CP;
ELSE
CPCT<=CPCT-1;
END IF;
END IF;
END PROCESS; --分频为500US周期
--主进程:拟采用500us时钟,即在500us后完成状态转换,修改LCDPT指针
--S0:初始状态,在R=1时,处于S0状态,LCDPT=0
-- 流程: 输出rst=1, 转S1
--S1:输出RST=0;判断BUSY=0? :Y: LCDPT+1;LCDPT到固定最后?::N: ->S2
-- ::Y: 转S3
-- ;N; NULL
--S2:给出STROBE信号。转S1
--S1,S2完成初始化固定显示的功能
PROCESS(CP,R)
BEGIN
IF R='1' THEN
S<=S0;LCDPT<=0;RST<='1';
ELSIF CP='1' AND CP 'EVENT THEN
CASE S IS
WHEN S0=> S<=S1;LCDPT<=0;RST<='1';
WHEN S1=> RST<='0';STROBE<='0';
IF BUSY='0' THEN
LCDPT<=LCDPT+1;
IF LCDPT=5 THEN
S<=S3;
ELSE
S<=S2;
END IF;
END IF;
WHEN S2=> S<=S1;STROBE<='1';
--S3~S4完成扫描显示功能
--S3:BUSY=0? :Y: LCDPT循环+1 ,转S4
--S4:给出STROBE信号,转S3
WHEN S3=> STROBE<='0';
IF BUSY='0' THEN
IF LCDPT=10 THEN
LCDPT<=5;
ELSE
LCDPT<=LCDPT+1;
END IF;
S<=S4;
END IF;
WHEN S4=> STROBE<='1';S<=S3;
WHEN OTHERS=> NULL;
END CASE;
END IF;
END PROCESS;
--选择输出进程(LCDPT)
--LCDPT=0,NULL
-- =1~4 显示EW SN E 45H,5 W57H,6 S53H,9 N4EH,10
PROCESS(LCDPT)
BEGIN
CASE LCDPT IS
WHEN 0 => NULL;
WHEN 1=> DATA<="01000101";ADDR<="0101";OUTLINE<='0';
WHEN 2=> DATA<="01010111";ADDR<="0110";OUTLINE<='0';
WHEN 3=> DATA<="01010011";ADDR<="1001";OUTLINE<='0';
WHEN 4=> DATA<="01001110";ADDR<="1010";OUTLINE<='0';
--LCDPT=5,6 EWBCD码 EH,5 EL,6
--LCDPT=7 EW 红绿灯 R,4
--LCDPT= SNBCD码 SH,9 SL,10
--LCDPT=10 SN 红绿灯。 G,8 R52H;Y59H;G47H
WHEN 5=>DATA<="0011"&EW(7 DOWNTO 4);ADDR<="0101";OUTLINE<='1';
WHEN 6=>DATA<="0011"&EW(3 DOWNTO 0);ADDR<="0110";OUTLINE<='1';
WHEN 7=>DATA<=ASCEW;ADDR<="0100";OUTLINE<='1';
WHEN 8=>DATA<="0011"&SN(7 DOWNTO 4);ADDR<="1001";OUTLINE<='1';
WHEN 9=>DATA<="0011"&SN(3 DOWNTO 0);ADDR<="1010";OUTLINE<='1';
WHEN 10=>DATA<=ASCSN;ADDR<="1000";OUTLINE<='1';
WHEN OTHERS=> NULL;
END CASE;
END PROCESS;
PROCESS(EWRYG)
BEGIN
CASE EWRYG IS
WHEN "100" => ASCEW<="01010010";
WHEN "010" => ASCEW<="01011001";
WHEN "001" => ASCEW<="01000111";
WHEN OTHERS=> NULL;
END CASE;
END PROCESS;
PROCESS(SNRYG)
BEGIN
CASE SNRYG IS
WHEN "100" => ASCSN<="01010010";
WHEN "010" => ASCSN<="01011001";
WHEN "001" => ASCSN<="01000111";
WHEN OTHERS=> NULL;
END CASE;
END PROCESS;
end architecture JGT;
三.仿真图形
1.初始时的仿真图
2.状态转换时的仿真图
四.设计电路图
所生成模块体及总电路连线
CPIN:时钟信号输入端
JJ:紧急状态控制输入端
R:复位清0输入端
SGL[2..0]:主干道灯信号灯输出端
SZL[2..0]: 支干道灯信号灯输出端
ST1C[7..0]:主干道计数输出端
ST2C[7..0]: 支干道计数输出端
在下板实现时是不能加外设和分频语言的,所以要得到仿真图时需要去掉函数和LCD模块语言,分频语言并将中间的状态语言拿出来进行修改和测试,这就需要稍作修改。因此请下载此文档的人注意:直接用这些最后整合的语言去仿真和下载是达不到效果的,必须按步骤添加语言!
PS:WORD文档与记事本间有符号转换问题,复制时请注意。