EDA实验报告实验四:交通灯控制器设计

实验四   交通灯控制器设计

一、实验目的

1、学习与日常生活相关且较复杂数字系统设计;

2、进一步熟悉EDA实验装置和QuartusⅡ软件的使用方法;

3、学习二进制码到BCD码的转换;

4、学习有限状态机的设计应用。

二、设计要求

完成设计、仿真、调试、下载、硬件测试等环节,在型EDA实验装置上实现一个由一条主干道和一条乡间公路的汇合点形成的十字交叉路口的交通灯控制器功能,具体要求如下:

1、有MR(主红)、MY(主黄)、MG(主绿)、CR(乡红)、CY(乡黄)、CG(乡绿)六盏交通灯需要控制;

2、交通灯由绿转红前有4秒亮黄灯的间隔时间,由红转绿没有间隔时间;

3、乡间公路右侧各埋有一个串连传感器,当有车辆准备通过乡间公路时,发出请求信号S=1,其余时间S=0;

4、平时系统停留在主干道通行(MGCR)状态,一旦S信号有效,经主道黄灯4秒(MYCR)状态后转入乡间公路通行(MRCG)状态,但要保证主干道通行大于一分钟后才能转换;

5、一旦S信号消失,系统脱离MRCG状态,即经乡道黄灯4秒(MRCY)状态进入MGCR状态,即使S信号一直有效,MRCG状态也不得长于20秒钟;

6、控制对象除红绿灯之外,还包括分别在主干道和乡间公路各有一个两位十进制倒计时数码管显示。

三、           主要仪器设备

1、微机                                                                                    1台

2、QuartusII集成开发软件                                                   1套

3、EDA实验装置                                                           1套

四、实验思路

1、设计一个状态寄存器,控制六盏灯的亮与灭

2、设计一个计时器,控制各状态的持续时间,计时器应满足以下要求:

    1)当S=1,且计数器已完成60计数时,计数器进入模4计数,随后进入模

       20计数,再进入模4计数,再回到模60计数

    2)当计数器进行摸20计数时,一旦S变为0,计数器立马进入模4计数,

       再进入模60计数

    3)完成模20计数后,不论S为0或1,计数器进入模4计数,再进入模60

       计数

    4)若计数器未完成模60计数,不论S如何变话,计数器将继续进行模60

       计数

3、设计一个译码显示电路,将计时器的八位BCD码转化为数码管可以显示的段位码。通过动态扫描电路实现。

4、设计一个分频器,将扫描频率分频为基准频率,提供计时器,状态器,译码显示的钟控。

5、使用文本设计4个底层文件,并生成相应元器件,再使用原理图设计顶层文件

五、实验步骤

1、建立工作库文件夹和编辑设计文件

   1)建立一个文件夹保存工程文件;

2)打开QuartusII,建立新的VHDL文件,再打开的页面下输入以下程序

控制6盏灯的模块代码:

LIBRARY IEEE;                                                     

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY jtd IS

PORT(clk,RESET,S:IN STD_LOGIC;

        COUNT:IN STD_LOGIC_VECTOR(7 DOWNTO 0);

        MG,MY,MR,CG,CY,CR:OUT STD_LOGIC);

END jtd;

ARCHITECTURE behav OF jtd IS

   TYPE jtdSTATE IS(mgcr,mycr,mrcg,mrcy);

   SIGNAL STATE:jtdSTATE;

BEGIN

 PROCESS(RESET,STATE,clk, S)

 BEGIN

  IF RESET='1'  THEN STATE<=mgcr;MG<='1';CR<='1';MY<='0';MR<='0';CG<='0';CY<='0';

  ELSIF clk'EVENT AND clk='1' then

     CASE STATE IS

       WHEN mgcr=>IF COUNT="00000001" AND S='1'THEN

                       STATE<=mycr;MY<='1';CR<='1';MG<='0';MR<='0';CG<='0';CY<='0';

                  ELSE STATE<=mgcr;MG<='1';CR<='1';MY<='0';MR<='0';CG<='0';CY<='0'; 

                  END IF;

       WHEN mycr=>IF COUNT="00000001" THEN

                       STATE<=mrcg;MR<='1';CG<='1';MG<='0';MY<='0';CR<='0';CY<='0';

                  ELSE STATE<=mycr;MY<='1';CR<='1';MG<='0';MR<='0';CG<='0';CY<='0';

                  END IF;

       WHEN mrcg=>IF COUNT="00000001" OR S='0'THEN

                       STATE<=mrcy;MR<='1';CY<='1';MY<='0';MG<='0';CR<='0';CG<='0';

                  ELSE STATE<=mrcg;MR<='1';CG<='1';MG<='0';MY<='0';CR<='0';CY<='0';

                  END IF;

       WHEN mrcy=>IF COUNT="00000001" THEN

                       STATE<=mgcr;MG<='1';CR<='1';MR<='0';MY<='0';CY<='0';CG<='0';

                  ELSE STATE<=mrcy;MR<='1';CY<='1';MY<='0';MG<='0';CR<='0';CG<='0';

                  END IF;

     END CASE;

   END IF;

 END PROCESS;

END behav;

控制数码管显示倒计时数并且输出:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY JISHU IS

 PORT(clk,S:IN STD_LOGIC;

    tim:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));

END JISHU;

ARCHITECTURE behav OF JISHU IS

  TYPE RGY IS(mgcr,mycr,mrcg,mrcy);

  SIGNAL STATE:RGY;

BEGIN

  PROCESS(clk)

  VARIABLE b:STD_LOGIC:='0';

  VARIABLE a:STD_LOGIC:='0';

  VARIABLE th,tl:STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

  --IF RESET='1' THEN STATE<=mgcr; th:="0000" ;tl:="0000";a:='0';b:='0';

  IF clk'EVENT AND clk='1' THEN

    CASE STATE IS

       WHEN mgcr => IF S='1' AND b='1' THEN STATE<=mycr;a:='0';th:="0000";tl:="0100";b:='0';

                    ELSIF  S='0' AND b='1' THEN STATE<=mgcr;a:='1';th:="0000";tl:="0001";

                    ELSE 

                         IF a='0' THEN

                            th:="0110";tl:="0000";a:='1';

                         else

                             IF NOT(th="0000" AND tl="0010") then

                                IF tl="0000" then

                                    tl:="1001";th:=th-1;

                                else tl:=tl-1;

                                END IF;

                             ELSE th:="0000";tl:="0001";a:='0';b:='1';

                             END IF;

                         END IF;

                     END IF;

       WHEN mycr => IF a='0' THEN

                      th:="0000";tl:="0100";a:='1';

                    else

                         IF NOT(th="0000" AND tl="0010") then

                            tl:=tl-1;

                         ELSE th:="0000";tl:="0001";a:='0';STATE<=mrcg;

                         END IF;

                    END IF;

        WHEN mrcg =>IF S='1' THEN

                     IF a='0' THEN

                           th:="0010";tl:="0000";a:='1';

                     else

                          IF NOT(th="0000" AND tl="0010") then

                               IF tl="0000" then

                                  tl:="1001";th:=th-1;

                               else tl:=tl-1;

                               END IF;

                           ELSE th:="0000";tl:="0001";a:='0';STATE<=mrcy;

                           END IF;

                     END IF;

                    ELSE a:='0';STATE<=mrcy;th:="0000";tl:="0100";

                    END IF;

        WHEN mrcy =>IF a='0' THEN

                         th:="0000";tl:="0100";a:='1';

                     else

                         IF NOT(th="0000" AND tl="0010") then

                             tl:=tl-1;

                         ELSE th:="0000";tl:="0001";a:='0';STATE<=mgcr;

                         END IF;

                     END IF;

     END CASE;

tim <= th & tl;

END IF;

end process;

END behav;

动态译码显示电路

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY disp IS

PORT(CLK:IN STD_LOGIC;

     INPO:IN STD_LOGIC_VECTOR(7 DOWNTO 0);

      sl0,sl1,sl2:buffer STD_LOGIC;

      SEL:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);

      SG:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);

      GW,SW: buffer STD_LOGIC_VECTOR(3 DOWNTO 0)

     );

END DISP;

ARCHITECTURE behav OF DISP IS

      SIGNAL CNT8: STD_LOGIC_VECTOR(2 DOWNTO 0);

      SIGNAL A : STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

 GW<=INPO(3  downto 0);                                            

 SW<=INPO(7  downto 4);                                         

 P3:PROCESS( CLK)                                             

   BEGIN                                                             

     IF CLK'EVENT AND CLK='1' THEN

       IF CNT8<"001" THEN CNT8 <=CNT8+1;

           ELSE CNT8<=(OTHERS=>'0');

       END IF;

   END IF;

SEL(0)<=sl0  ;

SEL(1)<=sl1  ;

SEL(2)<=sl2  ;

    CASE CNT8 IS                                                  

     WHEN "000" => sl2<='0';sl1<='1';sl0<='0';A<=GW;                                

     WHEN "001" => sl2<='0';sl1<='0';sl0<='1';A<=SW;

     WHEN OTHERS =>NULL;

     END  CASE;

     END PROCESS  ;

P4:PROCESS(A)

BEGIN

CASE A IS

     WHEN "0000" =>SG<="00111111"; WHEN "0001" =>SG<="00000110";

     WHEN "0010" =>SG<="01011011"; WHEN "0011" =>SG<="01001111";

     WHEN "0100" =>SG<="01100110"; WHEN "0101" =>SG<="01101101";

     WHEN "0110" =>SG<="01111101"; WHEN "0111" =>SG<="00000111";

     WHEN "1000" =>SG<="01111111"; WHEN "1001" =>SG<="01101111";

     WHEN OTHERS=>NULL;

END CASE;

END PROCESS;

END behav;

分频器电路:

LIBRARY IEEE; 

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY FEN IS

PORT ( CLK : IN STD_LOGIC;

FOUT : OUT STD_LOGIC );

END;

ARCHITECTURE one OF FEN IS

SIGNAL FULL : STD_LOGIC;

BEGIN

P_REG: PROCESS(CLK)

VARIABLE CNT8 : STD_LOGIC_VECTOR(4 DOWNTO 0);   --INPORTANT

BEGIN

IF CLK'EVENT AND CLK = '1' THEN    --512fen

IF CNT8 = "11111" THEN       

CNT8 := "00000"; --当CNT8计数计满时,输入数据D被同步预置给计数器CNT8

FULL <= '1'; --同时使溢出标志信号FULL输出为高电平

ELSE CNT8 := CNT8 + 1; --否则继续作加1计数

FULL <= '0'; --且输出溢出标志信号FULL为低电平

END IF;

END IF;

END PROCESS P_REG ;

P_DIV: PROCESS(FULL)

VARIABLE CNT2 : STD_LOGIC;

BEGIN

IF FULL'EVENT AND FULL = '1' THEN

CNT2 := NOT CNT2; --如果溢出标志信号FULL为高电平,D触发器输出取反

IF CNT2 = '1' THEN FOUT <= '1'; ELSE FOUT <= '0';

END IF;

END IF;

END PROCESS P_DIV ;

END;

2、编译过程

   1)输入完程序之后逐个编译

2)逐个编译无错之后进行全程编译

3、将以上模块生成元器件

   1)控制6盏灯的模块:

     

   2)控制数码管显示倒计时数的模块:

     

3)控制动态扫描显示的模块

4)控制分频的模块

4、建立新的工程,将各个模块的元器件用原理图连接,进行编译。

原理图如下:

5、系统仿真

  1)建立新的波形激励文件

   2)在波形编辑器窗口添加节点

   3)通过Edit->End Time 来设定仿真结束时间

   4)在CLOCK窗口中设置clk的时钟周期为10ns

5)点击save保存

6) 通过Tools下的Simulator Tools项进行仿真,然后观察输出波形。

仿真波形如下:

jtd1.jpg

  

线形标注 3: 当没有完成模60计数,即使S=1,状态也不发生改变 


线形标注 3: 60秒过后,若S=1主道进入黄灯状态并保持4秒jtd2.jpg

线形标注 3: 20秒过后,不论S=1或0乡道进入黄灯状态并保持4秒jtd3.jpg

jtd4.jpg

线形标注 3: 当S一旦为0,乡道立刻进入黄灯状态,并持续四秒 


6、引脚设定

六、实验现象及验证

1、当“电平1”不按时(S为0),数码管一直保持60秒倒计时,计数结束后数码管保持000001状态,LED灯保持001100;

2、当按下“电平1”(S为1),数码管倒计时4秒,LED灯011100;随后倒计时20秒,LED灯100001,此后倒计时4秒,LED灯001011;最后进入倒计时60秒;

3、当倒计时20秒时,若灭掉“电平1”(S变为0),数码管倒计时4秒,LED灯001011;最后进入倒计时60秒。(6个led分别对应主红黄绿、乡红黄绿)

七、实验心得

1、学会了模可变倒计时计数器,熟悉了IF NOT语句,这次试验用了四个模块,总体思路比较清晰,明白了主绿乡红、主黄乡红、主红乡绿、主红乡黄4个状态之间的循环。

2、 主要编写了动态译码电路和分频器源代码,对代码的编写要求更加清楚明晰,并且能够在熟悉个元件端口及功能的基础上,能够对元件进行顶层逻辑连接,使之达到所需的实验要求。

3、此实验的仿真与硬件结果存在一定的偏差,说明仿真结果并非完全属实,因此更要注重实践,以实验结果为准。

相关推荐