基于FPGA的交通信号灯设计(二)

详细设计及实现

根据要求,我们可以用典型时序状态机实现功能,共有六个大的状态,现设定:

S0: 四个方向的红灯全亮

S1: 东、西方向绿灯亮,南、北方向红灯亮

S2:东、西方向黄灯闪烁,南、北方向红灯亮

S3:东、西方向红灯亮,南、北方向绿灯亮

S4:东、西方向红灯亮,南、北方向黄灯闪烁

S5:东、西、南、北四个方向的红灯亮

整体控制状态图如下:

图1 整体功能状态机

此状态机是该设计的核心模块,由其控制着东、西、南、北方向的交通。仔细分析设计要求可知,东西方向交通灯状态变化相同,南北方向亦相同,故实际上只需控制两组交通灯,所以状态机有六个输出变量,分别控制东西、南北方向的红、绿、黄灯的亮灭状态。另外,状态机还有三个输入变量,分别为复位信号、紧急状况控制信号、时钟信号。

由于在vhdl语言中,同一个进程内只能有一个时钟,所以紧急信号宜以电平来触发。但实验要求通过单脉冲来控制紧急信号,为了解决这个矛盾,可以设计一个边沿触发的紧急信号发生器,当输入一个单脉冲时,输出电平为高,即进入紧急状态;再输入一单脉冲,输出电平为低,解除紧急状态。

为了控制各个状态持续的时间,需在状态机中设置计时装置。可将输入状态机的时钟信号的频率设计为1Hz,即一个脉冲周期为1s。由于实际试验中,给定的实验器材频率都很大,从Khz到MHz,在这里采用50MHz,这样就只需要计数器来分频。此外,复位信号利用高低电平来控制,当电平为高时,状态机保持东、西、南、北四个方向红灯均亮的状态,若为低则由初始状态进入状态循环。

综上所述,可得总体设计结构框图如下:

图2 总体设计结构框图

clk为输入时钟(用于计时,由计数器分频后提供);

reset为复位信号,与计数器的复位信号连接在一起,由一个电平开关控制;

hold为紧急信号(由紧急信号发生器控制);

输出变量red1、green1、yellow1控制东西方向红、绿、黄交通灯的亮灭状态;南北方向则由red2、green2、yellow2控制。

部分模块结构图如下:

图2 控制模块结构图

图3 时钟分频模块
图4 数码管显示模块结构图

状态机

状态机用于控制十字路口交通灯的状态变化。此模块中我设计的是异步复位和异步等待(即进入紧急状态),复位信号是低电平有效,紧急信号是高电平有效。另外,为了控制各个状态的持续时间,此状态机中还设计了一个计数装置,用于计时。

状态SO持续时间为1s,由于输入状态机的时钟频率为1Hz,即一个脉冲持续时间为1s,所以在计数为0~1内状态机为S0状态。同理,在计数为1~31内,为S1状态;在计数为31~36内,为S2状态;S3状态所处的计数范围为36~56;S4状态所处的计数范围为56~61。

状态机部分代码如下:

ENTITY state_machine IS
PORT(
    clk,reset_n,hold,clk_1hz,select_model:     IN STD_LOGIC;       --clk为50M时钟信号,hold为紧急信号,reset为复位信号
    second_count_ge_out: OUT std_logic_vector(3 downto 0);--秒的个位
    second_count_shi_out:OUT std_logic_vector(3 downto 0);--秒的十位
    red1_out,green1_out,yellow1_out:OUT STD_LOGIC; --控制东西方向的交通灯
    red2_out,green2_out,yellow2_out:OUT STD_LOGIC);--控制南北方向的交通灯
END;

ARCHITECTURE state_machine_function OF state_machine IS
TYPE states IS(s0,s1,s2,s3,s4);
SIGNAL next_state:states;    


signal red1:        std_logic;
signal red2:        std_logic;
signal green1:        std_logic;
signal green2:        std_logic;
signal yellow1:        std_logic;
signal yellow2:        std_logic;
signal second_count_ge:  std_logic_vector(3 downto 0);--秒的个位
signal second_count_shi: std_logic_vector(3 downto 0);--秒的十位
signal second_count_ge_reg:  std_logic_vector(3 downto 0);--秒的个位
signal second_count_shi_reg: std_logic_vector(3 downto 0);--秒的十位
signal second_count_ge_model:  std_logic_vector(3 downto 0);--秒的个位
signal second_count_shi_model: std_logic_vector(3 downto 0);--秒的十位
BEGIN
    red1_out<= red1;
    red2_out<= red2;
    green1_out<= green1;
    green2_out<= green2;
    yellow1_out<= yellow1;
    yellow2_out<= yellow2;
    
    second_count_ge_out<=second_count_ge_reg;
    second_count_shi_out<=second_count_shi_reg;
    
    process(clk_1hz,reset_n)
      begin 
        if(reset_n = '0')then
            second_count_ge_reg<="0000";
            second_count_shi_reg<="0000";
        elsif(clk_1hz'event and clk_1hz = '1')then--上升沿触发
            second_count_ge_reg<=second_count_ge;
            second_count_shi_reg<=second_count_shi;
        end if;
    end process;
    process(select_model)
      begin 
        if(select_mode = '1')then--白天模式
            second_count_ge_model1<="1001";--主干道30秒
            second_count_shi_model1<="0010";
            
            second_count_ge_model2<="1001";--次干道20秒
            second_count_shi_model2<="0001";
        else--夜晚模式
            second_count_ge_model1<="1001";--主干道20秒
            second_count_shi_model1<="0010";
            
            second_count_ge_model2<="1010";--次干道10秒
            second_count_shi_model2<="0000";
        end if;
    end process;
-- /**********************************************************/
-- //控制模块
-- //
-- /**********************************************************/
     PROCESS(reset_n,hold,clk_1hz)
     VARIABLE countnum:INTEGER RANGE 0 TO 61;  --计数变量
     BEGIN
          IF(reset_n='0') THEN     --复位
             countnum:=0;  
             next_state<=s0;  
             red1<='1';green1<='0';yellow1<='0';
             red2<='1';green2<='0';yellow2<='0';
             
            second_count_ge <= "0001";--1
            second_count_shi <= "0000";--0
          ELSIF(hold='0') THEN   --进入紧急状态
             countnum:=0; 
             next_state<=next_state;
             red1<='1';green1<='0';yellow1<='0';
             red2<='1';green2<='0';yellow2<='0';
          ElSIF(clk_1hz'event AND clk_1hz='1') THEN
             IF(countnum>=60) THEN  --循环后又回到S1状态
               countnum:=1;
             ELSE
               countnum:=countnum+1; --计数加1
             END IF;
             
             CASE next_state IS
                WHEN s0 =>        --东西、南北方向红灯均亮
                  red1<='1';green1<='0';yellow1<='0';
                  red2<='1';green2<='0';yellow2<='0';
                  
                if(second_count_ge = "0000")then
                    second_count_ge <= "0000";--0
                else
                    second_count_ge <= second_count_ge - '1';

                end if;
                  
                  IF(countnum=1) THEN
                    next_state<=s1;
                    second_count_ge <= second_count_ge_model1;--9
                    second_count_shi <= second_count_shi_model1;--2
                  ELSIF(countnum>=0 AND countnum<1) THEN
                    next_state<=s0;
                  END IF;
              
                WHEN s1 =>    --东西方向绿灯亮,南北方向红灯亮。东西方向通车,时间30S
                  red1<='0';green1<='1';yellow1<='0';
                  red2<='1';green2<='0';yellow2<='0';
                  
                if(second_count_ge = "0000")then
                    second_count_ge <= "1001";--
                    if(second_count_shi = "0000")then
                        second_count_shi <= "0000";--0
                    else
                        second_count_shi <= second_count_shi - '1';
                    end if;
                else
                    second_count_ge <= second_count_ge - '1';
                end if;
                  
                  IF(countnum = 31) THEN
                    next_state<=s2;
                    second_count_ge <= "0100";--4
                    second_count_shi <= "0000";--0
                  ELSIF(countnum>=1 AND countnum<31) THEN
                    next_state <= s1;
                  END IF;

                WHEN s2 =>    --东西方向黄灯亮,南北方向红灯亮,时间5s。
                  red1<='0';green1<='0';yellow1<='1';  
                  red2<='1';green2<='0';yellow2<='0';
                  
                  if(second_count_ge = "0000")then
                    second_count_ge <= "0000";--0
                 else
                    second_count_ge <= second_count_ge - '1';
                 end if;
                 
                  IF(countnum=36) THEN
                    next_state<=s3;
                    second_count_ge <= second_count_ge_model2;--9
                    second_count_shi <= second_count_shi_model2;--1
                  ELSIF(countnum>=31 AND countnum<36) THEN
                    next_state<=s2;
                  END IF;

                  WHEN s3 =>   --东西方向红灯亮,南北方向绿灯亮,南北方向通车,时间20s。
                    red1<='1';green1<='0';yellow1<='0';
                    red2<='0';green2<='1';yellow2<='0';
                    
                    if(second_count_ge = "0000")then
                        second_count_ge <= "1001";--9
                        if(second_count_shi = "0000")then
                            second_count_shi <= "0000";--0

                        else
                            second_count_shi <= second_count_shi - '1';

                        end if;
                  else
                    second_count_ge <= second_count_ge - '1';

                  end if;
                    
                    IF(countnum=56) THEN
                      next_state<=s4;
                       second_count_ge <= "0100";--4
                       second_count_shi <= "0000";--0
                    ELSIF(countnum>=36 AND countnum<56) THEN
                      next_state<=s3;
                    END IF;

                  WHEN s4 =>    --东西方向红灯亮,南,北方向黄灯亮,时间5s。
                    red1<='1';green1<='0';yellow1<='0';
                    red2<='0';green2<='0';yellow2<='1';
                    
                    if(second_count_ge = "0000")then
                        second_count_ge <= "0000";--0
                    else
                        second_count_ge <= second_count_ge - '1';
                  end if;
                    
                    IF(countnum=1) THEN
                      next_state<=s1;
                      second_count_ge <= second_count_ge_model1;--9
                      second_count_shi <= second_count_shi_model1;--2
                    ELSIF(countnum>=56 AND countnum<61) THEN
                      next_state<=s4;
                    END IF;
             END CASE;
          END IF;
     END PROCESS;
    
     
END state_machine_function;

状态机的波形图如下:

初始状态为四个方向的红灯全亮,时间1秒。然后东、西方向绿灯亮,南、北方向红灯亮。东、西方向通车,时间30秒。但在此过程中,有一个紧急的信号出现,所以在大概在6秒左右,出现紧急信号,东西南北方向红灯都亮。在11秒左右解除紧急信号,仿真图中恢复S1的状态。经验证,图中均符合题目要求。

  • 52
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在基于FPGA交通信号灯设计方面,有一些相关的英文文献可以参考。 1. Chen, Y., Fan, X., & Xu, J. (2018). Real-time intelligent traffic light control using FPGA. IEEE Access, 6, 38479-38488. 本文提出了一种基于FPGA的实时智能交通信号灯控制方法。利用FPGA的高并行性能和实时响应能力,实现了智能化交通信号灯的控制。通过深度学习和数据挖掘技术,对交通流量进行检测和预测,并根据实时情况调整信号灯的控制策略。实验结果表明,该方法有效地提高了交通流量的效率和道路安全性。 2. Li, X., Wang, M., Wu, J., & Lin, C. (2016). FPGA-based intelligent traffic light control system. Journal of Computer Applications, 36(3), 764-768. 该文介绍了一种基于FPGA的智能交通信号灯控制系统。通过使用FPGA实现的数字信号处理技术,对交通信号灯进行实时控制和优化。系统利用车辆检测、实时流量估计和信号灯优化算法,减少了交通拥堵和排队时间。实验结果表明,该系统可以提高道路的通行效率和减少交通事故的发生率。 3. Zhou, Y., Lin, K., & Fan, H. (2015). Design of FPGA-based traffic signal controller for intersection. Procedia Computer Science, 60, 1335-1344. 本文介绍了一种基于FPGA交通信号灯控制器的设计方法。该控制器利用FPGA的高并行性能,通过硬件描述语言实现交通信号灯的控制算法。通过优化信号灯相位和计时方案,减少了交叉口的交通拥堵和延误。实验结果表明,该控制器可以提高交叉口的通行效率和道路安全性。 这些文献提出了基于FPGA交通信号灯设计方案,并通过实验验证了这些方案的有效性。通过利用FPGA的高并行性能和实时响应能力,可以实现智能化的交通信号灯控制,提高交通流量的效率和道路的安全性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值