⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 新建 文本文档.txt

📁 交通灯的设计
💻 TXT
字号:
基于VHDL语言的交通灯控制器设计

04信息工程 0416424030 卞跃宇
同组合作人:陆圣仙 丁悦 孙斌 王绍正 顾成国(2007年6月)


【摘 要】以交通灯控制器设计为例, 系统地阐述了用FPGA/CPLD实现数字电路的设计过程, 展示了FPGA/CPLD的强大功能和非凡特性。
关键词: 数字系统,交通灯控制器,EDA,FPGA,CPLD,MAX_plus II
【Abstract 】Through analyzing the design process of TLC(Traffic Light Controller),this paper describes in detail the design process of implementing the digital circuit with FPGA/CPLD,and it shows the powerful function and excellent character of FPGA/CPLD. 
Keywords:digital system,EDA,FPGA/CPLD,MAX+plus II,traffic light controller(TLC)
 


引言
    自1987年VHDL(Very High Integrated Circuit Hardware Description Language 即超高速集成电路硬件描述语言),被定为IEEE标准IEEE-STD-1076以来,VHDL已被工业界广泛认可,并取得了巨大成功,成为数字系统设计和存档的重要工具,极大的提高了数字系统的设计水平和效率。而八十年代中期诞生的复杂可编程逻辑器件 CPLD 和现场可编程逻辑门阵列 FPGA 以其大大提高了处理速度,可重复编程,功能灵活,降低了初始设计费用等优点,使得它的应用越来越广泛,特别是在产品生产前期和小批量生产中由于成本比使用专用集成电路(ASIC)便宜,因而有着非常广泛的市场潜力。本设计正是基于VHDL语言全文本输入进行底层 CPLD开发。
 


设计要求

1、显示一个方向的绿、黄、红的指示状态。
2、特殊情况按键能实现特殊的功能,计数器停止计数并保持在原来的状态,显示红灯状态。 特殊状态解除后能继续计数.
3、复位按键实现总体计数清零功能。
4、实现正常的倒计时功能. 用数码管作为倒计时显示, 显示时间为绿灯17s,黄灯3s红灯20s。
|----------------->|--->|-------------------->|
|       绿灯       |黄灯|        红灯         |
 
  设计思想

    首先由晶振产生出发信号,由控制器处理成1HZ的时钟,利用此时钟进行计数,通过判断计数的值来控制交通灯的亮灭。通过每种灯亮的时间总数与计数值比较得到数码管应该显示的数值,利用分位程序将其分成十位和个位。通过译码电路来实现数码管的显示。
    本实验所使用的芯片为EPM7128SLS84-6,实体逻辑单元为64点,结构体逻辑单元为128点,是一种小型芯片。

软件

    本实验使用MAX+plus II 10来进行程序的编写,编译,仿真以及下载。在实验中发现其功能虽然使用,但仍有地方需要改进,不支持MOD取余运算。
(源程序)
    *在MAX+plus II中,汉字很容易出现乱码,建议大家用英文,这里为了考虑到读者的习惯,因此在写论文时都译成中文
Library IEEE;
Use IEEE.std_logic_1164.all;

Entity redgreen is
Port
(
    clock_in:in std_logic;
    hold_state:in std_logic;
    reset_state:in std_logic;
    led_red,led_green,led_yellow:out std_logic;
    select_en:buffer std_logic;
    select_display:out std_logic_vector(0 to 6)
);
end;

Architecture half of redgreen is
constant loop_hz:integer:=800000; --根据晶振实际频率算出来
signal count_time:integer range 0 to loop_hz;
signal clock_buffer:std_logic;
signal clock_out:std_logic;
signal count_num:integer range 0 to 40;
signal display_num:integer range 0 to 20;
signal display_shi:integer range 0 to 9;
signal display_ge:integer range 0 to 9;

constant loop_time:integer:=40; --一个循环周期的时间
constant red_time:integer:=20; --红灯的时间
constant green_time:integer:=17; --绿灯的时间
constant yellow_time:integer:=3; --黄灯的时间
begin
    process(clock_in) --分频进程
    begin
        if rising_edge(clock_in) then
            if count_time=loop_hz then
                count_time<=0;
                clock_buffer<=not clock_buffer;
            else
                count_time<=count_time+1;
            end if;
        end if;
        clock_out<=clock_buffer; --输入1HZ的频率
    end process;

    process(reset_state,clock_out) --计数进程
    begin
        if reset_state=1 then --重启后计数归零
            count_num<=0;
        elsif rising_edge(clock_out) then
            if hold_state=1 then --紧急时计数占停
                count_num<=count_num;
            else
                if count_num=loop_time-1 then
                    count_num<=0;
                else
                    count_num<=count_num+1;
                end if;
            end if;
        end if;
    end process;

    process(clock_out) --交通灯显示
    begin
        if falling_edge(clock_in) then
            if hold_state=1 then --占停时红灯亮
                led_red<=1;
                led_green<=0;
                led_yellow<=0;
            else
                if count_num                    display_num<=green_time-count_num;
                    led_red<=0;
                    led_green<=1;
                    led_yellow<=0;
                elsif count_num                    display_num<=green_time+yellow_time-count_num;
                    led_red<=0;
                    led_green<=0;
                    led_yellow<=1;
                else
                    display_num<=loop_time-count_num;
                    led_red<=1;
                    led_green<=0;
                    led_yellow<=0;
                end if;
            end if;
        end if;
    end process;

    process(display_num) --分位进程
    begin
        if display_num>=20 then
            display_shi<=2;
            display_ge<=display_num-20;
        elsif display_num>=10 then
            display_shi<=1;
            display_ge<=display_num-10;
        else
            display_shi<=0;
            display_ge<=display_num;
        end if;
    end process;

    process(clock_in) --数码管显示
    begin
        if falling_edge(clock_in) then
            select_en<=1;    --因为我们的实验箱采用数码管并联方式,所以这里用动态显示
            case display_shi is
                when 0=>select_display<=1111110;
                when 1=>select_display<=0110000;
                when 2=>select_display<=1101101;
                when others=>select_display<=0000000;
            end case;
            if select_en=1 then
                select_en<=0;
                case display_ge is
                    when 0=>select_display<=1111110;
                    when 1=>select_display<=0110000;
                    when 2=>select_display<=1101101;
                    when 3=>select_display<=1111001;
                    when 4=>select_display<=0110011;
                    when 5=>select_display<=1011011;
                    when 6=>select_display<=1011111;
                    when 7=>select_display<=1110000;
                    when 8=>select_display<=1111111;
                    when 9=>select_display<=1110011;
                    when others=>select_display<=0000000;
                end case;
            end if;
        end if;
    end process;
end;
--由于时间和硬件限制,这个程序仅仅实现了一路交通灯,用类似的方法可以写出两路交通灯的程序。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -