• 小学
  • 初中
  • 高中
  • 小升初
  • 中考
  • 高考
  • 英语
  • 考研
  • 四六级
  • 单元
  • 节日
  • 母爱
  • 诚信
  • 父爱
  • 环保
  • 家庭
  • 感动
  • 成长
  • 感恩
  • 梦想
  • 爱国
  • 写景
  • 写人
  • 叙事
  • 状物
  • 议论
  • 说明
  • 抒情
  • 观后感
  • 诗歌
  • 读后感
  • 想象
  • 素材
  • 名言
  • 段落
  • 哲理
  • 诗词
  • 成语
  • 赏析
  • 基础
  • 演练
  • 教学
  • 当前位置: 天一资源网 > 交通灯 正文

    [北邮数字电路综合实验报告——交通灯控制器VHDL实现]

    时间:2020-07-24 16:29:37 来源:天一资源网 本文已影响 天一资源网手机站

     数字电路综合实验报告

     班 级:

     姓 名:

     班内序号:

     学 号:

     日 期:

     目录TOC \o "1-3" \h \u

      30779 一、实验摘要 3

      2634 二、实验任务 3

      13164 1.任务要求 3

      4997 2.任务解析 3

      13415 三、实验设计思路 4

      21293 1.状态转移图 4

      25546 2.流程图 5

      22418 3.模块确定 5

      1551 4.系统框图 7

      11535 四、程序代码 7

      28891 ⒈主程序 7

      19071 ⒉分频模块 9

      8235 ⒊防抖模块 10

      16981 ⒋交通灯控制模块 11

      20860 ⒌数字译码模块 14

      25988 五、实验结果 15

      15778 1.仿真结果 15

      11930 2.实物结果 17

      3563 六、所遇问题分析 17

      16058 七、实验总结 18

     交通灯控制器的VHDL实现

     一、实验摘要

     随着交通情况的日益复杂,交通灯在生活中所处的位置也越来越高。本实验就是基于VHDL语言编程实现了十字路口的交通灯控制器。对于交通等控制器的设计是分模块自顶向下的设计思想,软硬件结合来实现本设计。

     关键字:交通灯、VHDL、控制器

     二、实验任务

     1.任务要求

     南北和东西方向各有一组绿、黄、红灯用于指挥交通,绿灯、黄灯和红灯的持续时间分别为20秒、5秒和25秒;

     当有特殊情况(如消防车、救护车等)时,两个方向均为红灯亮,计时停止,当特殊情况结束后,控制器恢复原来状态,继续正常运行;

     用两组数码管,以倒计时方式显示两个方向允许通行或禁止通行的时间;

     2.任务解析

     东西(A车道)和南北(B车道)方向各有一组绿、黄、红灯用于指挥交通(如图1),绿灯、黄灯和红灯的持续时间分别为 20 秒、5 秒和 25 秒。

     图1 十字路口交通灯模型

     因此,可以设计如下四个状态,其关系为:

     状态

     亮灯情况

     车辆行驶状况

     持续时间(秒)

     下一状态

     A车道

     B车道

     S0

     红亮

     红亮

     紧急状况,A/B车道均禁止通行

     ~

     S1

     S1

     绿亮

     红亮

     A车道通行,B车道禁止通行

     20

     S2

     S2

     黄亮

     红亮

     A车道缓行,B车道禁止通行

     5

     S3

     S3

     红亮

     绿亮

     A车道禁止通行,B车道通行

     20

     S4

     S4

     红亮

     黄亮

     A车道禁止通行,B车道缓行

     5

     S1

     三、实验设计思路

     1.状态转移图

     图2 状态转移图

     2.流程图

     图3 流程图

     3.模块确定

     ⑴分频模块

     设计原因:由于实验板只能提供50MHz的时钟信号,而电路中只能使用较低频率的时钟:

     1Hz时钟信号:计数器count变化时使用;

     20Hz时钟信号:在防抖电路中使用的时钟信号;

     1kHz时钟信号哦:用于数码管位选信号的改变的时钟信号。

     功能:用于将实验板上的50MHz的时钟信号经分频后输出:1kHz、20Hz、1Hz。

     图4 分频模块的输入和输出

     ⑵防抖动模块

     设计原因:只要有按键或是拨码开关,防抖电路就是不可缺少的一个模块。否则,按键信号中的一些毛刺和抖动往往会引起电路不可预知的错误。

     功能:将带有抖动的信号进行识别和判断,输出持续时间超过0.1s的高电平信号。

     图5 防抖动模块的输入和输出

     ⑶交通灯控制模块

     设计原因:这个模块是本程序设计的灵魂,是重中之重!这个模块用于控制电路的状态改变和按键响应,也就是系统中控制器的作用。

     功能:根据按键信号和输入时钟,输出符合交通灯状态变化规律的LED驱动信号、数码管显示的数据、数码管位选信号。

     图6 交通灯控制模块的输入和输出

     ⑷数字译码模块

     设计原因:由于交通灯控制模块输出的为数码管显示的数据,为10进制数,因此必须要一个译码电路,将此十进制数转化为LED灯的驱动信号,而这个功能正是由此模块完成。

     功能:将输入的十进制数转变为相应的8位2二进制数作为数码管的驱动信号。

     图7 数字译码模块的输入和输出

     ⑸整体模块连接图

     图8 模块整体连接图

     4.系统框图

     图9 系统框图

     四、程序代码

     ⒈主程序

     主程序

     library ieee;

     use ieee.std_logic_1164.all;

     entity traffic_lights is

      port(clk:in std_logic; 时钟信号

      emerg,reset:in std_logic; 复位和紧急情况信号

      seg:out std_logic_vector(7 downto 0); 7段数码管显示

      select_led:out std_logic_vector(5 downto 0); 选通输出

      lights:out std_logic_vector(7 downto 0));led发光管输出

     end traffic_lights;

     architecture a of traffic_lights is 分别调用各个模块

      signal cp1k,cp20,cp1,resetout,emergout:std_logic;

      signal number:integer range 0 to 9;

     component freq_divide 分频模块 1k 100hz 1hz

      port(clk_in:in std_logic;

      clk_1,clk_20,clk_1k:out std_logic);

     end component;

     component noshake 分频模块 1k 100hz 1hz

      port(clk_20,keyin:in std_logic;

      keyout:out std_logic);

     end component;

     component traffic 交通灯控制模块

      port(clk1,clk1k:in std_logic;

      emerg,reset:in std_logic;

      num:out integer range 0 to 9;

      lights:out std_logic_vector(7 downto 0);

      select_led:out std_logic_vector(5 downto 0));

     end component;

     component display 数字译码模块

      port(num:in integer range 0 to 9;

      seg:out std_logic_vector(7 downto 0));

     end component;

     begin

      u1:freq_divide port map(clk,cp1,cp20,cp1k); 分频器产生时钟信号

      u2:noshake port map(cp20,reset,resetout); 对复位信号防抖处理

      u3:noshake port map(cp20,emerg,emergout); 对紧急信号防抖处理

      u4:traffic port map(cp1,cp1k,emergout,resetout,number,lights,select_led); 状态机运转

      u5:display port map(number,seg); 数码管显示

     end;

     ⒉分频模块

     分频模块

     library ieee;

     use ieee.std_logic_1164.all;

     use ieee.std_logic_unsigned.all;

     entity freq_divide is

      port(clk_in : in std_logic;

      clk_1,clk_20,clk_1k : out std_logic);

     end;

     architecture a of freq_divide is

      signal count1 : integer range 0 to 24999;

      signal count2 : integer range 0 to 24;

      signal count3 : integer range 0 to 9;

      signal clk_tmp1,clk_tmp2,clk_tmp3: std_logic;

     begin

     50000分频进程

     输出:1kHz的时钟信号

     功能:用于数码管显示时刷新频率

      p1:process(clk_in)

      begin

      if (clk_in'event and clk_in='1') then

      if count1=24999 then

      count1<=0;

      clk_tmp1<= not clk_tmp1;

      else

      count1<=count1+1;

      end if;

      end if;

      end process p1;

     50分频进程

     输出:20Hz的时钟信号

     功能:防抖动电路中使用

      p2:process(clk_tmp1)

      begin

      if (clk_tmp1'event and clk_tmp1='1') then

      if count2=24 then

      count2<=0;

      clk_tmp2<= not clk_tmp2;

      else

      count2<=count2+1;

      end if;

      end if;

      end process p2;

     20分频进程

     输出:1Hz的时钟信号

     用于状态转变的时钟信号

      p3:process(clk_tmp2)

      begin

      if (clk_tmp2'event and clk_tmp2='1') then

      if count3=9 then

      count3<=0;

      clk_tmp3<= not clk_tmp3;

      else

      count3<=count3+1;

      end if;

      end if;

      end process p3;

     

      clk_1<=clk_tmp3;

      clk_20<=clk_tmp2;

      clk_1k<=clk_tmp1;

     

     end;

     ⒊防抖模块

     防抖动模块

     library ieee;

     use ieee.std_logic_1164.all;

     use ieee.std_logic_unsigned.all;

     entity noshake is

      port(clk_20,keyin: in std_logic;

      keyout: out std_logic);

     end;

     architecture a of noshake is

      signal cp:std_logic;

     begin

     只有持续时间高于0.1s的高电平才有效

      process(clk_20)

      variable times:integer range 0 to 2;

      begin

      if (clk_20'event and clk_20='1') then

      if keyin='1' then

      if times=2 then

      times:=times;

      else times:=times+1;

      end if;

      else times:=0;

      end if;

      end if;

      if times=2 then

      cp<='1';

      else cp<='0';

      end if;

      keyout<=cp;

      end process;

     end;

     ⒋交通灯控制模块

     交通灯控制模块

     library ieee;

     use ieee.std_logic_1164.all;

     use ieee.std_logic_unsigned.all;

     entity traffic is

      port(clk1,clk1k:in std_logic;

      emerg,reset:in std_logic;

      num:out integer range 0 to 9;

      lights:out std_logic_vector(7 downto 0);

      select_led:out std_logic_vector(5 downto 0));

     end traffic;

     architecture control of traffic is

      type states is(s0,s1,s2,s3,s4);

      signal state:states;

      signal num1,num2,num3,num4:integer range 0 to 9;

      signal emerg_status,reset_status:std_logic:='0';

      signal count:integer range 1 to 50 :=50;

     begin

     紧急信号的处理进程

      p1:process(emerg)

      begin

      emerg_status<=emerg;

      end process p1;

     

     复位信号处理及计数器count控制进程

      p2:process(reset)

      begin

      reset_status<=reset;

      end process p2;

      p3:process(clk1)

      begin

      if(reset_status='1') then

      count<=50;

      elsif(emerg_status='1') then

      count<=count;

      else

      if(clk1'event and clk1='1') then

      if count=1 then

      count<=50;

      else count<=count-1;

      end if;

      end if;

      end if;

      end process;

     核心状态机

      p4:process(emerg_status,count)根据计数器来选择交通灯状态

      begin

      if(emerg_status='1')then state<=s0; 6个正常状态和1个紧急情况状态

      else

      if(count>=31)then state<=s1;

      elsif(count<=30 and count>=26)then state<=s2;

      elsif(count<=25 and count>=6)then state<=s3;

      else state<=s4;

      end if;

      end if;

      case state is 交通灯状态,用LED发光管模拟交通灯

      when s0=>lights<=; --;RA/RB

      when s1=>lights<=; --;GA/RB

      when s2=>lights<=; --;YA/RB

      when s3=>lights<=; --;RA/GB

      when s4=>lights<=; --;RA/YB

      end case;

      end process;

     

     根据计数器值确定数码管显示数字

      p5:process(emerg_status,count)

      begin

      if(emerg_status='1') 紧急状态下数码管显示8

      then num1<=8;num2<=8;num3<=8;num4<=8;

      else

     

      状态S1

      if(count=50)

      then num1<=2;num2<=0;num3<=2;num4<=5;

      elsif(count>=45 and count<50)

      then num1<=1;num2<=count-40;num3<=2;num4<=count-45;

      elsif(count>=40 and count<=44)

      then num1<=1;num2<=count-40;num3<=1;num4<=count-35;

      elsif(count>=35 and count<=39)

      then num1<=0;num2<=count-30;num3<=1;num4<=count-35;

      elsif(count>=31 and count<=34)

      then num1<=0;num2<=count-30;num3<=0;num4<=count-25;

      状态S2

      elsif(count>=26 and count<=30)

      then num1<=0;num2<=count-25;num3<=0;num4<=count-25;

      状态S3

      elsif(count=25)

      then num1<=2;num2<=5;num3<=2;num4<=0;

      elsif(count>=20 and count<=24)

      then num1<=2;num2<=count-20;num3<=1;num4<=count-15;

      elsif(count>=15 and count<=19)

      then num1<=1;num2<=count-10;num3<=1;num4<=count-15;

      elsif(count>=14 and count<=10)

      then num1<=1;num2<=count-10;num3<=0;num4<=count-5;

      状态S4

      elsif(count>=6 and count<=9)

      then num1<=1;num2<=count;num3<=0;num4<=count-5;

      else num1<=0;num2<=count;num3<=0;num4<=count;

      end if;

      end if;

      end process;

     

     数码管选通信号输出

      p6:process(clk1k)

      variable temp:integer range 0 to 3;

      begin

      if(clk1k'event and clk1k='1')then

      case temp is

      when 0=>num<=num1;temp:=1;select_led<="011111"; 选用4个数码管输出倒计时

      when 1=>num<=num2;temp:=2;select_led<="101111";

      when 2=>num<=num3;temp:=3;select_led<="111101";

      when 3=>num<=num4;temp:=0;select_led<="111110";

      end case;

      end if;

      end process;

     end;

     ⒌数字译码模块

     数字译码模块

     library ieee;

     use ieee.std_logic_1164.all;

     entity display is

      port(num:in integer range 0 to 9;

      seg:out std_logic_vector(7 downto 0));

     end;

     architecture a of display is

     begin

     d1:process(num)

      begin

      case num is

      when 0=>seg<=; 由七位二进制数表示0到9

      when 1=>seg<=;

      when 2=>seg<=;

      when 3=>seg<=;

      when 4=>seg<=;

      when 5=>seg<=;

      when 6=>seg<=;

      when 7=>seg<=;

      when 8=>seg<=;

      when 9=>seg<=;

      when others=>seg<="XXXXXXXX";

      end case;

      end process;

     end;

     五、实验结果

     1.仿真结果

     ⑴仿真说明

     由于分频模块的存在,导致无法整体仿真(可能可以,但是很费时间)。因此,只对核心模块——交通灯控制模块进行仿真。

     为了结果的易读性,现将程序做如下修改。

     ①LED灯的驱动信号lights的修改:

     when s0=>lights<=; --;RA/RB

     when s1=>lights<=; --;GA/RB

     when s2=>lights<=; --;YA/RB

     when s3=>lights<=; --;RA/GB

     when s4=>lights<=; --;RA/YB

     即从S0~S4,相应的lights信号从0~4改变。

     ②数码管位选信号select_led的修改:

     when 0=>num<=num1;temp:=1;select_led<="000000";

     when 1=>num<=num2;temp:=2;select_led<="000001";

     when 2=>num<=num3;temp:=3;select_led<="000010";

     when 3=>num<=num4;temp:=0;select_led<="000011";

     即数码管位选信号循环输出0~3。

     ③输入信号:1Hz和1kHz的时钟信号,仿真时间为110s。

     ⑵仿真波形图

     ①正常状况下

     reset和emerg都为低电平。

     图10 正常状态下的仿真波形

     图11 续图10

     由上两图可见,正常情况下,状态转移完全符合设计要求:,如此循环往复。

     num信号和select_led信号(局部)

     图12 正常运行下的的仿真波形

     数码管显示数字和数码管位选信号也都正常输出。

     ②复位信号响应

     reset信号

     reset信号

     图13 复位情况下的仿真波形

     由上面仿真波形中可见,当reset为高电平时,在时钟沿上状态改变为S1,即复位成功。

     ③紧急信号响应

     紧急信号

     紧急信号

     图14 紧急情况下的仿真波形

     由图14可见,在emerg信号有效时,交通灯状态一直处于S0,一旦emerg信号失效,状态立马恢复到原来(emerg信号之前的状态)。总之,紧急状况处理成功!

     2.实物结果

     总体来说,实验要求的基本功能全部完成,且没有bug。交通灯运行完全符合前面分析的要求。

     六、所遇问题分析

     问题1:状态改变的参考量的确定。

     解决方案:当初设计时,丝毫没有头绪。当参考了以前同学的程序后,心中不由豁然开朗——使用计数器count的值来控制状态改变和数码管显示数字。这个想法确实很巧妙,做到了一个count解决所有控制问题。这样的设计,大大减小了程序的复杂度。

     问题2:reset信号由拨码开关还是由按键来输入。

     解决方案:这点困扰了我好久。最后考虑到如果使用按键输入时,一来与实际情况不符,二来为程序编写增加了难度。难度引入主要是由于按键检测的时钟和按键状态检测的时间,都很难确定,无论使用分频器产生的何种时钟信号都无法满足要求。最后采用拨码开关直接输入,使程序大为简便,也使这一问题得到圆满的解决。

     七、实验总结

     这次实验中,虽然在编程中遇到了不少困难,但是最终还是按时完成实验,确实令人信心倍增啊。

     首先,在实验题目选定之后,对于题目的切入点一直找不到,不知如何下手。于是就在老师的课件中找灵感,万幸的是我竟然找见了!在老师课件中的一些示例中,我慢慢摸索和品味其中的要义,认真思考硬件编程的特点,并在网上查找资料,并重新拜读了去年发的那本《数字电路实验讲义》,从中得到不少启迪。终于在第二次上课前完成了程序原理和状态分析等任务。

     然后,就开始编程了。最先编写的是分频模块——按照数字电路网站上的那个50M分频器的方法,编写出了实验要求的分频模块。接下来就是编写程序的主模块——交通灯控制模块。这个模块的编写借鉴了以前同学的设计思路,因此编写的头绪时很清晰的。最后编写了防抖模块和数字译码模块。这个过程中,始终伴随我的就是编译时的各种warning和error。但是我没有泄气。要知道——兵来将挡,水来土掩;凡事皆有因。有错误,就一句一句排错,最后整体进行逻辑检测。终于在最后一个没有warning和error的程序编写完毕。

     接下来就是仿真和下载。但是在仿真中,发现原先编写的程序有很大的逻辑错误。于是反复修改,反复阅读程序,查找病因。果然是“苦心人,天不负”,终于在最后,一个仿真正常、运行正常的程序编写成功。此时的喜悦真是无以言表。

     在以上过程中,对于硬件编程的理解日渐深刻。这是我使我在平常的软件编写的惯性中,不由停下脚步,慢慢体会硬件编程的思想和技巧。

     数字电路综合实验虽然结束了,但是在实验中学到的知识将使我收益一生。在此,感谢那些“诲人不倦”的老师和同学!

    相关关键词: 交通灯程序流程框图 交通灯 单片机交通灯实验报告 单片机交通灯实验报告摘要 单片机交通灯仿真实验报告
    相关热词搜索: 交通灯 控制器 北邮 数字电路 实验

    • 范文大全
    • 教案下载
    • 优秀作文
    • 励志
    • 课件
    • 散文
    • 名人名言