基于状态机的交通灯控制(vhdl)

一 设计要求
1、 开发板上三个led等分别代表公路上红黄绿三种颜色交通灯。
2、 交通灯状态机初始状态为红灯,交通灯工作过程依次是红→绿→黄→红。
3、 为了方便观察,本次实验要求红灯的显示时间为9s,绿灯显示时间为6s,黄灯显示时间为3s,时间需要倒计时,在数码管上显示。编程之前要求先画好ASM图。
5、 第三次实验课用到EP2C8Q208C8通过74HC595驱动数码管,可调用verilog数码管驱动模块。EP2C8Q208C8的SCTP,SHCP,SER_DATA数码管信号线通过两块74HC595集成块,再驱动数码管。

二 八段数码管译码列表
在这里插入图片描述
三 交通灯设计
实验模块包括:分频器模块、复位部分、交通灯显示模块,扩位模块。其中复位部分包括1个状态:reset0,红灯部分包括9个状态:r1到r9,绿灯部分包括6个状态:r1到r6,黄灯部分包括3个状态:y1到y3。其中,对脉冲信号进行2的n次方分之一的分频,实现分频器分频。扩位模块采用补0操作实现将4位二进制数转为16位二进制数。

四 代码实现

分频器

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity clkdiv is
    generic(n:integer:=50000000);
    port(clk_50MHZ:in std_logic;
         clk_1HZ:out std_logic);
end clkdiv;

architecture behavior of clkdiv is
 signal count:integer range n-1 downto 0:=n-1;
begin
  process(clk_50MHZ)
  begin
    if(clk_50MHZ'event and clk_50MHZ='1'and clk_50MHZ'last_value='0') then
      count<=count-1;
       if count>=n/2 then
          clk_1HZ<='0';
       else
          clk_1HZ<='1';
       end if;
       if count<=0 then
          count<=n-1;
       end if;
     end if;
   end process;
end behavior;


交通灯控制

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.all;
ENTITY traffic_light is
PORT(clk:IN std_logic;
rst_n:IN std_logic;
red_light:OUT std_logic;
green_light:OUT std_logic;
yellow_light:OUT std_logic;
holdtime:OUT integer range 0 TO 9);
END ENTITY;
ARCHITECTURE Behav OF traffic_light IS
TYPE state_type IS (reset0,r1,r2,r3,r4,r5,r6,r7,r8,r9,g1,g2,g3,g4,g5,g6,y1,y2,y3);
SIGNAL present_state,next_state:state_type;
BEGIN
seq:PROCESS(clk,rst_n)
BEGIN 
IF(rst_n='0') THEN
present_state<=reset0;
ELSIF(rising_edge(clk)) THEN
present_state<=next_state;
END IF;
END PROCESS;
com:PROCESS(next_state)
BEGIN
red_light<='0';
green_light<='1';
yellow_light<='1';
holdtime<=0;
CASE present_state IS
WHEN reset0=>
red_light<='0';
green_light<='1';
yellow_light<='1';
holdtime<=0;
next_state<=r1;
WHEN r1=>
red_light<='0';
green_light<='1';
yellow_light<='1';
holdtime<=9;
next_state<=r2;
WHEN r2=>
red_light<='0';
green_light<='1';
yellow_light<='1';
holdtime<=8;
next_state<=r3;
WHEN r3=>
red_light<='0';
green_light<='1';
yellow_light<='1';
holdtime<=7;
next_state<=r4;
WHEN r4=>
red_light<='0';
green_light<='1';
yellow_light<='1';
holdtime<=6;
next_state<=r5;
WHEN r5=>
red_light<='0';
green_light<='1';
yellow_light<='1';
holdtime<=5;
next_state<=r6;
WHEN r6=>
red_light<='0';
green_light<='1';
yellow_light<='1';
holdtime<=4;
next_state<=r7;
WHEN r7=>
red_light<='0';
green_light<='1';
yellow_light<='1';
holdtime<=3;
next_state<=r8;
WHEN r8=>
red_light<='0';
green_light<='1';
yellow_light<='1';
holdtime<=2;
next_state<=r9;
WHEN r9=>
red_light<='0';
green_light<='1';
yellow_light<='1';
holdtime<=1;
next_state<=g1;
WHEN g1=>
red_light<='1';
green_light<='0';
yellow_light<='1';
holdtime<=6;
next_state<=g2;
WHEN g2=>
red_light<='1';
green_light<='0';
yellow_light<='1';
holdtime<=5;
next_state<=g3;
WHEN g3=>
red_light<='1';
green_light<='0';
yellow_light<='1';
holdtime<=4;
next_state<=g4;
WHEN g4=>
red_light<='1';
green_light<='0';
yellow_light<='1';
holdtime<=3;
next_state<=g5;
WHEN g5=>
red_light<='1';
green_light<='0';
yellow_light<='1';
holdtime<=2;
next_state<=g6;
WHEN g6=>
red_light<='1';
green_light<='0';
yellow_light<='1';
holdtime<=1;
next_state<=y1;
WHEN y1=>
red_light<='1';
green_light<='1';
yellow_light<='0';
holdtime<=3;
next_state<=y2;
WHEN y2=>
red_light<='1';
green_light<='1';
yellow_light<='0';
holdtime<=2;
next_state<=y3;
WHEN y3=>
red_light<='1';
green_light<='1';
yellow_light<='0';
holdtime<=1;
next_state<=r1;
END CASE;
END PROCESS;
END Behav;

扩位

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.all;
ENTITY data is
PORT(clk:IN std_logic;
input4bit:IN std_logic_vector(3 DOWNTO 0);
output16bit:OUT std_logic_vector(15 DOWNTO 0));
END ENTITY;
ARCHITECTURE behav OF data IS 
BEGIN
output16bit<="ZZZZZZZZZZZZZZZZ";
PROCESS(clk,input4bit)
BEGIN 
IF(rising_edge(clk)) 
THEN
output16bit<="000000000000"&input4bit;
END IF;
END PROCESS;
END behav;

数码管驱动

module seg(
clk,rst_n,en,
idis_data,
ds_stcp,ds_shcp,ds_data
);
input clk; //25M??????
input rst_n; //??????????
input en;
input [15:0] idis_data ;
output ds_stcp; //74HC595????????????????????????
output ds_shcp; //74HC595?????????????????????
output ds_data; //74HC595???????
//????? 0~F ??????
parameter SEG_NUM0 = 8'hc0,
SEG_NUM1 = 8'hf9,
SEG_NUM2 = 8'ha4,
SEG_NUM3 = 8'hb0,
SEG_NUM4 = 8'h99,
SEG_NUM5 = 8'h92,
SEG_NUM6 = 8'h82,
SEG_NUM7 = 8'hF8,
SEG_NUM8 = 8'h80,
SEG_NUM9 = 8'h90,
SEG_NUMA = 8'h88,
SEG_NUMB = 8'h83,
SEG_NUMC = 8'hc6,
SEG_NUMD = 8'ha1,
SEG_NUME = 8'h86,
SEG_NUMF = 8'h8e;
//????? 0~7????
parameter SEG_WE0 = 8'b1111_1110,
SEG_WE1 = 8'b1111_1101,
SEG_WE2 = 8'b1111_1011,
SEG_WE3 = 8'b1111_0111;
// SEG_WE4 = 8'b1110_1111,
// SEG_WE5 = 8'b1101_1111,
// SEG_WE6 = 8'b1011_1111,
// SEG_WE7 = 8'b0111_1111;
wire en;
reg clk_div_2;
reg clk1;
always@(en) //use enable siganl to break the module
begin
if (en==1)
clk1<=clk;
else clk1<=clk1;
end
always@(posedge clk1 or negedge rst_n)
if(!rst_n)
clk_div_2<=1'b0;
else
clk_div_2<=~clk_div_2;
//-------------------------------------------------
//-------------------------------------------------
//??????????
reg[3:0] seg_num; //??????
reg[7:0] seg_duan; //7???????????????8??
reg[7:0] seg_wei; //7????????
reg[7:0] cnt_4; //?????
//?????
always @(posedge clk_div_2 or negedge rst_n)
if(!rst_n) cnt_4 <= 8'd0;
else cnt_4 <= cnt_4+1'b1;
//????
always @(posedge clk_div_2 or negedge rst_n)
if(!rst_n) seg_num <= 8'h00;
else
case(cnt_4[7:6])
2'b00: seg_num <= idis_data[3:0];
2'b01: seg_num <= idis_data[7:4];
2'b10: seg_num <= idis_data[11:8];
2'b11: seg_num <= idis_data[15:12];
default: ;
endcase
//??????
reg flag;
always @(posedge clk_div_2 or negedge rst_n)
if(!rst_n) begin seg_duan <= 8'hff;
// flag<=1'b0;
end
//else if(flag) begin seg_duan<=8'hff;
// flag<=~flag;
// end
else
case(seg_num)
4'h0: seg_duan <= SEG_NUM0;
4'h1: seg_duan <= SEG_NUM1;
4'h2: seg_duan <= SEG_NUM2;
4'h3: seg_duan <= SEG_NUM3;
4'h4: seg_duan <= SEG_NUM4;
4'h5: seg_duan <= SEG_NUM5;
4'h6: seg_duan <= SEG_NUM6;
4'h7: seg_duan <= SEG_NUM7;
4'h8: seg_duan <= SEG_NUM8;
4'h9: seg_duan <= SEG_NUM9;
4'ha: seg_duan <= SEG_NUMA;
4'hb: seg_duan <= SEG_NUMB;
4'hc: seg_duan <= SEG_NUMC;
4'hd: seg_duan <= SEG_NUMD;
4'he: seg_duan <= SEG_NUME;
4'hf: seg_duan <= SEG_NUMF;
default: ;
endcase
//????
always @(cnt_4[7:6])
case(cnt_4[7:6])
2'b00: seg_wei <= SEG_WE0;
2'b01: seg_wei <= SEG_WE1;
2'b10: seg_wei <= SEG_WE2;
2'b11: seg_wei <= SEG_WE3;
default: seg_wei <= 8'b0000_0000;
endcase
//-------------------------------------------------
//74HC95????
reg ds_stcpr; //74HC595????????????????????????
reg ds_shcpr; //74HC595?????????????????????
reg ds_datar; //74HC595???????
//????????
always @(posedge clk_div_2 or negedge rst_n)
if(!rst_n) ds_shcpr <= 1'b0;
else if((cnt_4 > 8'h02 && cnt_4 <= 8'h22) || (cnt_4 > 8'h24 && cnt_4
<= 8'h44)
|| (cnt_4 > 8'h46 && cnt_4 <= 8'h66) || (cnt_4 > 8'h68 && cnt_4
<= 8'h88)
|| (cnt_4 > 8'h90 && cnt_4 <= 8'hb0) || (cnt_4 > 8'hb2 && cnt_4
<= 8'hd2)
|| (cnt_4 > 8'hd4 && cnt_4 <= 8'hf4))
ds_shcpr <= ~ds_shcpr;
else ds_shcpr<=1'b0;
//????????
always @(posedge clk_div_2 or negedge rst_n)
if(!rst_n) ds_datar <= 1'b0;
else
case(cnt_4)
8'h02,8'h46,8'h90,8'hd4: ds_datar <= seg_duan[7];
8'h04,8'h48,8'h92,8'hd6: ds_datar <= seg_duan[6];
8'h06,8'h4a,8'h94,8'hd8: ds_datar <= seg_duan[5];
8'h08,8'h4c,8'h96,8'hda: ds_datar <= seg_duan[4];
8'h0a,8'h4e,8'h98,8'hdc: ds_datar <= seg_duan[3];
8'h0c,8'h50,8'h9a,8'hde: ds_datar <= seg_duan[2];
8'h0e,8'h52,8'h9c,8'he0: ds_datar <= seg_duan[1];
8'h10,8'h54,8'h9e,8'he2: ds_datar <= seg_duan[0];
8'h12,8'h56,8'ha0,8'he4: ds_datar <= seg_wei[0];
8'h14,8'h58,8'ha2,8'he6: ds_datar <= seg_wei[1];
8'h16,8'h5a,8'ha4,8'he8: ds_datar <= seg_wei[2];
8'h18,8'h5c,8'ha6,8'hea: ds_datar <= seg_wei[3];
8'h1a,8'h5e,8'ha8,8'hec: ds_datar <= seg_wei[4];
8'h1c,8'h60,8'haa,8'hee: ds_datar <= seg_wei[5];
8'h1e,8'h62,8'hac,8'hf0: ds_datar <= seg_wei[6];
8'h20,8'h64,8'hae,8'hf2: ds_datar <= seg_wei[7];
8'h24,8'h68,8'hb2,: ds_datar <= 1;
8'h26,8'h6a,8'hb4,: ds_datar <= 1;
8'h28,8'h6c,8'hb6,: ds_datar <= 1;
8'h2a,8'h6e,8'hb8,: ds_datar <= 1;
8'h2c,8'h70,8'hba,: ds_datar <= 1;
8'h2e,8'h72,8'hbc,: ds_datar <= 1;
8'h30,8'h74,8'hbe,: ds_datar <= 1;
8'h32,8'h76,8'hc0,: ds_datar <= 1;
8'h34,8'h78,8'hc2,: ds_datar <= 1;
8'h36,8'h7a,8'hc4,: ds_datar <= 1;
8'h38,8'h7c,8'hc6,: ds_datar <= 1;
8'h3a,8'h7e,8'hc8,: ds_datar <= 1;
8'h3c,8'h80,8'hca,: ds_datar <= 1;
8'h3e,8'h82,8'hcc,: ds_datar <= 1;
8'h40,8'h84,8'hce,: ds_datar <= 1;
8'h42,8'h86,8'hd0,: ds_datar <= 1;
default: ds_datar <= seg_duan[0];
endcase
//????????
always @(posedge clk1 or negedge rst_n)
if(!rst_n) ds_stcpr <= 1'b0;
else if((cnt_4 == 8'h02) || (cnt_4 == 8'h23) || (cnt_4 == 8'h45) ||
(cnt_4 == 8'h67) || (cnt_4 == 8'h89)|| (cnt_4 == 8'hb1)|| (cnt_4 == 8'hd3))
ds_stcpr <= 1'b0;
else if((cnt_4 == 8'h22) || (cnt_4 == 8'h44) || (cnt_4 == 8'h66) ||
(cnt_4 == 8'h88) || (cnt_4 == 8'hb0)|| (cnt_4 == 8'hd2)|| (cnt_4 == 8'hf4))
ds_stcpr <= 1'b1;
wire ds_stcp = ds_stcpr;
wire ds_shcp = ds_shcpr;
wire ds_data = ds_datar;
endmodule

五 整机电路图
在这里插入图片描述
六 仿真结果
在这里插入图片描述
七 实验结果
(a) 红灯9秒
在这里插入图片描述
(b) 红灯8秒
在这里插入图片描述
© 红灯7秒
在这里插入图片描述
(d) 红灯6秒
在这里插入图片描述
(e) 红灯5秒
在这里插入图片描述
(f) 红灯4秒
在这里插入图片描述
(g) 红灯3秒
在这里插入图片描述
(h) 红灯2秒
在这里插入图片描述
(i) 红灯1秒
在这里插入图片描述
(j) 绿灯6秒
在这里插入图片描述
(k) 绿灯5秒
在这里插入图片描述
(l) 绿灯4秒
在这里插入图片描述
(m) 绿灯3秒
在这里插入图片描述
(n) 绿灯2秒
在这里插入图片描述
(o) 绿灯1秒
在这里插入图片描述
§ 黄灯3秒
在这里插入图片描述
(q) 黄灯2秒
在这里插入图片描述
® 黄灯1秒
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43789635/article/details/112978817
今日推荐