找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3982|回复: 1
打印 上一主题 下一主题
收起左侧

基于FPGA的交通灯设计 附分频主控译码VHDL源程序

[复制链接]
跳转到指定楼层
楼主
ID:556863 发表于 2020-11-16 20:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

设计一个十字路口交通控制系统,要求如下:

(1)东西、南北两个方向均有绿灯、黄灯、红灯指示,其持续时间分别为35秒、5秒、40秒,交通灯运行的切换示意图如图1所示。

图1 交通灯运行切换示意图

(2)系统设有时钟,以倒计时的方式显示每一路允许通行的时间。

3系统设计方案

本设计是基于FPGA的交通灯的设计,故系统设计方案采用自上而下的顶层设计,将整体设计方案分成若干个模块分别进行设计,然后采用硬件语言VHDL生成元件和构建原理图的方式进行整体设计。根据设计的任务要求,由系统内部时钟信号提供计时时间。而红绿灯正常的工作由倒计时的时间控制,且倒计时的时间显示由数码管控制。故此本系统设计方案可以分为五个模块:分频器模块,主控制器模块,提取显示值模块,动态扫描模块,译码器模块。其系统设计方案如图2所示。

图2  系统整体框图

其中分频器模块用于24MHz分频为1Hz;主控器模块用于计时和控制红绿灯的亮灭;提取显示值模块用于把倒计时两位数时间能分别显示在两个数码管上;动态扫描模块用于人眼能清晰地看出四位数码管同时倒计时的时间;译码器模块用于把倒计时的时间在数码管显示出来。

4 各模块设计及仿真

4.1主控制器模块

设计主控器的作用是根据计数器值控制发光二极管的亮灭以及输出计数值。其中主控制器的计数范围0——40。倒计时从40到1完成一次循环。其主控器模块元件如图3所示。

图3 主控器模块元件

主控器模块的CLOCK是输入端,当时钟信号接收到1Hz的脉冲时,主控器开始计数的功能;REST是输入端,进行单独控制,当人为控制输入高电平‘1’时,A,B两路红灯亮起,停止计时,交通灯的状态进行复位;NUMA,NUMB是输出端,功能是计数值给七段数码管的提取显示值电路;六个指示灯也是输出端,其功能根据倒计时值,显示A,B路的红绿灯亮灭。即A路35s倒计时显示绿灯亮,5s倒计时显示黄灯亮时,B路口40s倒计时显示红灯亮,B路口 35s倒计时显示绿灯亮,然后5s黄灯亮时,A路口40s倒计时显示红灯亮。其仿真结果如图4所示,通过观察仿真,满足设计需求,完成了实验预期效果。

图4 主控器仿真图

4.2  分频器模块

分频器的设计是为了实现将高频时钟信号转换成低频的时钟信号,作用于主控器、提取显示值和动态扫描显示电路。动态扫描电路需要高频率时钟信号,而主控器,提取显示值则需要低频率的时钟信号,才能精确计时和显示。其分频模块如图5所示。

图5 分频器模块

分频器模块的输入端CLK24M选用是24Mhz高频率时钟,其作用于动态扫描。输出端CLK1Hz则是通过分频先将24Mhz经过48分频到500khz,在500000分频到1hz。而主控器电路需要分频成1hz低频率用于计时。其仿真结果如图6所示。通过观察仿真,满足设计需求,完成了实验预期效果。


图6 24mhz分频1hz时序仿真图

4.3  提取显示值模块

提取显示值模块也可以称为数码管分位模块,设计提取显示值模块是主控器输出的倒计时数值是1位或者2位数,而一个七段数码管只能显示一位数。为了倒计时能显示两位数,所以在七段数码管的译码电路前加一个分位电路。其模块生成的元件如图7所示。

图7 提取显示值模块元件

其模块输入端CLK是接收1Hz的脉冲信号,为了和主控器同步。输入端numin与主控器的numa相连,其作用是为了把计数的两位数值能分开显示在两个数码管上。输出端numa,numb是把输入的两位数分开输出,即两位数分成十位和个位。其仿真结果如图8所示。通过观察仿真,满足设计需求,完成了实验预期效果。

图8 提取显示值仿真图

4.4 动态扫描模块

设计动态扫描模块是为了能同时显示出四个数码管倒计时的动态变化。其原理是利用人眼的余晖效应,而此时的脉冲需要高频率的时钟信号来点亮数码管。其动态扫描模块如图9所示。

图9 动态扫描模块元件

此模块元件输入端clk时钟信号受到24mhz的脉冲信号,其数码管中等亮灭速度远远大于人眼识别最少时间13毫秒,所以动态扫描可以让人眼感受不到闪烁。其中AH,AL,BH,BL表示A,B路的输入端的高位和低位。当输入端输入1、2、3、4时,输出端dout输出的对应实验板上的用于显示倒计时的数码管的位置。输出端q为位循环输出,显示数值。其仿真结果如图10所示。通过观察仿真,满足设计需求,完成了实验预期效果。

图10 动态扫描时序仿真图

4.5 译码器模块

译码器模块的设计是将要显示的数字转换成能驱动数码管的信号,通过输入二进制数值,输出信号点亮二极管,显示出倒计时的数值。译码器模块如图11所示。

图11 译码器模块元件

此模块的输入端dout与动态扫描的输出端dout相连,是把输入的四位二进制数转换成输出端led7s的7位二进制信号,用来驱动数码管显示数值。其模块仿真图如图12所示。通过观察仿真,满足设计需求,完成了实验预期效果。

图12 译码器仿真图

5 顶层电路设计

顶层电路的工作流程:24MHz经过两次48分频和500000分频产生1hz的脉冲信号作用于主控器模块和提取显示值模块。主控器模块控制红绿灯的亮、灭和计数,提取显示值模块用于把计数的两位数分成十位和个位显示。24MHz高频率的时钟信号作用于动态扫描模块,用来能同时显示出四个数码管倒计时的动态变化。译码器模块作用于数码管来显示数值。其顶层电路设计如图13所示。

图13 顶层电路设计

引脚配置如图14所示。

图14 引脚分配图

通过对顶层电路的仿真,仿真结果如图15所示。通过观察仿真,满足设计需求,完成了实验预期。

图15 顶层电路仿真图

6功能扩展

根据进一步的实验要求,联系实际交通信号的灯的运转模式,添加紧急控制、闪烁、左转和右三个状态作为本次实验的功能扩展。

(1)紧急控制:当东西或南北两路中的任一路出现特殊情况,系统可由交警手动控制立即进入特殊运行状态,即红灯全亮,时钟停止计时,东西、南北两路所有车辆停止通行;当特殊运行状态结束后,系统恢复工作,继续正常运行。

(2)闪烁:当绿灯运行结束需要点亮黄灯或者闪烁绿灯作为点亮红灯前的过度状态。此功能在原红绿灯的基础上进行了扩展,让交通灯的变化显得更人性化。

(3)右转和左转:当直行时右转灯点亮10s后,熄灭右转灯后点亮左转向灯亮10s,熄灭左转灯后直行绿灯点亮25s,直行灯熄灭后点亮黄灯闪烁5s,熄灭黄灯后点亮干路红灯,运行50s后循环,支路干路一一对应,当干路左、右转向灯和直行绿灯亮起至黄灯熄灭,支路的红灯一直点亮;当支路左、右转向灯和直行绿灯亮起至黄灯熄灭,干路的红灯一直点亮;此功能扩展在原任务基础上添加左转和右转功能,完善了交通信号灯的功能。

6.1 扩展的主控器模块

扩展的主控制器模块的主要功能根据计数后的数值对输出端elect分几种情况控制红绿灯的状态,以及输出端rea7A,rea7B输出计数。其扩展后的主控器模块如图16所示。

图16 扩展后主控器模块元件

此模块的clk时钟信号是接收1hz的脉冲,主控器开始计数,而输出端rea7A、rea7B功能是把计数的值给7段数码管的分位译码电路。输出端elect的功能是根据计数后分类几种情况后,分别对红绿灯进行控制。输入端rest是紧急控制按键,对rest输入高电平(1)时,A(干路)和B(支路)两个路口红灯亮起,计数停止。输入低电平(0)时,正常工作。对此模块进行仿真,其仿真结果如图17所示。通过观察仿真,满足设计需求,完成了实验预期效果。

图17 扩展主控器仿真图

6.2 LED灯控制模块

LED灯控制模块的功能是对直行,左转,右转,停止指示灯的控制,使其符合红绿灯规则。其模块如图18所示。

图18 LED灯控制模块元件

此模块中的clk10的时钟信号是接收10hz的脉冲,是为了符合交通灯在遇到黄灯时闪烁的效果,10hz频率是0.1s,人眼可以看到其闪烁变化。而输入端elect是连接扩展主控器的输出端elect,其功能主要是通过对不同数值的选择,而对输出端10种指示灯控制,进一步符合红绿灯规则。即数值‘0’情况时,发生紧急制动;数值‘1’情况时,当A(干路)右转灯亮,数值‘2’情况时;当A(干路)左转灯亮;数值‘3’情况时,当A(干路)直行灯亮;数值‘4’情况时,当A(干路)黄灯闪烁;在这四种情况下,B(支路)红灯亮;同理另外四种情况,当B(支路)绿灯亮时,A(干路)红灯亮路。对此模块进行仿真,其仿真结果如图19所示。通过观察仿真,满足设计需求,完成了实验预期效果。

图19 LED灯控制仿真图

7 扩展的顶层设计

分频器模块,提取显示值模块,动态扫描模块,译码器模块等设计都和前面的模块设计一样,就不再叙述。由于黄灯闪烁需要加一个10hz的时钟信号脉冲,故多加一个分频器。扩展后的顶层设计流程和上述一样,不再叙述。其顶层设计电路如图20所示。

图20 扩展后设计电路

其引脚分频如图21所示。

图21 引脚分配图

通过对顶层电路的仿真,仿真结果如图22所示。通过观察仿真,满足设计需求,完成了实验预期。

图22 交通灯控制仿真图
附录

分频器模块程序:
48分频:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY fenpin2 IS
PORT(         
      CLK24M : IN  STD_LOGIC;
      CLK500k: OUT STD_LOGIC );
END fenpin2;
ARCHITECTURE BEHAV OF fenpin2 IS
  SIGNAL  COUNTER : INTEGER RANGE 0 TO 23;
  SIGNAL  CLK: STD_LOGIC;

  BEGIN
    PROCESS(CLK24M)  
    BEGIN            
      IF CLK24M'EVENT AND CLK24M='1' THEN
        IF COUNTER=23 THEN
              CLK<= NOT CLK;
              COUNTER <= 0;
        ELSE  COUNTER <= COUNTER+1;
                            END IF;
      END IF;
    END PROCESS;
   CLK500k <= CLK;
END;  
500000分频:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY fenpin3 IS
PORT(         
      CLK500k : IN  STD_LOGIC;
      CLK1hz: OUT STD_LOGIC );
END;
ARCHITECTURE BEHAV OF fenpin3 IS
  SIGNAL  COUNTER : INTEGER RANGE 0 TO 249999;
  SIGNAL  CLK: STD_LOGIC;
  BEGIN
    PROCESS(CLK500k)  
    BEGIN            
      IF CLK500k'EVENT AND CLK500k='1' THEN
        IF COUNTER=249999 THEN
                                   COUNTER<=0;
              CLK<= NOT CLK;
        ELSE  COUNTER <= COUNTER+1;
                            END IF;
      END IF;
    END PROCESS;
   CLK1hz <= CLK;
END;
24999分频:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY fenpin1 IS
PORT(         
      CLK500k : IN  STD_LOGIC;
      CLK10hz: OUT STD_LOGIC );
END;
ARCHITECTURE BEHAV OF fenpin1 IS
  SIGNAL  COUNTER : INTEGER RANGE 0 TO 24999;
  SIGNAL  CLK: STD_LOGIC;
  BEGIN
    PROCESS(CLK500k)  
    BEGIN            
      IF CLK500k'EVENT AND CLK500k='1' THEN
        IF COUNTER=24999 THEN
                                   COUNTER<=0;
              CLK<= NOT CLK;
        ELSE  COUNTER <= COUNTER+1;
                            END IF;
      END IF;
    END PROCESS;
   CLK10hz <= CLK;
END;
主控器程序:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY zkq IS
PORT
(CLOCK: IN STD_LOGIC;
RESET: IN STD_LOGIC;
NUMA,NUMB: OUT INTEGER RANGE 0 TO 40;
RedA,GreenA,YellowA: OUT STD_LOGIC;
RedB,GreenB,YellowB: OUT STD_LOGIC
);
END;
ARCHITECTURE CONTROL OF zkq IS
SIGNAL COUNTNUM: INTEGER RANGE 0 TO 80;
BEGIN
PROCESS(CLOCK,RESET)
BEGIN
  IF RESET='1' THEN
    COUNTNUM<=0;
  ELSIF RISING_EDGE(CLOCK) THEN
    IF COUNTNUM=79 THEN
      COUNTNUM<=0;
    ELSE
      COUNTNUM<=COUNTNUM+1;
   END IF;
  END IF;
END PROCESS;
PROCESS(CLOCK)
BEGIN
   IF RISING_EDGE(CLOCK) THEN
              IF RESET='1' THEN
                  RedA<='1';
                            RedB<='1';
         ELSIF COUNTNUM<=34 THEN
         NUMA<=35-COUNTNUM;
         RedA<='0';
         GreenA<='1';
         YellowA<='0';
       ELSIF (COUNTNUM<=39) THEN
         NUMA<=40-COUNTNUM;
         RedA<='0';
         GreenA<='0';
         YellowA<='1';
       ELSE
         NUMA<=80-COUNTNUM;
         RedA<='1';
         GreenA<='0';
         YellowA<='0';
       END IF;
       IF COUNTNUM<=39 THEN
         NUMB<=40-COUNTNUM;
         RedB<='1';
         GreenB<='0';
         YellowB<='0';
       ELSIF COUNTNUM<=74 THEN
         NUMB<=75-COUNTNUM;
         RedB<='0';
         GreenB<='1';
         YellowB<='0';
       ELSE
         NUMB<=80-COUNTNUM;
         RedB<='0';
         GreenB<='0';
         YellowB<='1';
       END IF;
     END IF;
  END PROCESS;
END;
提取显示值程序:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity xianshi is
port
(
  CLK:IN std_logic;
  numin:in integer range 0 to 40;
  numa,numb:out integer range 0 to 9
);
end;
architecture bhv of xianshi is
begin
process(CLK)
begin
if rising_edge(CLK) then
if numin=40 then
numa <= 4;
numb <= 0;
elsif numin>=30 then
numa <=3;
numb <=numin-30;
elsif numin>=20 then
numa <=2;
numb <=numin-20;
elsif numin>=10 then
numa <=1;
numb <=numin-10;
else
numa <=0;
numb <=numin;
end if;
end if;
end process;
end;
动态扫描程序:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity dongtai is
port(
  AH,AL,BH,BL:in std_logic_vector(3 downto 0);
  clk:in std_logic;
  q:buffer std_logic_vector(2 downto 0);
  dout:out std_logic_vector(3 downto 0)
);
end;
architecture bhv of dongtai is
signal qin:integer range 7 downto 0;
begin
p1:process(clk)
begin
if(clk'event and clk='1') then
if qin>3 then
qin<=0;
else
qin<=qin+1;
end if;
end if;
end process p1;
p2: process(qin,AL,AH,BH,BL)
begin
case qin is
when 0 => dout<=AH(3 downto 0);q<="111";
when 1 => dout<=AL(3 downto 0);q<="110";
when 2 => dout<=BH(3 downto 0);q<="011";
when 3 => dout<=BL(3 downto 0);q<="010";
when others =>null;
end case;
end process p2;
end;
译码器程序:
library ieee;
use ieee.std_logic_1164.all;
entity smxs is
port
(
dout:in std_logic_vector(3 downto 0);
led7s:out std_logic_vector(6 downto 0)
);
end;
architecture bhv of smxs is
begin
process(dout)
begin
   case dout is
   when "0000" => led7s <="0111111";
   when "0001" => led7s <="0000110";
   when "0010" =>  led7s <= "1011011" ;
   when "0011" =>  led7s <= "1001111" ;
   when "0100" =>  led7s <= "1100110" ;
   when "0101" =>  led7s <= "1101101" ;
   when "0110" =>  led7s <= "1111101" ;
   when "0111" =>  led7s <= "0000111" ;
   when "1000" =>  led7s <= "1111111" ;
   when "1001" =>  led7s <= "1101111" ;
   when others => led7s <= "0000000" ;
              end case;
              end process;
              end;
扩展后的程序
主控器程序:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity kuozkq is
port(

   clk:in std_logic;
              rest:in std_logic;
              elect:out integer range 0 to 8;
              rea7A:out integer range 0 to 100;
              rea7B:out integer range 0 to 100
);
end;
architecture bhv of kuozkq is
begin
process(clk,rest)
variable tep:integer range 0 to 100;
begin
if rest='1' then tep:=100;elect<=0;
else
if clk'event and clk='0' then
if tep>90 then elect<=1;rea7A<=tep-90;rea7B<=tep-50;tep:=tep-1;
elsif tep>80 then elect<=2;rea7A<=tep-80;rea7B<=tep-50;tep:=tep-1;
elsif tep>55 then elect<=3;rea7A<=tep-55;rea7B<=tep-50;tep:=tep-1;
elsif tep>50 then elect<=4;rea7A<=tep-50;rea7B<=tep-50;tep:=tep-1;
elsif tep>40 then elect<=5;rea7A<=tep;rea7B<=tep-40;tep:=tep-1;
elsif tep>30 then elect<=6;rea7A<=tep;rea7B<=tep-30;tep:=tep-1;
elsif tep>5 then elect<=7;rea7A<=tep;rea7B<=tep-5;tep:=tep-1;
elsif tep>0 then elect<=8;rea7A<=tep;rea7B<=tep;tep:=tep-1;
else elect<=8;rea7A<=tep;rea7B<=tep;tep:=100;
end if;
end if;
end if;
end process;
end bhv;
LED控制程序:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity kuoled is
port(
clk10:in std_logic;
elect:in integer range 0 to 8;
redA,greenA,yellowA,rightA,leftA:out std_logic;
redB,greenB,yellowB,rightB,leftB:out std_logic
);
end;
architecture bhv of kuoled  is
begin
process(clk10,elect)
begin
case elect is
when 0 => redA<='1';greenA<='0';yellowA<='0';rightA<='0';leftA<='0';redB<='1';greenB<='0';yellowB<='0';rightB<='0';leftB<='0';
when 1 => redA<='0';greenA<='0';yellowA<='0';rightA<='1';leftA<='0';redB<='1';greenB<='0';yellowB<='0';rightB<='0';leftB<='0';
when 2 => redA<='0';greenA<='0';yellowA<='0';rightA<='0';leftA<='1';redB<='1';greenB<='0';yellowB<='0';rightB<='0';leftB<='0';
when 3 => redA<='0';greenA<='1';yellowA<='0';rightA<='0';leftA<='0';redB<='1';greenB<='0';yellowB<='0';rightB<='0';leftB<='0';
when 4 => redA<='0';greenA<='0';yellowA<=clk10;rightA<='0';leftA<='0';redB<='1';greenB<='0';yellowB<='0';rightB<='0';leftB<='0';
when 5 => redA<='1';greenA<='0';yellowA<='0';rightA<='0';leftA<='0';redB<='0';greenB<='0';yellowB<='0';rightB<='1';leftB<='0';
when 6 => redA<='1';greenA<='0';yellowA<='0';rightA<='0';leftA<='0';redB<='0';greenB<='0';yellowB<='0';rightB<='0';leftB<='1';
when 7 => redA<='1';greenA<='0';yellowA<='0';rightA<='0';leftA<='0';redB<='0';greenB<='1';yellowB<='0';rightB<='0';leftB<='0';
when 8 => redA<='1';greenA<='0';yellowA<='0';rightA<='0';leftA<='0';redB<='0';greenB<='0';yellowB<=clk10;rightB<='0';leftB<='0';
when others =>null;
end case;
end process;
end;
扩展的显示程序:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY xianshi1 IS
PORT
(CLOCK:IN STD_LOGIC;
NUMIN:IN INTEGER RANGE 0 TO 99;
NUMA,NUMB:OUT INTEGER RANGE 0 TO 9
);
END;
ARCHITECTURE bhv OF xianshi1 IS
BEGIN
   PROCESS(CLOCK)
   BEGIN
     IF RISING_EDGE(CLOCK) THEN
               
       IF NUMIN>=10 THEN
         NUMA<=NUMIN/10;
         NUMB<=(NUMIN)rem(10);
                           
       ELSE
                               NUMA<=0;
                                          NUMB<=NUMIN;
       END IF;
     END IF;
   END PROCESS;
END;

以上的Word格式文档51黑下载地址:
基于FPGA的交通灯设计.doc (2.37 MB, 下载次数: 63)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:999139 发表于 2023-10-13 16:23 | 只看该作者
请问分频的占空比是多少呀?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表