当前位置:   article > 正文

基于FPGA的交通信号灯设计(二)_fpga丁字路口

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。

状态机部分代码如下:

  1. ENTITY state_machine IS
  2. PORT(
  3. clk,reset_n,hold,clk_1hz,select_model: IN STD_LOGIC; --clk为50M时钟信号,hold为紧急信号,reset为复位信号
  4. second_count_ge_out: OUT std_logic_vector(3 downto 0);--秒的个位
  5. second_count_shi_out:OUT std_logic_vector(3 downto 0);--秒的十位
  6. red1_out,green1_out,yellow1_out:OUT STD_LOGIC; --控制东西方向的交通灯
  7. red2_out,green2_out,yellow2_out:OUT STD_LOGIC);--控制南北方向的交通灯
  8. END;
  9. ARCHITECTURE state_machine_function OF state_machine IS
  10. TYPE states IS(s0,s1,s2,s3,s4);
  11. SIGNAL next_state:states;
  12. signal red1: std_logic;
  13. signal red2: std_logic;
  14. signal green1: std_logic;
  15. signal green2: std_logic;
  16. signal yellow1: std_logic;
  17. signal yellow2: std_logic;
  18. signal second_count_ge: std_logic_vector(3 downto 0);--秒的个位
  19. signal second_count_shi: std_logic_vector(3 downto 0);--秒的十位
  20. signal second_count_ge_reg: std_logic_vector(3 downto 0);--秒的个位
  21. signal second_count_shi_reg: std_logic_vector(3 downto 0);--秒的十位
  22. signal second_count_ge_model: std_logic_vector(3 downto 0);--秒的个位
  23. signal second_count_shi_model: std_logic_vector(3 downto 0);--秒的十位
  24. BEGIN
  25. red1_out<= red1;
  26. red2_out<= red2;
  27. green1_out<= green1;
  28. green2_out<= green2;
  29. yellow1_out<= yellow1;
  30. yellow2_out<= yellow2;
  31. second_count_ge_out<=second_count_ge_reg;
  32. second_count_shi_out<=second_count_shi_reg;
  33. process(clk_1hz,reset_n)
  34. begin
  35. if(reset_n = '0')then
  36. second_count_ge_reg<="0000";
  37. second_count_shi_reg<="0000";
  38. elsif(clk_1hz'event and clk_1hz = '1')then--上升沿触发
  39. second_count_ge_reg<=second_count_ge;
  40. second_count_shi_reg<=second_count_shi;
  41. end if;
  42. end process;
  43. process(select_model)
  44. begin
  45. if(select_mode = '1')then--白天模式
  46. second_count_ge_model1<="1001";--主干道30秒
  47. second_count_shi_model1<="0010";
  48. second_count_ge_model2<="1001";--次干道20秒
  49. second_count_shi_model2<="0001";
  50. else--夜晚模式
  51. second_count_ge_model1<="1001";--主干道20秒
  52. second_count_shi_model1<="0010";
  53. second_count_ge_model2<="1010";--次干道10秒
  54. second_count_shi_model2<="0000";
  55. end if;
  56. end process;
  57. -- /**********************************************************/
  58. -- //控制模块
  59. -- //
  60. -- /**********************************************************/
  61. PROCESS(reset_n,hold,clk_1hz)
  62. VARIABLE countnum:INTEGER RANGE 0 TO 61; --计数变量
  63. BEGIN
  64. IF(reset_n='0') THEN --复位
  65. countnum:=0;
  66. next_state<=s0;
  67. red1<='1';green1<='0';yellow1<='0';
  68. red2<='1';green2<='0';yellow2<='0';
  69. second_count_ge <= "0001";--1
  70. second_count_shi <= "0000";--0
  71. ELSIF(hold='0') THEN --进入紧急状态
  72. countnum:=0;
  73. next_state<=next_state;
  74. red1<='1';green1<='0';yellow1<='0';
  75. red2<='1';green2<='0';yellow2<='0';
  76. ElSIF(clk_1hz'event AND clk_1hz='1') THEN
  77. IF(countnum>=60) THEN --循环后又回到S1状态
  78. countnum:=1;
  79. ELSE
  80. countnum:=countnum+1; --计数加1
  81. END IF;
  82. CASE next_state IS
  83. WHEN s0 => --东西、南北方向红灯均亮
  84. red1<='1';green1<='0';yellow1<='0';
  85. red2<='1';green2<='0';yellow2<='0';
  86. if(second_count_ge = "0000")then
  87. second_count_ge <= "0000";--0
  88. else
  89. second_count_ge <= second_count_ge - '1';
  90. end if;
  91. IF(countnum=1) THEN
  92. next_state<=s1;
  93. second_count_ge <= second_count_ge_model1;--9
  94. second_count_shi <= second_count_shi_model1;--2
  95. ELSIF(countnum>=0 AND countnum<1) THEN
  96. next_state<=s0;
  97. END IF;
  98. WHEN s1 => --东西方向绿灯亮,南北方向红灯亮。东西方向通车,时间30S
  99. red1<='0';green1<='1';yellow1<='0';
  100. red2<='1';green2<='0';yellow2<='0';
  101. if(second_count_ge = "0000")then
  102. second_count_ge <= "1001";--
  103. if(second_count_shi = "0000")then
  104. second_count_shi <= "0000";--0
  105. else
  106. second_count_shi <= second_count_shi - '1';
  107. end if;
  108. else
  109. second_count_ge <= second_count_ge - '1';
  110. end if;
  111. IF(countnum = 31) THEN
  112. next_state<=s2;
  113. second_count_ge <= "0100";--4
  114. second_count_shi <= "0000";--0
  115. ELSIF(countnum>=1 AND countnum<31) THEN
  116. next_state <= s1;
  117. END IF;
  118. WHEN s2 => --东西方向黄灯亮,南北方向红灯亮,时间5s。
  119. red1<='0';green1<='0';yellow1<='1';
  120. red2<='1';green2<='0';yellow2<='0';
  121. if(second_count_ge = "0000")then
  122. second_count_ge <= "0000";--0
  123. else
  124. second_count_ge <= second_count_ge - '1';
  125. end if;
  126. IF(countnum=36) THEN
  127. next_state<=s3;
  128. second_count_ge <= second_count_ge_model2;--9
  129. second_count_shi <= second_count_shi_model2;--1
  130. ELSIF(countnum>=31 AND countnum<36) THEN
  131. next_state<=s2;
  132. END IF;
  133. WHEN s3 => --东西方向红灯亮,南北方向绿灯亮,南北方向通车,时间20s。
  134. red1<='1';green1<='0';yellow1<='0';
  135. red2<='0';green2<='1';yellow2<='0';
  136. if(second_count_ge = "0000")then
  137. second_count_ge <= "1001";--9
  138. if(second_count_shi = "0000")then
  139. second_count_shi <= "0000";--0
  140. else
  141. second_count_shi <= second_count_shi - '1';
  142. end if;
  143. else
  144. second_count_ge <= second_count_ge - '1';
  145. end if;
  146. IF(countnum=56) THEN
  147. next_state<=s4;
  148. second_count_ge <= "0100";--4
  149. second_count_shi <= "0000";--0
  150. ELSIF(countnum>=36 AND countnum<56) THEN
  151. next_state<=s3;
  152. END IF;
  153. WHEN s4 => --东西方向红灯亮,南,北方向黄灯亮,时间5s。
  154. red1<='1';green1<='0';yellow1<='0';
  155. red2<='0';green2<='0';yellow2<='1';
  156. if(second_count_ge = "0000")then
  157. second_count_ge <= "0000";--0
  158. else
  159. second_count_ge <= second_count_ge - '1';
  160. end if;
  161. IF(countnum=1) THEN
  162. next_state<=s1;
  163. second_count_ge <= second_count_ge_model1;--9
  164. second_count_shi <= second_count_shi_model1;--2
  165. ELSIF(countnum>=56 AND countnum<61) THEN
  166. next_state<=s4;
  167. END IF;
  168. END CASE;
  169. END IF;
  170. END PROCESS;
  171. END state_machine_function;

状态机的波形图如下:

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/648748
推荐阅读
相关标签
  

闽ICP备14008679号