CASE_01 基于FPGA的交通灯控制器

        该系类博客序言和资源简介可浏览该博客:PREFACE FPGA经典案例序言 快速了解该系列博客的内容与可用 资源。

 

目录

1 案例引导

1.1 硬件设计初窥

1.2 逻辑设计初窥

2 模块级逻辑设计

2.1 时钟分频模块

2.2 数码管译码模块

2.3 主逻辑运行模块

3 系统逻辑设计

4 硬件设计

4.1 电源接口电路设计

4.2 电源系统设计

4.3 时钟设计

4.4 JTAG端口和FPGA配置电路设计

4.5  FPGA芯片的电源引脚

4.6 A方向信号灯电路

4.7 B方向信号灯电路

4.8 复位电路

4.9 PCB设计图

 4.10  实物图

5 实物验证

5.1 管脚分配

5.2  实物验证

    资料合集包传送门:


1 案例引导

1.1 硬件设计初窥

CASE_01 基于FPGA的交通灯控制器_第1张图片

       如图所示是实际生活中的一个十字路口,看这个图是作为交通灯硬件设计的输入,说明白一点就是需要哪些元器件。

       图中的设计是为了让每个方向的人和车辆都能看到信号灯,所以红绿黄灯的数量加上人行道上的灯总共是48个灯。那么在实际设计中真的要在板卡上设计那么多灯吗?很显然是不需要的,通过观察可以发现只要是同一方向上的灯,所显示的状态都是一样的。所以实际设计时按A方向和B方向把灯分为两组即可,同样显示倒计时的数码管也是同样的道理。

       于是可以得出初步的硬件设计框图,如下:

CASE_01 基于FPGA的交通灯控制器_第2张图片

       A方向和B方向上分别由红、绿、黄、左转四个信号灯和两个数码管组成。这里解释一下为什么有左转信号灯,在一般的路口只有红、绿、黄三个信号灯,当该方向上的绿灯亮时车是可以直行和左转的,但是在一些大型路口,车流量大,所以一般将左转单独进行时间控制,做这个功能是为了让交通灯功能更完备,提高设计的通用性。

       到这里初步可以确定硬件设计需要的东西,但是具体硬件设计在这里是得不出结论的,因为在没有进行FPGA/CPLD逻辑设计之前,是很难评估需要多少资源来进行设计的,所以芯片选型这一步还要往后放一放。

1.2 逻辑设计初窥

       虽然硬件设计尚未定稿,但这并不妨碍进行逻辑设计,这就是FPGA/CPLD设计的优点。可以在逻辑设计仿真验证完毕之后,再进行硬件电路的设计,这样可以大大降低先期考虑不充分,导致设计的硬件不能使用或者芯片选型不合理所带来的风险。

       结合需要驱动外围设备,以及系统逻辑。可以大致推断出逻辑设计的框图如下:

CASE_01 基于FPGA的交通灯控制器_第3张图片

       到这里得不出详细的逻辑设计输入,但是可以大致了解到设计分为这几个部分,在接下来的工作里将这几个部分分别实现就能完成设计。

2 模块级逻辑设计

2.1 时钟分频模块

       时钟分频,为什么要进行时钟分频呢?因为信号灯在进行倒计时是按秒信号倒计时的,而FPGA/CPLD一般采用晶振或者一些频率较高的信号源来提供时钟,所以需要对高频时钟进行分频来得到需要的秒信号。

       时钟分频的原理很简单,而且对于成偶数被时钟关系的分频也十分容易实现。

举个例子:如果的主时钟12hz,如何来生成1hz的秒信号呢?很简单只需要用计数器每计到5个数时对一个信号进行取反,就刚好能生成的秒信号。

       如下为时钟分频的代码,工程位于Traffic_light\module_test\CLK_div中。

//------------------------------------------------------
//design name	:CLK_div
//use			:时钟分频
//engineer		:比特电子工作室
//version		:V0.1
//change note	:
//--------------------------------------------------------
module CLK_div
(
    input   clk    ,
    input   rst_n  ,
    output  clk_1s 
);

localparam div_parameter = 5; // 仿真时将此值改为5,缩短仿真时间,真实程序跑时改为650。
reg [27:0] counter;
reg co;

//counter
always @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        counter <= 0;
    end
    else if(counter == div_parameter )begin
        counter <= 0;
    end
    else begin
        counter <= counter + 1;
    end
end

//co
always @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        co <= 0;
    end
    else if(counter == div_parameter )begin
        co <= ~ co;
    end
end

//clk_1s
assign clk_1s = co;
endmodule

         仿真结果如下图:

CASE_01 基于FPGA的交通灯控制器_第4张图片

       如果把clk看作是12hz的时钟,那么clk_1s便是秒信号了。可以看出CLK12个周期CLK_1S完成了自己的一个周期。

       如果主时钟的频率更高呢?怎么获得秒信号呢?很简单只要加大计数的周期就可以了,计数的个数可以通过如下的公式获得:

N = fclk /2 – 1

       N:分频系数 (即程序中div_parameter的值  fclk :主时钟的频率

2.2 数码管译码模块

       这里指的数码管就是最常见的七段显示数码管,如图:

CASE_01 基于FPGA的交通灯控制器_第5张图片

        为什么叫七段,因为可以看出它是由7段小灯组成的,通过点亮小灯的组合不同可以组成不同的文字。管脚图如下:

CASE_01 基于FPGA的交通灯控制器_第6张图片

       每个管脚控制着一段灯管,数码管还分为共阴和共阳的说法,共阴是说每段小灯的负极是连接在一个(一个共地管脚),每段小灯的正级是分开的(对应着每个管脚),共阳数码管的则刚好相反。本文就以共阴的数码管为例来讲解。

       对于交通灯来讲,单个的只需要数码管显示0~9这10个数字,按照管脚状态的组合,可以得到如下的数字管脚组合组合表,就称它为译码表(小数点忽略,该设计不涉及小数点的使用):

       图中用‘1’表示该关键状态为高,点亮该管脚对应的段码;‘0’则相反;

数字   管脚

a

b

c

d

e

f

g

0

1

1

1

1

1

1

0

1

0

1

1

0

0

0

0

2

1

1

0

1

1

0

1

3

1

1

1

1

0

0

1

4

0

1

1

0

0

1

1

5

1

0

1

1

0

1

1

6

1

0

1

1

1

1

1

7

1

1

1

0

0

0

0

8

1

1

1

1

1

1

1

9

1

1

1

1

0

1

1

        到这里就可以进行数码管译码模块的程序编写了,如下便是数码管的译码模块的代码了,该例程位于Traffic_light\module_test\Nixie_tube中。

//--------------------------------------------------
//--design name :Nixie_tube
//use			:数码管译码
//engineer		:比特电子工作室
//version		:V0.1
//change note	:
//-----------------------------------------------------
module Nixie_tube
(
    input           clk      ,
    input           rst_n    ,
    input       [3:0] number  ,
    output  reg [6:0] seg_data  //从高到低位abcdefg
);

always @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        seg_data <= 7'b0000000;
    end
    else begin
        case(number)
            4'h0   : seg_data <= 7'b1111110;
            4'h1   : seg_data <= 7'b0110000;
            4'h2   : seg_data <= 7'b1101101;
            4'h3   : seg_data <= 7'b1111001;
            4'h4   : seg_data <= 7'b0110011;
            4'h5   : seg_data <= 7'b1011011;
            4'h6   : seg_data <= 7'b1011111;
            4'h7   : seg_data <= 7'b1110000;
            4'h8   : seg_data <= 7'b1111111;
            4'h9   : seg_data <= 7'b1111011;
            default: seg_data <= 7'b0000000;
        endcase
    end
end
endmodule

       仿真结果如下图:

        

       可以用该仿真结果与译码表进行比对,可以证实译码结果正确。

2.3 主逻辑运行模块

       主逻辑运行在FPGA设计中可以理解为状态机,那么状态机肯定离不开状态图,交通灯的运行无非就是倒计时并控制灯,如果只考虑一个方向的灯的状态那就变得更加简单,计时一到就改变灯的状态,再次进行下一个状态的计时即可,那么我么如何保证两个方向的灯能协同好呢?看如下的状态图就能明白:

CASE_01 基于FPGA的交通灯控制器_第7张图片 ​​​​​               

        由于FPGA并行的特点,可以将A方向和B方向作为两个分立的状态机同时运行,并且遵循以下两点原则即可保证交通灯的正常运行:

  1. A方向以绿灯亮为初始状态,B方向以红灯亮为初始状态;(可互换)
  2. A方向上红灯不亮的时间等于B方向上红灯不亮的时间,且两个方向上状态运行完一圈的时间相等;

        只要满足以上两点,时间任意设置,这里就可以满足一些路口需要主干道与支干道信号灯时间不同的要求;

在这里做如下设计:

CASE_01 基于FPGA的交通灯控制器_第8张图片

       可以通过计算验证设计是否合理:

A方向从绿灯到最后一个黄灯所需的时间是55S,B方向红灯恰好是55S;

反过来B方向也是如此,两边运行完一圈状态都是110S。可见这是一个标准的十字路口,两个方向的时间是相同的。若要配置为分主支干道的交通灯,只需遵守以上提到的两点随意分配时间即可。

       分析到这里就可以进行逻辑的设计了,该例程位于Traffic_light\module_test\Lignt_run

        仿真结果如下图:

        CASE_01 基于FPGA的交通灯控制器_第9张图片

        粗略看AB两个方向上的完全符合交通灯逻辑,A方向上绿灯+黄灯+左转灯+黄灯 = B方向红灯时间,反过来也是如此;再看一个细节图:

        CASE_01 基于FPGA的交通灯控制器_第10张图片

        倒计时时间非常准确,表明该模块已经完全满足设计的要求了。

3 系统逻辑设计

        在上一章节中,已经分模块对交通灯的各个模块进行了设计和仿真验证,那么到这里需要有机的将各个模块组合起来,便能完成的交通灯设计。

以下便是将各个模块组合的代码,该例程位于Traffic_light\system_test\Traffic_light中。

        使用quartuse ii对系统工程进行综合以后,点击RTL_VIWER系统可以帮组自动生成设计的系统框图(RTL视图),如图:

       CASE_01 基于FPGA的交通灯控制器_第11张图片

       该图可以清晰的看出各个模块之间的信号走向和连接关系,同时与1.2逻辑设计初窥中的逻辑设计框图是一样的,只是细节表现的更具体了,下面就来对整个设计进行仿真。

       仿真图如下:

CASE_01 基于FPGA的交通灯控制器_第12张图片

       可以看到仿真结果与主逻辑运行模块的仿真结果是一样的,只是倒计时的显示变成了数码管的段码而已,看一下细节图:

CASE_01 基于FPGA的交通灯控制器_第13张图片

       对用段码翻译成数字,可以看出A方向绿灯初始时间为30S并依次递减,B方向红灯为55S也依次递减,证明设计是正确的。

4 硬件设计

        前面硬件描述语言已经把整个设计的做完,功能仿真也进行完毕了。但是硬件设计的核心器件还没有定下来。那么下面来进行器件选型。首先按照之前的选择的器件(EP4CE10F17C8)对工程进行综合编译,可以看到资源占用报告,如图:

CASE_01 基于FPGA的交通灯控制器_第14张图片

       设计占用该芯片的资源1%都不到,这样显然是不合理的。换用该系列资源最少的芯片(EP4CE6E22C8)对工程进行综合编译,得到资源占用如图:

CASE_01 基于FPGA的交通灯控制器_第15张图片

       设计占用该芯片资源的2%,实则也是不合理的。如果非要用该系列FPGA来做,无疑该芯片已是最佳选择。

       那么最佳的方案是哪一个呢?撇开FPGA,其实CPLD同样也可以实现的,采用EPM240T100C5对工程进行编译得到如下资源占用报告:

CASE_01 基于FPGA的交通灯控制器_第16张图片

       可以看出设计占用了该器件60%的资源,这样还有40%的资源余量,那这样看来该器件 才是完成该设计的最佳选择。

       下面以FPGA为例选用EP4CE6E22C8来完成该设计,下面分模块对硬件原理图进行讲解。

4.1 电源接口电路设计

CASE_01 基于FPGA的交通灯控制器_第17张图片

        电源接口电路采用了两种供电的方式,满足不同的情况下使用。

1Micro Usb供电,取电方便,用智能手机的充电线或者充电宝均可取电;(2)排针供电,但是必须要实验室直流电源通过排线接入5V电源。

        电路中使用D1用来防反接,防止电源接反,R1使用的是自恢复保险丝,当后面电路存在短路的情况时,保险丝会断开,防止烧坏后面电路的器件,LED作为一个电源指示灯,当电源接好并且K1开关打开时,电源指示灯常亮。

4.2 电源系统设计

        FPGA芯片需要用到3种电源供电,所以电路中设计3种电源转换电路。

        (1)5V电源转3.3V,E1、E2用来滤波储能,C3、C6用来滤出高频电源噪声。

CASE_01 基于FPGA的交通灯控制器_第18张图片

        (2)5V电源转2.5V,外部加的滤波电容功能同上。

CASE_01 基于FPGA的交通灯控制器_第19张图片

        (3)3V电源转1.2V,外部的电容功能同上。

CASE_01 基于FPGA的交通灯控制器_第20张图片

4.3 时钟设计

CASE_01 基于FPGA的交通灯控制器_第21张图片

        全局主时钟采用50M有源晶振设计,频率精度高、稳定性好,C7、C8用来滤除有源晶振的电源噪声。

4.4 JTAG端口和FPGA配置电路设计

CASE_01 基于FPGA的交通灯控制器_第22张图片

        程序的下载,采用通用的JTAG方式下载程序,由于FPGA掉电易失,所以需要挂一个存储器,电路中选用的是EPCS16S18N,配置管脚需要注意的地方,就是有些脚需要上拉电阻。

4.5  FPGA芯片的电源引脚

CASE_01 基于FPGA的交通灯控制器_第23张图片

FPGA的电源引脚分布情况,VCC_3V3,VCC_1_2,以及VCC_2.5。

4.6 A方向信号灯电路

CASE_01 基于FPGA的交通灯控制器_第24张图片

         A方向上的信号灯分为红,绿,黄,左转等4种,都是高电平点亮,而数码管采用的是7段共阴极数码管,在程序中需要编程实现显示的数字。

4.7 B方向信号灯电路

CASE_01 基于FPGA的交通灯控制器_第25张图片

        电路里面的控制方式同A方向上的相似。

4.8 复位电路

CASE_01 基于FPGA的交通灯控制器_第26张图片

       复位电路,用于程序的复位,本电路中使用的是低电平复位。

4.9 PCB设计图

CASE_01 基于FPGA的交通灯控制器_第27张图片

 4.10  实物图

CASE_01 基于FPGA的交通灯控制器_第28张图片

5 实物验证

        在这里就已经到达设计的最后一个阶段了,需要把整个设计在实物上进行验证。

5.1 管脚分配

Step1:打开Traffic_light\formal_code\Traffic_light中的工程

CASE_01 基于FPGA的交通灯控制器_第29张图片

 Step2:选择Pin Planner

Step3:根据《管脚分配手册》,对管脚进行分配

CASE_01 基于FPGA的交通灯控制器_第30张图片

        分配完成以后保存并从新编译工程。(注:在正式程序的工程中,管脚已经分配好,所以使用时无需再进行分配,这里只是带大家学习这一过程。

5.2  实物验证

        最后一步任务就是把程序下载进入设计的开发板中,然后就可以验证功能是否正确了。

Step1:将实物行如下连接:

CASE_01 基于FPGA的交通灯控制器_第31张图片

 Step2: 打开Traffic_light\formal_code\Traffic_light中的工程

CASE_01 基于FPGA的交通灯控制器_第32张图片

   Step3:打开programmer

  Step4:设置硬件链接

CASE_01 基于FPGA的交通灯控制器_第33张图片

 Step4:点击start等待下载完成,下载完成后重新上电

CASE_01 基于FPGA的交通灯控制器_第34张图片

运行结果:(工程中的下载配置文件已固化好,下载即可,若想学习如何进行下载文件的生成,请自行搜索相关方法  

CASE_01 基于FPGA的交通灯控制器_第35张图片

    资料合集包传送门:

          至此,基于FPGA的交通灯的全部设计流程已经讲解完毕,博客中讲解了所有的设计原理和设计重点,需要进一步学习的可下载全套资料合集包,本案例资料包含Verilog和VHDL两个版本,请下载自己需要的版本:

        Verilog资料合集传送门: Traffic_light_Verilog.rar

        VHDL资料合集传送门:Traffic_light_VHDL_new.rar

资料包含内容如下:

文件夹名

功能描述

备注

bom

元器件清单

module_test

模块级的仿真工程(可能采用不同的仿真形式和仿真工具,具体以对应的博客为准)

需要安装Quartuse II 13.1

system_test

系统级的仿真工程(可能采用不同的仿真形式和仿真工具,具体以对应的文档为准)

需要安装Quartuse II 13.1

formal_code

程序工程的实物运行版本版本,用于下载到板卡上运行的(与仿真版本只有参数上的差异,并且生成了配置文件)

需要安装Quartuse II 13.1

sch&pcb

原理图和PCB设计图

打开文档需要安装Adobe Acrobat

video

产品设计讲解课程,与document的文件使用方法相同,也需要用你的机器码来获取播放密码。并且需要“比特电子视频专用播放器”打开,否则会报文件损坏错误。

使用“比特电子视频专用播放器” 去打开视频

软件提取网址

工作室提供了文件使用所需要的软件下载地址和对应的软件安装使用教程提取网址

你可能感兴趣的:(fpga,verilog,vhdl,硬件)