首页 行业资讯 宠物日常 宠物养护 宠物健康 宠物故事
您的当前位置:首页正文

FPGA智能小车设计

2020-12-06 来源:画鸵萌宠网
天水师范学院

《基于EDA的小车控制器的设计》

实践报告

学院: 物理与信息科学学院 专业: 电子信息科学与技术 班级: 11 级电信二班 姓名: 尹天林 倪波波

学号: 235 219

#

*

2013年12月30日

'

目 录

摘要 ........................................... 错误!未定义书签。

1 引言 .........................................................1 选题背景 ...................................................... 1 智能小车简介 .................................. 错误!未定义书签。 FPGA在控制方面的应用 ......................... 错误!未定义书签。

本课题研究目的及意义 .......................... 错误!未定义书签。

^

研究目的 ...................................... 错误!未定义书签。 研究意义 ...................................... 错误!未定义书签。 2 总体方案说明 ................................. 错误!未定义书签。 设计目标 ...................................... 错误!未定义书签。 方案概述 ....................................... 错误!未定义书签。 3 软件设计 ..................................... 错误!未定义书签。 VHDL语言介绍 ................................. 错误!未定义书签。

Quartus II软件介绍 ........................... 错误!未定义书签。

`

分频器模块 .................................... 错误!未定义书签。 分频器的功能 .................................. 错误!未定义书签。 分频器的设计 .................................. 错误!未定义书签。 周期运行控制模块 .............................. 错误!未定义书签。 周期运行控制模块实现的功能 .................... 错误!未定义书签。 状态机简介 .................................... 错误!未定义书签。 周期运行控制模块的设计 ........................ 错误!未定义书签。

避障模块 ...................................... 错误!未定义书签。

'

避障模块实现的的功能 ........................... 错误!未定义书签。 避障模块的设计 ................................ 错误!未定义书签。 遥控模块 ...................................... 错误!未定义书签。 遥控模块的功能 ................................ 错误!未定义书签。 遥控模块的设计 ................................ 错误!未定义书签。 循迹模块 ....................................... 错误!未定义书签。

驱动模块 ....................................... 错误!未定义书签。

驱动模块的功能 ................................ 错误!未定义书签。

脉冲宽度调制调速基本原理 ...................... 错误!未定义书签。 驱动模块的设计 ................................. 错误!未定义书签。 模式选择模块 ................................... 错误!未定义书签。 顶层图设计 ..................................... 错误!未定义书签。 4 硬件设计 ..................................... 错误!未定义书签。 检测电路 ...................................... 错误!未定义书签。 遥控接收电路 .................................. 错误!未定义书签。

驱动电路 ...................................... 错误!未定义书签。

直流电机驱动原理 .............................. 错误!未定义书签。 L298N电机驱动芯片及驱动电路 .................. 错误!未定义书签。 模式选择电路 .................................. 错误!未定义书签。 5 设计结果 ..................................... 错误!未定义书签。 硬件组装 ...................................... 错误!未定义书签。 软硬件联合测试 ................................ 错误!未定义书签。 测试准备 ...................................... 错误!未定义书签。

6 总结与展望 ................................... 错误!未定义书签。

^

附录A ........................................................ 27

摘 要:现场可编程逻辑阵列(FPGA)具有可在线反复编程,开发周期短,并行处理,运算速度快,集成度高,可靠性高等特点,广泛应用于数字信号处理,工业控制,通信等各个领域。基于FPGA设计控制器,可以把一些外设和逻辑器件集成起来,从而缩小体积,减少电路的走线,降低功耗,提高可靠性,同时能够通过在线编程来修改和扩充控制器功能,缩短了开发周期,也使系统的使用变的灵活,扩展方便。由于FPGA可以实现真正的并行处理,并且运算速度快,用它实现复杂的控制算法可以提高算法运算速度,满足实时控制要求。

本设计是典型的软件和硬件结合的设计产品,基于EPM570T100C5型FPGA芯片设计了一个较为通用的小车控制器。通过数字量输入/输出通道连接了障碍检测模块无线接收模块;电机驱动模块;模式选择模块等。采用硬件描述语言(Verilog HDL)实现了对各个功能模块的编程、仿真、编程下载、功能测试。并在Quartus II开发环境下搭建了一个基于FPGA的小车控制器研究平台,用Verilog HDL语言实现了整个系统的设计和仿真,使小车控制器系统实现了周期运行、避障、循迹、遥控等功能。通过此方法可在软件中嵌入不同的控制算法,扩展多种控制性能,实现各种硬件功能,这种基于FPGA的电子设计的开发方法可根据需要随时增加扩展用户需要的功能,具有很大的开发潜力,在工业控制中有一定的推广应用价值。 1引言 选题背景

1.1.1智能小车简介

工业的发展对生产的自动化程度和产品精度要求越来越高,传统的人工很难适应产业升级带来的挑战;科技的进步使得人类的探索范围越来越大,亟需一种能够在恶劣的环境替代人类完成任务的智能装置。智能机器人控制系统应运而生。工业机器人和探测机器人的发展成为了当下机器人发展的主要方向,智能小车是机器人的一种,又称轮式机器人,在工业和探测两个领域均有广泛应用。

智能小车控制器的设计具有极强的可移植性和易扩展性,可应用于替代一些单调枯燥简单重复的岗位。同时,配合传感器等数据采集装置,小车可以作为一个独立运动单元自主执行一些要求更高的任务。在军事上,现代战争的复杂程度越来越高,需要在复杂恶劣的环境中完成各种侦察或作战任务,增加了作战人员的危险性;在工业、民用、社会公共设施等诸多领域上,比如在恶劣环境下进行的科学研究、在危险地段作业、危险品排除等诸多场合需要人们冒着巨大的风险;在影视剧拍摄、家庭服务、智能化家居、康复医疗等多种应用领域,为了确保工作人员的安全性,提高舒

适性,都急需一种能够替代人完成这些任务的机器人。

智能小车控制系统为人类突破这些限制提供了条件。这种智能小车可以适应不同环境,不受温度、大气、重力、强辐射等外界条件的影响,在人类不适宜的工作环境或者技术含量较低的高强度任务中有效地替代人类完成工作,提高效率。从机器人诞生至今,随着科学技术的不断发展,机器人应用已经从制造领域向非制造领域发展,原先只是在航空军事领域中才使用的机器人也开始走进人们的日常生活。

机器人的发展经历了三代,第一代机器人属于示教再现型,第二代则具备了一定的环境感知能力,第三代机器人是智能型机器人,它除了具有感觉能力之外,还具备独立辨别和自主运动能力。它上面装有多种环境感应设备,是人工智能技术发展到高级阶段的产物。随着计算机、网络、微电子等领域迅速发展,人类活动领域的不断扩大,智能小车的应用领域也不断扩大,有了客观的发展理由:

a. 智能小车系统可以把人从有毒有害、缺氧、高压、高温等危险的环境中解放出来。比如,发电厂的高温环境的设备检修,煤气管道的修复,易燃易爆危险品排除装置等。

b. 智能小车系统可以进入到人类无法生存或无法进入的区域代替人类工作,例如可以把智能小车送入太空,探测火星;或者潜入海底,勘探资源等。

c. 随着经济的不断增长及互联网的迅速普及,人们的生活水平和质量不断提高,智能化家居生活开始推广开来,人们可以通过网络远程控制家中的智能小车完成特定的任务,比如整理房间、远程监控等。 1.1.2FPGA在控制方面的应用

FPGA是英文Field Programmable GateArray的缩写,即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上经过进一步发展的产物。出现至今历经30年的发展,FPGA已由当初的1200门发展成为今天的百万门级。FPGA一般是基于SRAM工艺,基本结构是基于查找表加寄存器结构。FPGA采用了逻辑单元阵列LCA(LogicCell Array),内部包括可配置逻辑模块CLB(ConfigurableLogicBlock)、输出输入模块IOB(Input Output Block)和内部连线(InterConnect)三个部分。FPGA是由存放在片内RAM中的程序来设置其工作状态的,因此,在其工作时需要对片内的RAM进行编程。用户可以根据不同的模式进行配置,并可以采用不同的方式进行编程。

FPGA芯片在控制方面可实现的优点:

a. 采用FPGA芯片设计ASIC电路,不需要大量生产,就能得到适用的芯片;

b. FPGA芯片可做其它全定制或半定制ASIC电路的中试样片;

c. FPGA芯片内部有丰富的触发器和I/O引脚; d. FPGA芯片设计周期最短、开发费用低、风险小;

e. FPGA芯片采用高速CHMOS工艺,功耗低,可以与CMOS、TTL电平兼容。

基于以上特点,可以说FPGA芯片是小批量系统提高系统集成度、可靠性是实现小车控制的最佳选择之一。 本课题研究目的及意义 1.2.1研究目的

为了适应工业和科技的快速发展产生的新要求,使生产达到较高的自动化水平和效率及实现产品精度的提高,基于FPGA的小车控制系统应运而生。本设计意在设计一种设计具有较强可移植性的小车控制器,经改进可应用于替代一些单调枯燥简单重复的岗位,如流水线、仓储物流等。设计功能包括周期运行、自动避障、循迹、遥控运行,这些功能具有很强的使用意义,正常状态下小车能够自主周期运行完成设定的任务,遇到障碍物能够自行躲避,在一些突发情况下能够人工干预小车的运行。

本次设计旨在用来检查这学期专业知识的学习情况,通过综合知识运用锻炼解决问题的能力,通过软硬件设计锻炼实践能力,通过对设计全局的把握培育系统观念。 1.2.2研究意义

本课题以FPGA芯片为控制器设计了智能小车控制系统,意义如下: a. 基于FPGA开发的控制器具有运算速度快,体积小,修改方便,集成度高,可靠性高,易扩展等优点。

b. 用FPGA实现智能算法可以提高算法的运算速度,满足实时控制的要求。本文在基于FPGA实现复杂的智能算法方面作了一些探索性的工作,为以后进一步嵌入其它复杂算法打下了基础。

c. 搭建了智能小车控制系统的实验平台,为将来进一步研究和开发智能小车控制器做了基础性工作。

d. 对这学期所学的专业知识进行系统梳理、综合运用。 2总体方案说明 设计目标

本课题基于EDA技术,使用Altera公司的的EDA软件开发工具Quartus II进行设计准备、设计输入、功能仿真、设计处理、时序仿真和器件编程及测试,以可编辑逻辑器件FPGA为核心部件,基于FPGA核心开发板进行扩展做出硬件,主要包括以下各项:

a. 掌握利用Verilog HDL设计智能小车控制器的原理、方法;

b. 利用芯片内部时钟进行分段定时周期直线运动; c. 小车外接光电传感器检测障碍物并做出相应反应; d. 人工干预遥控运行;

e. 在FPGA开发板上,针对FPGA芯片的特点进行系统配置并验证功能的实现,并做出扩展硬件; 方案概述

本设计是基于FPGA芯片,采用Verilog HDL语言进行的EDA设计,是软硬件协同设计,分为软件和硬件设计两部分。首先进行软件的设计输入、功能仿真、设计处理,然后下载到FPGA芯片内配合外围电路进行硬件测试。

其具体功能是实现自主的周期运行,通过光电传感器检测障碍物进行避障运动,除此之外又加入了遥控功能,其原理框图如图所示。

FPGA核心板光电传感器模块遥控接收模块驱动模块 光电传感器模块是芯片外接的三个光电传感器,当传感器检测到障碍时其输出电平信号发生变化,输入电平信号经程序处理后发送到FPGA芯片,

图 小车控制器原理框图

遥控运行周期运行循迹运行魔手运行避障运行向驱动模块发出相应的信号,使小车做出适当的规避动作。

遥控模块是实现遥控运行功能的模块,包括硬件的信号接收装置和软件处理模块。遥控器以无线信号的形式从发射端发出不同的指令信号,经无线接收电路处理之后输出并行信号,FPGA芯片根据程序设定向驱动模块发出信号,小车做出相应的动作。

周期运行控制程序存储在FPGA芯片中,使用状态机进行状态循环,并在不同状态下向驱动模块发送不同的驱动信号,使小车实现周期运行。 驱动模块是接收FPGA芯片输出信号进行电机驱动的模块,由驱动程序和外围的驱动芯片两部分构成,在接收以上各模块的输出信号之后,进行处理之后输出控制信号驱动直流电机的运行。

以上各模块综合起来实现智能小车控制器的全部功能,其流程图如图所示。程序按照此流程设计完成之后下载进FPGA芯片中,完成外设电路之后再软硬件联合测试,以实现设计要求。

开始模式选择遥控模式周期运行模式循迹模式魔手模式避障模式高速前进4S接收信号停止2S减速前进4S做出相应动作检测到黑线检测到障碍YESNO检测到障碍YESNOYESNO停止2S加速后退4S做出寻线运动停止后退前进做出规避动作直行继续NO停止2SYES减速后退4S YES继续NONONO继续YES继续继续YES NO结束

图 小车控制器流程图

3软件设计

小车控制器的软件程序设计采用Verilog HDL语言,利用Altera公司的EDA开发软件QuartusII进行设计。软件部分由原理图和模块程序两部分组成,包括模式选择模块、分频器模块、电机驱动模块、周期控制模块、障碍检测模块遥控模块。以及下文将详细介绍介绍各个功能块的功能及实现方法,并给出仿真波形。

语言介绍

VHDL 的英文全名是Very High Speed Integrated Circuit Hardware Description Language,即超高速集成电路硬件描述语言,被认为是标准的硬件描述语言,有专家认为,在新世纪中,VHDL与Verilog HDL语言将承担起几乎全部的数字系统设计任务。

VHDL 主要用于描述数字系统的结构、行为、功能和接口。除了含有许多具有硬件特征的语句外,VHDL 的语言形式和描述风格与句法十分类似于一般的计算机高级语言。VHDL的程序结构特点是将一项工程设计,或称设

计实体(可以是一个元件、一个电路模块或一个系统)分成外部(或称可视部分,即端口)和内部(或称不可视部分),即设计实体的内部功能和算法完成部分。在对一个设计实体定义了外部界面后,一旦内部开发完成后,其他的设计可以直接调用这个实体。这种将设计实体分成内外部分的概念是VHDL 系统设计的基本点。

VHDL具有功能强大的语言结构,可以用简洁明确的源代码来描述复杂的逻辑控制。它具有多层次的设计描述功能,层层细化,最后可直接生成电路级描述。VHDL支持同步电路、异步电路和随机电路的设计,这是其他硬件描述语言所不能比拟的。VHDL还支持各种设计方法,既支持自底向上的设计,又支持自顶向下的设计;既支持模块化设计,又支持层次化设计。

VHDL具有多层次的设计描述功能,既可以描述系统级电路,又可以描述门级电路。而描述既可以采用行为描述、寄存器传输描述或结构描述,也可以采用三者混合的混合级描述。另外,VHDL支持惯性延迟和传输延迟,还可以准确地建立硬件电路模型。VHDL支持预定义的和自定义的数据类型,给硬件描述带来较大的自由度,使设计人员能够方便地创建高层次的系统模型。

设计人员用VHDL进行设计时,不需要首先考虑选择完成设计的器件,就可以集中精力进行设计的优化。当设计描述完成后,可以用多种不同的器件结构来实现其功能。VHDL是一种标准化的硬件描述语言,同一个设计描述可以被不同的工具所支持,使得设计描述的移植成为可能。

基于以上种种优点,VHDL作为IEEE的工业标准硬件描述语言,得到众多EDA公司支持,在电子工程领域,已成为事实上的通用硬件描述语言。 软件介绍

Max+plus II作为Altera的上一代PLD设计软件,由于其出色的易用性而得到了广泛的应用。目前Altera已经停止了对Max+plus II的更新支持。Quartus II是Altera公司继Max+plus II之后开发的一种针对其公司生产的系列CPLD/FPGA器件的综合性开发软件,它的版本不断升级,目前已经发布了版本,该软件有如下几个显著的特点:

该软件界面友好,使用便捷,功能强大,是一个完全集成化的可编程逻辑设计环境,是先进的EDA工具软件。该软件具有开放性、与结构无关、多平台、完全集成化、丰富的设计库、模块化工具等特点,支持原理图、VHDL、VerilogHDL以及AHDL(Altera Hardware Description Language)等多种设计输入形式,内嵌有综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD、FPGA设计流程。

Quartus II可以在Windows、Linux以及Unix上使用,除了可以使用TCL脚本完成设计流程外,提供了完善的用户图形界面设计方式。具有运行速度快,界面统一,功能集中,易学易用等特点。

Quartus II支持Altera公司的MAX 3000A系列、MAX 7000系列、MAX 9000系列、ACEX 1K系列、APEX 20K系列、APEX II系列、FLEX 6000系列、FLEX 10K系列,支持MAX7000/MAX3000等乘积项器件。支持MAX II CPLD系列、Cyclone系列、Cyclone II、Stratix II系列、Stratix GX系列等。支持IP核,包含了LPM/MegaFunction宏功能模块库,用户可以充分利用成熟的模块,简化了设计的复杂性、加快了设计速度。此外,Quartus II 通过和DSP Builder工具与Matlab/Simulink相结合,可以方便地实现各种DSP应用系统;支持Altera的片上可编程系统(SOPC)开发,集系统级设计、嵌入式软件开发、可编程逻辑设计于一体,是一种综合性的开发平台。 分频器模块 分频器的功能

在接口电路中,时钟信号的作用至关重要。一般的FPGA开发板或最小系统板附带的晶振频率过高,达到20MHz甚至50MHz,但是这种时钟脉冲不适合直接接入程序工作,所以需要引入时钟分频电路,即分频器,将晶振输出的脉冲分频。分频之后的时钟信号适合接入电路工作。分频器模块就是用软件方法实现分频器的功能。

时钟信号一般有两种功能,计数和选通。对于周期运行控制模块来说,每个状态都需要进行计时,所以需要接入较低频率的时钟脉冲,便于对计时器赋值。驱动模块需要进行调速,而小直流电机需要通过调节驱动脉冲的占空比进行调速,在调节占空比时就需要进行计数运算,也就需要一个合适的时钟信号。

障碍检测模块和遥控模块输入的是并行电平信号,在电平突然改变时,由于电平跃变或信号传输的延迟产生竞争冒险现象,在输出端产生尖脉冲的毛刺,从而产生误操作。为了解决这一问题,需要接入一个选通控制信号。竞争冒险一般发生在输入信号变化瞬间,若选通信号在这期间将输出关闭,等到输入信号稳定后再将输出开启,就可以消除竞争险象。选通信号也是由分频器输出的时钟信号。 分频器的设计

分频器是将较高的频率进行分频,从而得到较低的频率。需要用到计数器,高频率输入之后,触发计数器进行计数运算同时输出电平保持不变,当计数器到达一个限值时输出电平翻转。分频系数是输入频率和输出频率之比,计数上限就等于分频系数除以2再减去1。

本设计输入晶振频率是50MHz,为了方便计数和选通,输出频率设定为100Hz,计数上限为249999。

分频器模块如图所示,CLK是50MHz晶振频率输入,CLK100是100Hz时钟频率输出。

模块设计完成之后,对程序进行功能仿真,设置CLK输入接口的频率为50MHz,得到如图所示的仿真波形图。由于Quartus II软件只不适合长时间的仿真,在此截止时间设置40ms,此图只截取了一个完整周期。

图分频器仿真波形

因为50MHz的频率太高导致上升下降沿过密,所以在图中显示为一条黑色粗线,但是从时间上看波形还是正确的,在10ms时,输出端CLK_OUT100完成1个周期输出。 周期运行控制模块

周期运行控制模块实现的功能

周期运行控制模块用于实现小车的周期运行功能,通过计时器加状态机进行状态设置和状态转换。在本设计中周期运行控制模块将完成如下周期运行的控制,功能块使能之后进行周期运动。一个运动周期包括高速前进4S,停止2S,低速前进4S,停止2S,高速后退4S,停止2S,低速后退4S。之后进入下一周期再次高速前进4S。 状态机简介

本设计使用了状态机进行设计,在此先对状态机进行简要的介绍。有限状态机简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。状态机及其设计技术是使用数字逻辑设计的重要组成部分,状态机是实现高效率、高可靠性的控制逻辑的重要途径。利用状态机进行逻辑系统设计无论是与基于VHDL的其他设计方法相比还是与完成相似功能的CPU相比,都有其独到的优点。

状态机克服了纯硬件数字系统控制不灵活的缺点,能够按照输入信号的控制和预先设定的执行程序在各个状态之间顺序地执行切换,能够很好地执行顺序逻辑。状态机实现方式简单,设计方案相对固定。采用状态机设计易于构成良好的同步时序逻辑,有利于消除大规模逻辑电路中常见的竞争冒险现象。状态机与VHDL其他描述方法相比,层次分明、结构清晰、易懂好读,在模块化修改、优化、移植方面有优势。

在VHDL语言中,状态机有多种实现方式。从输出方式上分为Mealy(米里)型和Moore(莫尔)型状态机。Mealy型状态机属于同步时钟状态机,

他的输出是当前状态和所有输入信号的函数,其输出是在输入变化后立即发生的,不依赖时钟同步。Moore型状态机属于异步输出状态机,他的输出仅为当前状态的函数,在输入发生变化后,还必须等待时钟上升沿的到来,才能导致输出的改变。 周期运行控制模块的设计

为了实现周期运行控制的功能,在该模块使用状态机进行设计。首先将周期中各个运行状态在状态机中进行定义,高速前进4S、停止2S、低速前进4S、停止2S、高速后退4S、停止2S、低速后退4S分别定义为s0、s5、s1、s2 、s3、s6,S4。由此可以得到状态转换图,如图所示。

图 周期运行状态转换图

很明显,该状态机属于Moore型状态机,没有其他外部输入口,在使能之后进行顺序状态装换。每个状态在计数的同时像驱动模块发出使能信号、方向和速度控制信号。各状态对应的输出控制信号见表。

表 运行状态信号输出对照

运行状态 电机使能 转动速度 转动方向 S0 高 高速 正向 S5 低 停止 停止 S1 中 低速 正向 S2 低 停止 停止 S3 高 高速 反向 s6 低 停止 停止 S4 中 低速 反向 程序编译完成之后创建如图所示的模块文件。

图周期运行控制模块图

在该模块中,ENB输入端是模块的使能信号,CLK输入端是从分频器接入的100Hz的时钟脉冲。EN是电机驱动模块的使能控制信号输出端,ZF是电机正反转的控制信号输出端,SP是小车速度控制信号输出端。

当ENB为 低电平时该模块使能,当ENB为高电平时模块不工作。在模块使能之后,状态机直接进入s0状态,计数器在时钟脉冲上升沿时进行0到399的累加计数,同时EN端输出高电平使能信号,ZF端输出高电平正转信号,SP端输出高电平高速信号,此时小车前进。当计数器计数到399时,4S计数器清零,状态机跳转到下一状态s5。在状态s5中,计数器从0到199计数,计数周期为2S,在此期间EN端输出低电平非使能信号,ZF端输出低电平反转信号,SP端输出低电平低速运行信号,此时小车停止。当计数器计数到199时,2S计数器清零,状态机跳转到下一状态s1.当s1状态时计数器在此进行和s0相同的计数,同时EN端继续输出高电平使能信号,ZF端继续输出高电平正转信号,SP端输出低电平低速运动信号,此时小车低速前进。当计数器再次计数到399时,4S计数器再次清零,状态机跳转到下一状态s2。在状态s2中,计数器从0到199计数,计数周期为2S,在此期间EN端输出低电平非使能信号,ZF端输出低电平反转信号,SP端输出低电平低速运行信号,此时小车停止。当计数器计数到199时,2S计数器清零,状态机跳转到下一状态s3.在s3状态,除了ZF端输出低电平反方向运行信号之外其余输入输出量与s0相同。此状态下,小车高速反方向运行4S。当计数器再次计数至399时,又一次清零跳转到s6状态。在s6状态下,停止2S,又一次清零转到S4,此时ZF输出低电平反方向运行信号,其余输出同s1,此时小车低速反向运动。4S计数周期结束之后,计数器清零,状态机跳转到状态s0,开始下一周期的运行。如图所示,在使能信号输入低电平之后,EN、SP、ZF端输出相应值,并且计数周期正确。在使能信号高电平时,全部输出端口复位到低电平,待到使能端低电平时继续周期循环。

图周期运行控制模块仿真波形

避障模块

避障模块实现的的功能

避障模块接收外围电路4个光电传感器所发出的4位并行数字信号,经处理之后向驱动模块输出使能信号、正反方向信号,实现小车的障碍检测和规避障碍的功能。

避障模块的设计

由于光电传感器在没有障碍物阻挡的情况下输入的是高电平1,当传感器前方检测到障碍物时输入的是低电平0。由此可以列出小车规避障碍动作与传感器输入到FPGA芯片的电平状态对照表,见表。在表中列出了传感器输入状态的所有可能情况,并给出小车对应的规避动作。

表 传感器输入状态与小车规避动作对照表 传感器输入状态 小车动作 传感器输入状态 小车动作 0000 停止 0100 左转 0001 直行 0101 直行 0010 右转 0110 右转 0011 直行 0111 直行 1000 后退 1100 左转 1001 直行 1101 直行 1010 右转 1110 右转 1011 直行 1111 直行 根据以上分析设计出避障模块的程序,编译仿真之后创建模块文件。如

图避障模块图

图所示。

DIN2[0],DIN2[1],DIN2[2],DIN2[3]分别为小车前方中、右、左,后四个光电传感器的输入信号,ENE端为模块使能信号输入。Zuo1,zuo2为左轮的两路输入,you1,you2为右轮的两路输入,en1,en2分别为左轮和右轮的使能。当ENE输入信号为低电平时,避障模块使能,此时输入的传感器信号经模块处理之后,输出端输出相应信号,实现对障碍的规避。

编译之后进行模块的功能仿真,得到如图所示的波形。从波形上可以看出,以上设计功能全部实现。

图避障模块仿真波形

遥控模块 遥控模块的功能

遥控模块是实现遥控功能的一个功能模块,遥控器发出的指令信号经接收电路处理之后输入到FPGA芯片中,遥控模块接收到信号之后向驱动模块输出控制信号,实现与遥控信号对应的动作。 遥控模块的设计

遥控器发射的信号经接收电路处理之后,输入到FPGA芯片中的是四位并行信号。遥控器按键对应的并行信号与小车动作见表。本次设计的是模拟消防车灭火,小车是两前轮驱动,依靠车轮反向转动进行转向,并同时发出警报和七彩LED指示灯闪,所以设定遥控器上的四个按键组合进行操作。

表 遥控器按键与小车动作对照表

遥控器按键 并行输入信号 小车动作

A 0001 右转 B 0010 后退 C 0100 前进 D 1000 左转 A和B 0011 停止并开启风扇 其他按键组合 — 停止

根据以上设定编写模块程序,编译之后生成模块文件,如图所示。 CLK接入系统时钟信号,key[4..1]是经遥控接收电路处理之后的四位并行信号,ENA是模块使能信号输入端。Zuo1,zuo2为左轮的两路输入,you1,you2为右轮的两路输入,en1,en2分别为左轮和右轮的使能。Feng是控制风扇的输入端,beep是控制蜂鸣器,led1是七彩LED指示灯的控制端。

当ENA输入信号为低电平时,遥控模块使能,此时输入的4位并行信号经模块处理之后,输出端输出相应信号,实现遥控运行。

yaokongkey[4..1]ENAclkzuo1zuo2you1you2en1en2fengbeepled1inst图遥控模块图

程序编写完成之后验证其是否实现了设计功能,编译之后进行功能仿真,得到如图所示波形。

图 遥控模块仿真波形

从图上可以看出,该模块完全达到设计要求。 循迹模块

循迹模块接收外围电路4个光电传感器所发出的4位并行数字信号,经处理之后向驱动模块输出使能信号、正反方向信号,实现小车的寻黑线的功能。

由于光电传感器属于红外线反射探测,因此目标的反射率和形状是探测距离的关键。其中黑色探测距离最小,白色最大;在没有障碍物阻挡的情况下输入的是高电平1,相当于前面挡了张黑纸,当传感器前方检测到障碍物时输入的是低电平0,相当于前面挡了张白纸。由此可以列出小车循迹动作与传感器输入到FPGA芯片的电平状态对照表,见表。在表中列出了传感器输入状态的所有可能情况,并给出小车对应的规避动作。

表 传感器输入状态与小车规避动作对照表 传感器输入状态 小车动作 传感器输入状态 小车动作 0000 直行 0100 右转 0001 左转 0101 停止 0010 左转 0110 直行 0011 左转 0111 左转 1000 右转 1100 右转 1001 停止 1101 停止 1010 停止 1110 右转 1011 停止 1111 直行 根据以上分析设计出避障模块的程序,编译仿真之后创建模块文件。如

图循迹模块图

图所示。

Clk2是系统时钟脉冲,DIN [0],DIN [1],DIN [2],DIN [3]分别为小车左,中,中,右四个光电传感器的输入信号,ENC端为模块使能信号输入。Zuo1,zuo2为左轮的两路输入,you1,you2为右轮的两路输入,en1,en2分别为左轮和右轮的使能,由于循迹速度太快,现象不明显,这里给使能进行了PWM调速,速度减慢,效果才好。当ENC输入信号为低电平时,循迹模块使能,此时输入的传感器信号经模块处理之后,输出端输出相应信号,实现对黑线的循迹。

编译之后进行模块的功能仿真,得到如图所示的波形。从波形上可以看出,以上设计功能全部实现。

图循迹模块仿真波形

驱动模块 驱动模块的功能

驱动模块是本设计的基本模块之一,是将以上各模块的逻辑操作转化到实际运动的一个模块。该模块输入上述几个功能模块输出的使能、正反和速度控制信号,再将其转化为直流电机驱动信号输出到外围驱动电路中,

控制小车车轮的运行。由于本设计中出现了速度的变化,且使用的是直流电机,需要引入脉冲宽度调制(PWM)进行调速。 脉冲宽度调制调速基本原理

脉冲宽度调制,英文是“Pulse Width Modulation”,缩写PWM,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM是常用的一种调速方法,其基本原理是用改变电机接通和断开的时间比(占空比)来控制电机的速度,在脉宽凋速系统中,当电机通电时,其速度增加;电机断电时,其速度减低。只要按照一定的规律改变通、断电的时间,即可调整电机的速度。在传统的PWM调速系统中一般采用硬件作为脉冲发生器的方式,应用的元器件较多,同样会增加电路的复杂程度,随着电子技术和大规模可编程逻辑器件的发展,PWM采用软件的方法来实现调速过程,具有更大的灵活性,实现了硬件设计软件化。 驱动模块的设计

周期运行模块向驱动模块输出使能信号、正反方向信号、速度信号。速度控制是本模块在程序结构上区别于其他模块的地方。分为高速挡和低速挡,将高速模式设置为将直流电直接接到直流电机上,低速档使用PWM调速脉冲驱动。由于本设计没有精确的速度要求,将低速档位的速度能与高速挡位的速度区别开即可。按此要求完成程序设计,编译之后创建块文件,如图所示。

图 驱动模块图

Clk1为系统时钟脉冲,EN为模块使能信号输入端,ZF输入端连接的是周期模块输出的正反方向控制信号,SP输入端是周期模块输入的速度控制信号。Zuo1,zuo2为左轮的两路输入,you1,you2为右轮的两路输入,en1,en2分别为左轮和右轮的使能。

使能信号为高电平时,电机驱动模块开始工作。ZF输入为高电平时,电机正向转动;ZF输入为低电平时,电机反向转动。SP输入为高电平时,电机加速转动;SP输入为低电平时,电机低速转动。计数器在clk1时钟脉冲上升沿的触发下进行0到200的循环加法计数。在计数值在0到80区间中时,en1,en2输出低电平;计数值大于80时,en1,en2输出高电平。

对程序进行功能仿真之后得到图所示波形,从图上可以看出,输

图 驱动模块仿真波形

入输出波形完全达到设计要求。 模式选择模块

由于本设计之中包含周期运行、自主避障运行、遥控运行、魔手运行、循迹运行五种功能,功能之间的切换依靠五个自锁开关进行切换。模式选择模块的作用是为了防止自锁开关的误操作,保证当且仅当只有一个自锁开关使接通状态时向对

图 模式选择模块图

应模块输出使能信号。程序设计完成,编译之后创建块文件,如图所示。 EN_BIZHANG1,EN_YAOKONG,EN_CYCLE,EN_XUNJI,EN_BIZHANG分别对应五个自锁开关,当其中只有一个输入低电平时对应的输出端向对应能块输出低电平使能信号,并在数码管上显示数字指示第几个开关打开,其功能仿真波形如图所示。

图 模式选择模块仿真波形

顶层图设计

以上各个功能模块设计完成之后需要建立一个顶层原理图文件,将以上模

块综合起来,并按照逻辑功能连接模块之间的接线。这些工作完成之后就得到图所示的顶层图文件。

0 图 小车控制器程序顶层图

资源占用情况:

该程序运行周期过长,而QuartusII软件提供的仿真环境不适合长时间的功能仿真,故在此不进行全局仿真。

4.硬件设计

硬件设计的目的完成软件程序设计功能的硬件载体。包括FPGA芯片选取,电源模块设计,模式选择开关电路的设计,输入信号采集的光电传感器障碍检测电路、无线信号接收电路和输出信号控制的驱动电路的实现。

检测电路

检测电路包括3个光电传感器进行障碍检测,和一个以LM339四电压比较器为核心的中控电路。

本设计选用的光电传感器是NPN型光电开关。外接3条引线,分别是电源、接地、信号输出。正常状态下发射端发出红外信号,接收端没有接到发射回来的红外信号,此时感应信号输出高电平。当检测到障碍物时,发射端发出的红外信号经障碍物反射,接收端接收到红外信号,此时感应信号输出低电平。光电传感器有效探测距离3至80cm可调,本次设计通过调节滑动变阻器将探测距离设置为30cm。

中控板以LM339为核心,对传感器集中供电,并接收传感器的反馈信号,经处理输出到FPGA芯片。LM339内部包括有四个独立的电压比较器,在很宽的电源电压范围内适用于双电源工作模式,也适用于单电源工作模式。在方波发生器、时间延时器、脉冲发生器、A/D转换器等广泛应用。光电传

图 一路光电传感器与电压比较器原理图

感器信号输入到LM339中经电压比较器处理之后,向FPGA芯片输入端发送数字信号。当传感器未检测到障碍时,中控电路对应的发光二极管常亮,向芯片发送低电平;当检测到障碍时,对应发光二极管熄灭,向芯片发送高电平。一路光电传感器和原理如图所示。将三路信号输出端接入FPGA芯片,作为避障模块的输入。

图和图所示为光电传感器和中控板实物。

图光电传感器

图 感应电路中控板

遥控接收电路

遥控接收电路采用SC2272-M4解码电路,又名5V高频超再生四路解码接收模块。工作电压为DC5V;静态电流为;调幅调制;接收灵敏度为-105dB;工作频率315~;编码方式是焊盘编码(固定码);工作方式为点动,按住不放输出,放开停止输出。超再生接收模块采用LC振荡电路,内含放大整形,输出的数据信号为解码后的高电平信号,使用极为方便,并且价格低廉,所以被广泛使用。遥控接收电路原理如图所示,VT是无线接收状态输出端,D3至D1是四位并行信号输出[17]。

图 SC2272无线接收模块原理图

图和图所示为无线信号收发模块。

图 SC2272无线信号接收模块 图 无线信号发送模块

驱动电路 直流电机驱动原理

直流电机的驱动方法是H桥驱动,电路得名 “H桥驱动电路”是因为它形似字母H。图中所示为一个典型的直流电机驱动电路。如图所示,H桥式电机驱动电路包括4个三极管和一个直流电机。要使得直流电机运转,须导通对角线上的一对三极管,形成电势差。根据不同三极管对的导通情况,电流可能会从两条线路流过直流电机。左上方至右下方流过直流电机或从右上至左下流过直流电机。通过电流不同的流向控制直流电机的转动方向。例如,当三极管Q1和三极管Q4导通,这时电流就从电源正极经Q1从左上方至右下方穿过直流电机,然后从Q4发射极重新流回到电源的负极。该流向的电流将会驱动直流电机做顺时针转动。当另一对三极管Q2和Q3导通时,电流将从右上至左下流过直流电机,电流将从右至左流过直流电机,此时驱动直流电机做逆时针转动。

图 H桥驱动电路

然而在实际使用的时候,用分立元件制作H桥是很麻烦的,好在现在市面上有很多封装好的H桥集成电路,接上电源、电机和控制信号就可以使

图 L298N 驱动电路

用了,在额定的电压和电流内使用非常方便可靠。比如常用的L293D、L298N、ULN2003等。

电机驱动芯片及驱动电路

L298N是ST公司生产的一种高电压、大电流电机驱动芯片。该芯片采用15脚封装。主要特点是:工作电压高,最高工作电压可达46V;输出电流大,瞬间峰值电流可达3A,持续工作电流为2A;额定功率25W。内含两个由四个大功率晶体管组成的H桥电路构成的H桥高电压大电流全桥式驱动器(如图所示),可以用来驱动直流电动机和步进电动机、继电器线圈等感性负载;采用标准逻辑电平信号控制;具有两个使能控制端,在不受输入信号影响的情况下允许或禁止器件工作有一个逻辑电源输入端,使内部逻辑电路部分在低电压下工作;可以外接检测电阻,将变化量反馈给控制

图 L298N芯片内部原理图

电路。使用L298N芯片驱动电机,可以驱动一台两相步进电机或四相步进电机,也可以驱动两台直流电机。本次设计使用该芯片驱动两台直流电机。

图所示是L298N的电机驱动原理,表是L298N其中一组输入信号与对应直流电机转动状态的对照。IN3与IN4的输入与直流电机转动方向与此相同。这样将四路输入组合起来,通过电平信号的组合就能控制两直流电机的转动状态,实现小车的直行转弯。

表输入电平信号与电机转动状态对照 ENA IN1 IN2 电机转动状

1 1 0 正向转动 1 0 1 反向转动 0 1 0 停止

0 0 1 停止

L298N也给出了电机速度控制的解决办法,当驱动电路使能端为高电平时直流电机转动,当使能端为低电平时直流电机停止转动。那么给使能端接入FPGA芯片输出的的PWM控制信号就能实现对直流电机转动速度的控

图 L298N驱动模块

制。L298N驱动模块实物如图。 模式选择电路

模式选择电路采用三路开关向FPGA芯片输出低电平信号,实现不同功能之间的切换。电路原理如图所示。

S1PIN35S2PIN38S3PIN36S4PIN34S5PIN20图 开关电路原理图

5设计结果 硬件组装

将以上硬件组装起来,并用杜邦线将各输入输出端口相连接,得到小车的硬件成品,如图所示。

图 小车硬件实物图

软硬件联合测试

软件程序和硬件电路全部完成之后进行软硬件的联合调试。首先对程序进行引脚锁定,编译之后,将生成的.sof文件下载到FPGA芯片中去,然后进行各功能实现情况的测试。 测试准备

测试之前先要进行引脚锁定,将原理图中德输入输出端与FPGA芯片管脚进行映射,然后外围电路才能与软件程序配合运行。在实现功能的前提下,尽可能的将引脚设置的易于连接,得到各端口与芯片管脚对应关系见表。

表程序端口与FPGA芯片管脚对应关系

端口种类 原理图端口名称 FPGA对应管脚

EN_BIZHANG PIN34

EN_BIZHANG1 PIN20

EN_CYCLE PIN38 EN_XUNJI PIN36 EN_YAOKONG PIN35 输入端口 clk PIN12

Key[1] PIN53 Key[2] PIN52 Key[3] PIN51 Key[4] PIN50 DIN[0] PIN1 DIN[1] PIN100 DIN[2] PIN5 DIN[3] PIN4 DIN1 PIN15 DIN2[0] PIN44 DIN2[1] PIN47 DIN2[2] PIN42 DIN2[3] PIN43 DIG PIN84 SEG[0] PIN76 SEG[1] PIN83 SEG[2] PIN81 SEG[3] PIN75 SEG[4] PIN74 SEG[5] PIN78 SEG[6] PIN82 SEG[7] PIN77

输出端口

Feng PIN8 Led1 PIN16 Beef PIN73 En1 PIN71 En2 PIN70 Zuo1 PIN66 Zuo2 PIN67 You1 PIN58 You2 PIN61

引脚锁定完成之后,将未使用引脚设置为三态,除自带的电平信号引脚之外其余引脚在未使用时为高阻态。在此进行编译,编译完成之后.sof文件更新到最新状态。这时连接USBBlaster下载线,接通核心板电源,将.sof文件下载到EPM570T100C5芯片中,接下来就可进行功能测试。 6 总结与展望

基于FPGA的小车控制器的设计综合了数字电子技术、EDA技术、直流

电机电机驱动及自动控制等多种技术。本文主要结合当前FPGA技术的可在线反复编程,并行处理,运算速度快,集成度高,可靠性高,功耗低等特点,针对小车控制中实时性,智能化等要求,以Altera公司的EPM570T100C5型FPGA为基础,在FPGA应用于控制领域方面作了一些探索性的工作,并取得了一些成果。

本设计以EPM570T100C5型FPGA为核心,设计了一个较为通用的控制系统。首先进行了软件程序的设计,在QuartusII开发环境下用Verilog HDL语言完成了对各个部分的控制。各部分具有一定的通用性,可以针对不同的应用适当组合,完成具体的功能。然后选择了了核心板进行调试和扩展,在此基础上扩展了19路数字信号的输入通道,18路数字信号的输出通道。为了测试小车控制器的功能搭建了一个智能小车的框架。

随着电子技术的不断发展,智能小车系统处于不断完善创新的过程,然而由于条件限制,课题中还有一些地方值得继续研究和改进。

例如在驱动模块的设计中,本设计没有精确的速度要求,将低速档位的速度能与高速挡位的速度区别开即可。所以只是简单的将驱动脉冲占空比设置为一定值。今后可以在控制器中加入闭环转速控制功能,对小车的速度进行精确的控制。

在避障功能中,由于小车传感器数量的限制,无法进行全方位的识别,仅适用于对壁障的识别和躲避,有时还会存在死角。后期可以加入更高级的算法,通过对传感器信号序列的检测进行控制。也可以增加传感器数量或者添加距离感应器、温度传感器等实现更加高级的避障功能。

基于FPGA的小车控制器的功能有待日后进一步的扩展,本次设计搭建的智能小车平台在今后的设计中可以在软件中嵌入不同的控制算法,扩展多种控制性能,以实现更多的功能,替代人工完成生产、探测、服务等工作。

附录A 程序:

:

module

switch_(EN_BIZHANG1,EN_YAOKONG,EN_CYCLE,EN_XUNJI,EN_BIZHANG,ENA,ENB,ENC,END,ENE,DIG,SEG);

input EN_YAOKONG,EN_CYCLE,EN_XUNJI,EN_BIZHANG,EN_BIZHANG1; output ENA,ENB,ENC,END,ENE,DIG; output [7:0] SEG; reg [7:0] SEG;

reg ENA,ENB,ENC,END,ENE; assign DIG=0;

always @(EN_YAOKONG or EN_CYCLE or EN_XUNJI or EN_BIZHANG or EN_BIZHANG1)

begin

if (!EN_BIZHANG1) begin if (!EN_YAOKONG) begin if(!EN_CYCLE) begin

if(!EN_XUNJI) begin if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end else begin

if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end end

else begin if(!EN_XUNJI) begin if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end else begin

if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end

end end

else begin

if(!EN_CYCLE) begin

if(!EN_XUNJI) begin if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end else begin

if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end end

else begin if(!EN_XUNJI) begin if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end else begin

if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=0;SEG=8'H92; end

end

end end end

else begin

if (!EN_YAOKONG) begin if(!EN_CYCLE) begin

if(!EN_XUNJI) begin if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end else begin

if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end end

else begin if(!EN_XUNJI) begin if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end else begin

if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=0;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HF9; end

end

end end

else begin

if(!EN_CYCLE) begin

if(!EN_XUNJI) begin if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end else begin

if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=0;ENC<=1;END<=1;ENE<=1;SEG=8'HA4; end//

end end

else begin if(!EN_XUNJI) begin if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0;end

else begin ENA<=1;ENB<=1;ENC<=0;END<=1;ENE<=1;SEG=8'HB0; end

end else begin

if(!EN_BIZHANG) begin ENA<=1;ENB<=1;ENC<=1;END<=0;ENE<=1;SEG=8'H99;end

else begin ENA<=1;ENB<=1;ENC<=1;END<=1;ENE<=1;SEG=8'HC0; end

end

end end end end

endmodule :

module fenpin(clk,clk100);

input clk;

output clk100; reg clk100;

reg[24:0] counter; parameter N=50_000_0; always@(posedge clk) begin

counter<=counter+1'b1; if(counter==N/2-1) begin

clk100<=~clk100; counter<=0; end end

endmodule :

module zhouqi(ENB,CLK,ZF,SP,EN); input CLK; input ENB; output ZF; output SP; output EN; reg ZF; reg SP; reg EN;

reg[24:0] counter; reg[4:0] a1;

parameter N=399,H=199,s0=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6; always @( posedge CLK ) begin

if(ENB) begin EN<=0; end else begin

case(a1)

s0 :begin ZF<=1;

SP<=1;EN<=1'b1;

counter<=counter+1'b1;

if(counter==N) begin counter<=0; a1<=s5; end end

s1 : begin

ZF<=1;

SP<=0;EN<=1'b1;

counter<=counter+1'b1;

if(counter==N) begin counter<=0; a1<=s2; end end

s2 : begin

EN<=0;

counter<=counter+1'b1;

if(counter==H) begin counter<=0; a1<=s3; end end

s3 : begin ZF<=0;

SP<=1;EN<=1'b1;

counter<=counter+1'b1;

if(counter==N) begin counter<=0; a1<=s6; end end s4 : begin ZF<=0;

SP<=0;EN<=1'b1;

counter<=counter+1'b1;

if(counter==N) begin counter<=0; a1<=s0; end end

s5 : begin EN<=0;

counter<=counter+1'b1;

if(counter==H) begin counter<=0; a1<=s1; end end

s6 : begin EN<=0;

counter<=counter+1'b1;

if(counter==H) begin counter<=0; a1<=s4; end

end

default : a1<=s0; endcase end end

endmodule :

module

xiaochekong(key,ENA,clk,zuo1,zuo2,you1,you2,en1,en2,feng,beep,led1);//

input[4:1] key; input ENA; output led1;

output zuo1,zuo2,you1,you2,en1,en2,feng; reg zuo1,zuo2,you1,you2,en1,en2,feng; input clk; //系统时钟 output beep;

reg beep; //蜂鸣器输出端 reg beep_r;

reg led1; reg[27:0]count;

always@(posedge clk) begin

count <= count + 1'b1; end

always @(count[9]) begin

beep_r = !(count[13]&count[24]&count[27]); end

always @(key) begin

if(ENA==1) begin en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;beep<=0;led1<=1; end

else begin case(key)

4'b1000:begin

en1<=1;en2<=1;zuo2<=0;you2<=0;you1<=1;zuo1<=1;feng<=1;beep<=beep_r;led1<=0;end

4'b0100:begin

en1<=1;en2<=1;zuo2<=1;you2<=1;you1<=0;zuo1<=0;feng<=1;beep<=beep_r;led1<=0;end

4'b0010:begin

en1<=1;en2<=1;zuo2<=0;you2<=0;you1<=1;zuo1<=0;feng<=1;beep<=beep_r;led1<=0;end

4'b0001:begin

en1<=1;en2<=1;zuo2<=0;you2<=0;you1<=0;zuo1<=1;feng<=1;beep<=beep_r;led1<=0;end

4'b0011:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;feng<=0;beep<=beep_r;led1<=0;end

default:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;feng<=1;beep<=0;led1<=1;end

endcase end end

endmodule :

module PWM(clk1,ZF,SP,EN,zuo1,zuo2,you1,you2,en1,en2); input clk1; input ZF; input SP; input EN;

output zuo1,zuo2,you1,you2,en1,en2;

reg zuo1,zuo2,you1,you2,en1,en2; reg [29:0]j; reg fout;

always @(posedge clk1) begin if (j>=200) j<=0;

else j<=j+1;

if(j>=1&&j<80)fout<=0;

else if (j>=80&&j<=200)fout<=1; end

always @( ZF or SP or EN ) begin

if(EN==0) begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0; end else

case(ZF)

1'b1:case(SP) 1'b1:begin

en1<=1;en2<=1;zuo2<=0;you2<=0;you1<=1;zuo1<=1; end

0:begin

en1<=fout;en2<=fout;zuo2<=0;you2<=0;you1<=1;zuo1<=1;

end

endcase 0:case(SP)

1'b1:begin

en1<=1;en2<=1;zuo2<=1;you2<=1;you1<=0;zuo1<=0;end

0:begin

en1<=fout;en2<=fout;zuo2<=1;you2<=1;you1<=0;zuo1<=0;end

endcase endcase end

endmodule

:

module xunji(clk2,ENC,DIN,zuo1,zuo2,you1,you2,en1,en2); input ENC,clk2; input [3:0] DIN;

output zuo1,zuo2,you1,you2,en1,en2; reg zuo1,zuo2,you1,you2,en1,en2; reg fout; reg [29:0]j;

always @(posedge clk2) begin if (j>=200) j<=0;

else j<=j+1;

if(j>=1&&j<100)fout<=0;

else if (j>=100&&j<=200)fout<=1; end

always @(DIN) begin if(ENC) en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0; end

else

case(DIN)

4'B0000:begin

en1<=fout;en2<=fout;zuo2<=0;you2<=0;you1<=1;zuo1<=1;end 4'B0001:begin

en1<=0;en2<=fout;you2<=0;you1<=1;zuo2<=0;zuo1<=0;end

4'B0010:begin

en1<=0;en2<=fout;zuo2<=0;you2<=0;you1<=1;zuo1<=0;end

4'B0011:begin

en1<=0;en2<=fout;you2<=0;you1<=1;zuo2<=0;zuo1<=0;end

4'B0100:begin

en1<=fout;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=1;end

4'B0101:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;end

4'B0110:begin

en1<=fout;en2<=fout;zuo2<=0;you2<=0;you1<=1;zuo1<=1;endbegin

4'B0111:begin

en1<=0;en2<=fout;zuo2<=0;you2<=0;you1<=1;zuo1<=0;end

4'B1000:begin

en1<=fout;en2<=0;zuo2<=0;zuo1<=1;you1<=0;you2<=0;end

4'B1001:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;end

4'B1010:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;end

4'B1011:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;end

4'B1100:begin

en1<=fout;en2<=0;zuo2<=0;zuo1<=1;you1<=0;you2<=0;end

4'B1101:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;end

4'B1110:begin

en1<=fout;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=1;end

4'B1111:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;end

default:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;end

endcase end

endmodule :

module bizhang1(ENE,DIN2,zuo1,zuo2,you1,you2,en1,en2); input ENE;

input [3:0] DIN2;

output zuo1,zuo2,you1,you2,en1,en2; reg zuo1,zuo2,you1,you2,en1,en2; always @(DIN2) begin if(ENE) en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0; end

else

case(DIN2)

begin 4'B1111:begin

en1<=1;en2<=1;zuo2<=0;you2<=0;you1<=1;zuo1<=1;end

4'B1110:begin

en1<=1;en2<=0;you2<=0;you1<=0;zuo2<=0;zuo1<=1;end

4'B1101:begin

en1<=1;en2<=1;zuo2<=0;you2<=0;you1<=1;zuo1<=1;end

4'B1100:begin

en1<=0;en2<=1;you2<=0;you1<=1;zuo2<=0;zuo1<=0;end

4'B1011:begin

en1<=1;en2<=1;zuo2<=0;you2<=0;you1<=1;zuo1<=1;end

4'B1010:begin

en1<=1;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=1;end

4'B1001:begin

en1<=1;en2<=1;zuo2<=0;you2<=0;you1<=1;zuo1<=1;end

4'B1000:begin

en1<=1;en2<=1;zuo2<=1;you2<=1;you1<=0;zuo1<=0;end

4'B0111:begin

en1<=1;en2<=1;zuo2<=0;zuo1<=1;you1<=1;you2<=0;end

4'B0110:begin

en1<=1;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=1;end

4'B0101:begin

en1<=1;en2<=1;zuo2<=0;you2<=0;you1<=1;zuo1<=1;end

4'B0100:begin

en1<=0;en2<=1;zuo2<=0;you2<=0;you1<=1;zuo1<=0;end

4'B0011:begin

en1<=1;en2<=1;zuo2<=0;zuo1<=1;you1<=1;you2<=0;end

4'B0010:begin

en1<=1;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=1;end

4'B0001:begin

en1<=1;en2<=1;zuo2<=0;you2<=0;you1<=1;zuo1<=1;end

4'B0000:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;end

default:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;end

endcase end

endmodule

:

module bizhang(END,DIN1,zuo1,zuo2,you1,you2,en1,en2); input END; input DIN1;

output zuo1,zuo2,you1,you2,en1,en2; reg zuo1,zuo2,you1,you2,en1,en2; always @(DIN1) begin if(END)

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0; end

else

case(DIN1) 0:begin

en1<=1;en2<=1;zuo2<=1;you2<=1;you1<=0;zuo1<=0;end

1:begin

en1<=1;en2<=1;you2<=0;you1<=1;zuo2<=0;zuo1<=1;end

default:begin

en1<=0;en2<=0;zuo2<=0;you2<=0;you1<=0;zuo1<=0;end

endcase end

endmodule

begin

因篇幅问题不能全部显示,请点此查看更多更全内容