基于FPGA自动打铃器设计
学院电子工程学院
班级 A1121班
专业电子信息工程
姓名何树良
指导教师罗静
目录
第一章 绪论..............................................4
1.1选题目标..................................................................................................41.2FPGA发展历程................................................................................4
1.2.1FPGA优点.....................................................................................5
1.3器件及工具介绍...............................................................................5
1.3.1QuartusⅡ设计步骤......................................................................5
第二章 系统方案设计......................................5
2.1设计方案分析和选择..............................................................................5
2.3分频模块设计..........................................................................................7
2.2自动打铃器总体组成..............................................................................6
2.5.1秒计数模块....................................................................................9 2.5.2分计数模块....................................................................................9 2.5.3时计数模块..................................................................................102.5.4调时模块.............................................................................................112.6闹钟模块设计........................................................................................12 2.6.1定时模块......................................................................................12 2.6.2比较模块......................................................................................132.7打铃模块设计........................................................................................15
2.8报警模块设计........................................................................................17
2.8.1报警时长设定模块.............................................................................17
2.8.2蜂鸣器发声模块..........................................................................17
2.9显示模块设计........................................................................................18
2.9.1时间切换模块..............................................................................18
2.9.2动态扫描模块..............................................................................20
2.10按键电路设计...............................................................................22
第三章 试验结果分析.....................................22
3.1测试过程................................................................................................22
3.2结果分析................................................................................................23
参考文件.................................................25
附 录...................................................26
摘要
自动打铃器为学校上下课时间正确控制提供了很大便利,而且在工厂、办公室等场所也起到了提醒大家时间作用,所以打铃器设计有一定实用意义。
本设计学校打铃器采取基于现场可编程门阵列(FPGA)方法,底层模块采取硬件描述语言(HDL)设计,不仅能对时、分、秒正常计时和显示,而且还可进行闹铃时间设定,上下课时间报警,报警时间1-15秒设置。系统主芯片采取美国Altera企业EP3C40F484I7器件,由时钟模块、控制模块、闹钟模块、定时模块、数据译码模块、显示和报时等模块组成,由按键进行时钟校时、清零、启停等。本文在介绍FPGA器件基础上,着重叙述了怎样使用FPGA器件进行系统开发,和怎样实现学校打铃系统。经过仿真验证及实际测试,打铃器含有正常计时、定时报警、报警时长设定等功效,
可为日常作息提供正确、便捷提醒。
系统运行稳定,设计方法可行。
关键词:打铃器现场可编程门阵列硬件描述语言
第一章 绪论
1.1选题目标
当今社会,电子技术应用无处不在,电子技术正在不停地改变我们生活,改变着我们世界。在这快速发展年代,时间对大家来说是越来越宝贵,在快节奏生活时,大家往往忘记了时间,一旦碰到关键事情而忘记了时间,这将会带来很大损失。所以我们需要一个定时系统来提醒这些忙碌人。
数字化时钟给大家带来了极大方便。近些年,伴随科技发展和社会进步,大家对时钟要求也越来越高,传统时钟已不能满足大家需求。
多功效数字钟不管在性能还是在样式上全部发生了质改变,自动打铃器就是以时钟为基础,在平时校园生活中是必不可少工具。
自动打铃器数字化给大家生产生活带来了极大方便,而且大大地扩展了时钟原先报时功效。诸如定时自动报警、定时启闭电路、定时开关烘箱、通断动力设备,甚至多种定时电气自动启用等,全部这些,全部是以时钟数字化为基础。所以,研究时钟及扩展应用,有着很现实意义。
本设计将借助EDA技术,完成基于FPGA器件学校打铃器设计。EDA技术发展经历了一个由浅到深过程,前后经历了CAD、CAE和现代意义上EDA三个阶段。在可编程逻辑器件(PLD)内部,
数 | 字 | 电 | 路 | 可 | 用 | 硬 | 件 | 描 | 述 | 语 | 言 | 能 | 够 | 进 | 行 | 方 | 便 | 描 | 述 | , |
经过生成元件后可作为一个标准元件进行调用。同时,借助于开发设计平台,能够进行系统仿真和硬件测试等。
借助PLD器件和硬件描述语言等开发手段,即可设计出多种比较复杂数字系统, 对于数字电子技术试验和课程设计等,尤其是数字系统性课题,
经济地设计多种高性能电子系统,而且很轻易实现、修改及完善。
1.2FPGA发展历程
作为一个可编程逻辑器件,现场可编程门阵列(FieldProgrammable Gate Array, FPGA)出现是PLD发展改变肯定,她出现推进着可编程逻辑器件深入发展。所以说,了解了可编程逻辑器件发展历程,也就了解了FPGA发展历程。
PLD是20世纪70年代发展起来一个新型器。它应用不仅简化了电路设计,降低了成本, 提升了系统可靠性,而且给数字系统设计方法带来了革命性改变,其结构和工艺改变经历了一个不停发展过程。20世纪70年代,早期可编程逻辑器件只有可编程只读存放器(PROM)、 紫外线可擦除只读存放器(EPROM)和电可擦除只读存放器(EEPROM)3种。
随即, 出现了一类结构稍微复杂可编程芯片,即可编程逻辑阵列(ProgrammableLogic
Array,PLA)。PLA在结构上由一个可编程和阵列和可编程或阵列组成,阵列规模小,编程过程复杂繁琐。PLA现有现场可编程,又有掩膜可编程[2]。
1.2.1FPGA优点
概括地说,FPGA器件含有下列优点:高密度、高速度、系列化、标准化、小型化、多功效、低功耗、低成本,设计灵活方便,可无限次反复编程,
并 | 可 | 现 | 场 | 模 | 拟 | 调 | 试 | 验 | 证 | 。 | 使 | 用 | FPGA器 | 件 | , |
通常可在几天到几周内完成一个电子系统设计和制作,能够缩短研制周期,达成快速上市和深入降低成本要求。用FPGA器件实现数字系统时用芯片数量少,从而降低芯片使用数目,降低印刷线路板面积和印刷线路板数目,最终造成系统规模全方面缩减[3]。
1.3器件及工具介绍
1.3.1QuartusⅡ设计步骤
Quartus II 是Altera企业综合性PLD开发软件,支持原理图、 VHDL、
设计输入包含原理图输入、HDL 文本输入、 EDIF网表输入、
波形输入等多个方法。编译时要依据设计要求设定编译方法和编译策略,
然后依据设定参数和策略对设计项目进行网表提取、逻辑综合、器件适配,供分析、仿真和编程使用。设计完成后需要进行仿真,能够测试设计逻辑功效和延时特征。
最终能够用得到编程文件经过编程电缆配置PLD,进行在线测试。在设计过程中,假如出现错误,则需重新回到设计输入阶段,更正错误或调整电路后重新测试。
第二章 系统方案设计
2.1设计方案分析和选择
方案一:采取通用数字器件来设计。比如,打铃器结构组成中最基础是数字钟。
数字钟实际上是一个对标准频率(1HZ)进行计数计数电路。
因为计数起始时间不可能和标按时间(如北京时间)一致,
故需要在电路上加一个校时电路,同时标准1HZ时间信号必需做到正确稳定。
采取此方法设计数字钟通常使用石英晶体振荡器电路组成数字钟。
基于此设计方案数字钟部分结构组成图2-1所表示。
图2-1数字钟部分结构组成
2.2自动打铃器总体组成
本设计内容为基于FPGA学校打铃器,控制器底层模块采取硬件描述语言设计,
顶层模块设计方法采取原理图方法;打铃器含有计时功效,能对时、分、
秒正常 计 时 和 显示 ; 又 含 有 定 时 打 铃 功 效 ,
当设定打铃时间和学校上下课时间点相同时打铃;而且计时时间、定时时间、
打铃时长(1S~15S内)自由设置和调整,其数据信息经过数码管或LCD显示。
学校打铃器总体设计框图图2-2所表示。
振荡器产生稳定高频脉冲信号,作为数字钟时间基准,然后经过分频器输出标准秒脉冲。秒计数器满60后向分计数器进位,分计数器满60后向小时计数器进位,小时计数器根据“24翻1”规律计数。计满后各计数器清零,重新计数。计数器输出分别经译码器送数码管显示。在控制信号中除了通常校时信号外,还有时钟清零信号。时基电路能够由石英晶体振荡电路组成,晶振频率为25MHz,经过分频可得到秒脉冲信号。译码显示电路由七段译码器完成,显示由数码管组成。
图2-2学校打铃器总体设计框图
2.3分频模块设计
本设计FPGA外部使用是25MHz晶振,在其内部再依据需要进行分频。
图2-3所表示为分频模块连接图。分频模块由25k分频、200分频、 5分频、50k分频、250分频组成。其中25k分频输出作为按键消抖模块输入时钟信号,其频率为1kHz;200分频输出作为计时模块调分模块时钟输入,其频率为5Hz,
周期为0.2s; 5分频输出作为计时模块中秒计时输入,为1Hz频率1s时钟信号;
50k分频输出作为动态扫描模块输入时钟,其频率为500Hz;250分频输出作为计时模块调时模块输入时钟,其频率为2Hz,周期为0.5s。
图2-3分频模块连接图
现以5分频为例进行仿真,当初钟到第五个上升沿时,输出由“0”变为“1”,下降沿时又由“1”变为“0”,产生一个脉冲。满足设计要求。
2.4消抖模块设计
这就需要加入按键消抖模块。按键消抖模块通常有硬件和软件两种方法, 在本设计早期完成后,下载程序测试时,拨动按键或按下按键时显示出现异常,
一样能够达成去抖动目标,此次设计中采取硬件模块消抖动方法。
模块实现方法是先判定是否有按键按下,如有按键按下则延时一段时间,待抖动过去以后再读行线状态,假如仍有低电平行线,则确定有按键按下,然后产生一个有按键按下信号。该模块有一个时钟输入端口,输入时钟信号是分频出来1kHZ时钟;有一个输入端口和按键端相连;一个输出端口,用于输出有按键按下信号。图2-4所表示为消抖模块符号图。
|
|
图2-4消抖模块符号图
本设计按键消抖模块内部电路相当于一个D触发器,该模块在这里实现比较简单, 原理是当有按键按下时候,d会变成高电平,当有时钟上升沿到来且按键按下时,q输出高电平。因为时钟脉冲为1kHZ,故从有按键按下到输入信号产生大约需要1ms。
而按键产生抖动时间大约2ms到10ms,所以一旦计数完成,抖动已经过去,
不会发生重键现象了,这么就去除了抖动。图2-5所表示为按键消抖模块波形仿真图。
包含秒计数模块、分计数模块、时计数模块和调时模块。2.5时钟模块设计
2.5.1秒计数模块
图2-9所表示为秒计数模块符号图。输入端口clr是秒计数模块清零信号,也是整个数字中使能信号,低电平有效; cp是秒脉冲输入端口,外接分频模块频率为1Hz时钟信号;输出端口sqmsl[3..0]是秒时钟低位,sqmsh[3..0]是高位;co端口是进位输出端口,当秒计数到59时输出高电平,其它时候输出低电平。
图2-9秒计数模块符号图
图2-6所表示波形仿真图。由图能够看出,伴随1s时钟脉冲上升沿到来,每来一次秒计数低位就产生一个脉冲,当计到9时变为0,秒计数高位变为1,当低位为9,高位为5时,也就是计到59时,高、低位全部变为0,且输出co产生一个脉冲信号,由仿真图可知满足设计要求。
2.5.2分计数模块
也是整个数字中使能信号,低电平有效; clk是秒脉冲输入端口输出端口;min0[3..0]是分计时低位,min1[3..0]是分计时高位;co端口是进位输出端口,接时计数clk作为时钟输入,当秒计数到59时输出高电平,其它时候输出低电平。
图2-7分计数模块符号图
图2-8所表示为分计数模块波形仿真图。给clk一定时钟信号以后,clr高电平清零无效,每次达成时钟脉冲上升沿时,分计数低位min0计一个数,
计到9时向高位进位,当计到59时,模块进位输出co产生一个脉冲信号,由仿真图可知此模块设计满足设计要求。
图2-8分计数模块波形仿真图
2.5.3时计数模块
图2-9所表示为时计数模块符号图。输入端口clr是时计数模块清零信号,也是整个数字中使能信号,低电平有效; clk是秒脉冲输入端口输出端口;sl[3..0]是分计时低位,sh[3..0]是分计时高位。
图2-10时计数模块波形仿真图
时计数模块波形仿真图图2-10所表示。clk接分计时模块仅为输出,给定时钟信号,clr高电平清零无效,每次达成时钟脉冲上升沿时,时计数低位sl计一个数,计到9时向高位进位,当计到24时,高、低全部变为零,计数重新开始,由仿真图可知此模块设计满足设计要求。
2.5.4调时模块
图2-11调时模块符号图
输入端口key是调时模块调时开关,当为高电平是输出a数据,当为低电平时输出b数据;
图2-11所表示为调时模块符号图。本设计调时模块类似于二选一数据选择器,
图2-12调时模块波形仿真图
图2-12所表示为调时模块波形仿真图。当key为低电平时,调时模块输出b脉冲;当key为高电平时,输出a脉冲。由此可知,本模块满足设计要求。
2.6闹钟模块设计
连接基础数字钟模块时、分、秒输出,和定时时间时、分输出,另一端连接动态显示模块,经过外部按键来选择基础时钟或是闹钟时间设定显示。定时控制模块有复位键、调时调分切换键、累加键,来设定闹钟时间。
2.6.1定时模块
图2-14所表示分别为定时模块符号图。输入端口reset是定时模块复位信号,也是整个打铃器使能信号,低电平有效; k1是闹钟时间设定时、分切换按键,高电平时对时进行调整,低电平时对分进行调整;up_key是调整闹钟时间累加按键,另一端接按键消抖模块,每按一次计数加一; Q_tmpma、Q_tmpmb、Q_tmpha、 Q_tmphb分别为闹钟时间分低位、分高位、时低位时高位。
图2-14定时模块符号图
图2-15所表示为定时模块波形仿真图。当复位键为高电平、k1为低电平时,每按下一次up_key闹钟分低位就计一个数,计到9时向高位进一,当计到59时重新从0开始计数;当复位键为高电平、k1为高电平时,开始对时计数,up_key每来一个脉冲时低位就计一个数,计到9时变为0,高位进位,计到23时重新计数,由波形仿真克制此模块满足设计要求。
图2-15 定时模块波形仿真图
2.6.2比较模块
图2-16所表示为比较模块设计框图。设计思绪为:将闹钟设定时间和立即模块时间分别比较,即时高位、时低位、分高位、分低位分别进行比较,若时间相等,则输出高电平,输出信号和1Hz时钟信号相和,取得信号接蜂鸣器,可实现时隔一秒报警一次,报警时长为一秒。
QMB[3..0]为时钟分高位,QM_A[3..0]为时钟分低位;HARM_B[3..0]为闹钟时间时高位,
HARM_A[3..0]为闹钟时间时低位,MARM_B[3..0]为闹钟时间分高位,MARM_A[3..0]为闹钟时间分低位;SPEAK为比较模块输出,接报警时长设定模块输入。
图2-17 比较模块符号图
图2-18所表示为比较模块波形仿真图。给clk0一定时钟,设定闹钟时间时高位为1,时低位为2,分高位、分低位全部为0,即闹钟时间为十二点整,;首先设定时钟模块时高位设定为1,时低位为1,分高位为5,分低位为9,即十一点五十九分,再设定为十二点整;由波形仿真图可知,当初钟时间由十一点五十九分变为十二点整时,speak输出时钟波形,可知比较模块设计满足要求。
2.7打铃模块设计
图2-19打铃模块设计框图
图2-19所表示为打铃模块设计框图。模块包含作息选择和时间比较部分,其设计思绪为:经过k3进行春夏作息时间选择,将时钟时高位、时低位、分高位、分低位分别于打铃时间数据进行比较,若相等,则Q_Y输出高电平,不然输出低电平。
图2-20打铃模块符号图
图2-20所表示为打铃模块符号图。K3为切换春夏作息时间按键,当K3为高电平时选择春季作息时间,方为低电平时选择夏季作息时间;Q_HB[3..0]接时钟时间时高位,Q_HA[3..0]接时钟时间时低位,Q_MB[3..0]接时钟时间分高位,Q_MA[3..0]接时钟时间时低位;Q_Y为打铃模块输出,
接报警模块输入。
图2-21打铃模块波形仿真图
图2-21所表示为打铃模块波形仿真图。能够看出:当K3为高电平时,选择春季作息时间,当初钟时间由八点二十九分跳变为八点三十分时,Q_Y由低电平变为高电平,此为春季作息时间早晨八点三十分;当K3为低电平时,选择夏季作息时间,当初钟时间由八点二十九分跳变为八点三十分时,Q_Y由低电平变为高电平,此为夏季作息时间早晨八点三十分;当K3为高电平时,选择春季作息时间,当初钟时间由十三点二十九分跳变为十三点三十分时,Q_Y由低电平变为高电平,此为春季作息时间下午十三点三十分;当K3为低电平时,
Q_Y由低电平变为高电平,此为夏季作息时间下午十四点整。
选择夏季作息时间,当初钟时间由十三点五十九分跳变为十四点整时,
2.8报警模块设计由此可知打铃模块满足设计要求。
报警模块关键包含报警时长设定模块和蜂鸣器发生模块,实现学校作息时间报时和闹钟报警功效。
2.8.1报警时长设定模块
图2-22所表示分别为报警时长设定模块符号图和RTL图。其中Reset为复位端,低电平有效;up_key为调整报警时间按键,时长可从一秒调至十五秒,连接按键模块;speaktime[3..0]为报警时长输出,连接蜂鸣器发生模块输入端。
图2-22 报警时长设定模块符号图
图2-23所表示为报警时长设定模块波形仿真图。复位按键reset设为高电平,给up_key一定脉冲时钟,没抵达一次脉冲上升沿,speaktime就加一,当计到15时重新从0开始,实现了报警时长在1至15秒内自由设定要求。
图2-23报警时长设定模块波形仿真图
2.8.2蜂鸣器发声模块
另外一个蜂鸣器用于闹钟报警。
本设计需用两个蜂鸣器,一个蜂鸣器用于学校作息时间报时,
speaktime[3..0]接报警时长设定模块输出,为报警连续时间长度,范围在一秒至十五秒以内;q_20s为蜂鸣器发声模块输出,接蜂鸣器负极。
图2-24蜂鸣器发声模块符号图
图2-25所表示为蜂鸣器发声模块波形仿真图。给clk接入一定脉冲, speaktime为一秒, 当Q_Y为高电平时,伴随时钟脉冲下一个周期到来,
q_20s由低电平变为高电平,高电平连续时间和时钟脉冲一个周期相等,实际测试时,时钟脉冲为1Hz秒信号,所以报警时长为1s;当设定speaktime为15秒时,q_20s伴随时钟脉冲下一个周期到来,由低电平变为高电平,连续时间和时钟脉冲15个周期相等,可实现15s报警时长。由此可知,蜂鸣器发生模块满足设计要求,可实现1-15秒自由调整。
图2-25蜂鸣器发声模块
2.9显示模块设计
时钟计时显示、闹钟时间设定、蜂鸣器报警时长设定,全部需要数码管来显示,对于本学校打铃器设计,必不可少就是显示模块设计,因为依据设计要求,
2.9.1时间切换模块实际应用时候,数码管显示是最直观表现。
图2-26所表示为时间切换模块设计框图。设计思绪为:经过K2来进行时间切换,当K2为高电平时,输出正常计时时间;当K2为低电平时,输出定时时间。
图2-26 时间切换模块设计框图
图2-27时间切换模块符号图
图2-27所表示为时间切换模块符号图。K2为切换按键输入,用于切换时间输出;
QSAI[3..0]为时钟时间秒低位,QSBI[3..0]为时钟时间秒高位,
QMAI[3..0]为时钟时间分低位,QMBI[3..0]为时钟时间分高位,
QHAI[3..0]为时钟时间时低位,QHBI[3..0]为时钟时间时高位;
QH_ARM_A[3..0]为定时时间时低位,QH_ARM_B[3..0]为定时时间时高位,QM_ARM_A[3..0]为定时时间分低位,QM_ARM_B[3..0]为定时时间分高位;Q_HAO[3..0]为时间切换模块时低位,Q_HBO[3..0]为时间切换模块时高位,Q_MAO[3..0]为时间切换模块分低位,Q_MBO[3..0]为时间切换模块分高位,Q_SAO[3..0]为时间切换模块秒低位,Q_SBO[3..0]为时间切换模块秒高位。
设定时钟时间为21点34分52秒,定时时间为12点整;当K2为高电平时,模块输出为时钟时间21点34分52秒;当K2为低电平时,模块输出为定时时间十二点整。由此可知,本模块满足设计要求。
2.9.2动态扫描模块
所谓动态显示就是一位一位地轮番点亮各位显示器(扫描),对于显示器每一位而言,每隔一段时间点亮一次。即使在同一时刻只有一位显示器在工作(点亮),但利用人眼视觉暂留效应和发光二极管熄灭时余辉效应,看到却是多个字符“同时”显示。显示器亮度既和点亮时导通电流相关,
控制各位LED显示器所显示字形也需要一个8位口(称为数据口或字形口)。调整电流和时间参烽,可实现亮度较高较稳定显示[11]。
7段数码管通常由8个发光二极管组成,其中由7个细长发光二极管组成数字显示,另外一个圆形发光二极管显示小数点。当发光二极管导通时,对应一个点或一个笔画发光。控制对应二极管导通,就能显示出多种字符,尽管显示字符形状有些失真,能显示数符数量也有限,但其控制简单,使有也方便。发光二极管阳极连在一起称为共阳极数码管,阴极连在一起称为共阴极数码管,本设计使用共阴数码管,图2-28所表示为七段共阴数码管结构图。
图2-28七段数码管结构
图 2-29所表 示 为 数 码 管 显 示 连 接 图 。
动态扫描电路将计数器输出8421BCD码转换为数码管需要逻辑状态,
而
所谓动态扫描显示方法是在显示某一位LED显示块数据时候,让其它位不显示,且输 出 数 码管 选 信 号 [12]。
然后
只要确保每一位显示时间间隔不要太大,利用人眼视觉暂留现象,
就能够造成各位数据同时显示假象[13]。通常每一位显示时间为1~10ms。
图2-29 数码管显示连接图
图 | 2-30所 | 表 | 示 | 为 | 动 | 态 | 扫 | 描 | 模 | 块 | 符 | 号 | 图 | 。 |
该模块输入端口clk是频率为5kHZ扫描时钟,故每一位显示时间为0.2ms,需要扫描8个数码管,故显示间隔为1.6ms。由分频模块提供,数码管显示时、分和秒,和报警时间。其它输入端口接计数模块输出数据;输出端口segout[7..0]动态输出扫描数据;端口selout[7..0]输出数码管片选信号。
分别输出时钟时间或定时时间,和报警时长, 有波形仿真图可知此模块满足设计要求。
图2-31 动态扫描模块波形仿真图
2.10按键电路设计
本设计需要对计时时间和闹钟时间进行调整,调整过程需要用到按键电路,用到两种按键,一个是机械式开关,另外一个是拨码开关。因为按键电路比较简单,在此关键介绍按键各自完成功效。本设计由8个独立按键组成,包含两个拨码开关,六个机械式开关。其中2个拨码开关分别用于调整报警时长和闹钟定时时间调整;另外6个机械式开关分别用于复位,数码管显示切换,闹钟定时时、分切换,作息时间切换,时钟时间时、分调整。
第三章试验结果分析
3.1测试过程
将设计程序下载到试验箱上进行实际测试,以下为实际测试过程:
闹钟显示切换按键为高电平时显示时钟时间,可经过时钟调时、 目前状态为正常计时状态,将复位按键设为高电平,计时开始, 时钟、
显示时间为十二点十九分十八秒,报警时长为十五秒。
为闹钟设定时间显示,经过时钟、闹钟显示切换按键来进行切换,当为低电平时显示闹钟时间,可经过定时调时调分切换按键来选择调整时或分,按下闹钟时间调整拨码开关进行闹钟时间设定,图中数码管显示从左到右依次为:报警时长高位、低位,定时时间时高位、时低位,分高位、分地位,秒高位、秒低位,目前显示闹钟设定时间为十二点十三分,报警时长为五秒,当初钟时间为十二点十三分时,蜂鸣器报警,时长为五秒。
测试说明,最终止果和预期效果基础一致,时、分、秒能够正常计数并可调整时间,学校上下课时间打铃功效正常,而且能够经过按键调整作息时间和报警时长。
自动打铃器设计关键在于按键控制和各个模块代码编写, 即使能把键盘接口和各个模块代码编写出来,并能正常显示,
但对于各个模块优化设计还有一定缺点和不足。总来说,经过这次设计试验更深入地增强了试验动手能力,对打铃器工作原理也有了愈加透彻了解。在本设计调试过程中碰到了部分难点问题,经过努力加以处理:
1、当程序下载到试验箱上后,数码管显示全部为零,计数器不工作,经分析得悉程序中总清零信号保持有效状态,改动程序后计数器开始计数。
2、当秒时钟计数到59时变0时,分计数模块滞后计数,考虑器件延时,将程序中秒进位信号提前1秒。
3、在对学校打零时间设置及更改问题上,一开始想经过ROM实现,但思索以后还是采取了经过程序实现方法,因为ROM只能读不能写。
4、在检测按键时,因为有些按键控制是秒时钟同时,所以控制起来显得稍微慢些,不过工作正常,能满足实际需要。
3.2结果分析
本设计是采取硬件描述语言和FPGA芯片相结合进行学校打铃器研究,
轻易修改。 本设计中仍存在一定不足,用来控制学校打铃器按键为八个,数量较多, 在实际应用中会带来不便,以后能够考虑深入优化, 如,可经过加入位选控制按键来实现节省按键资源,一键多用, 便能够降低按键,实现一样控制功效。
另外,在本设计基础上还能够进行一系列创新,比如增加音乐报警功效,替换稍有刺耳蜂鸣声,会使用户在实际应用中多一份乐趣,还能够加入遥控功效、语音识别等等,相信伴随电子技术发展,打铃器功效会愈加多样化,满足大家多种需要,为大家以后工作和生活提供更多方便。
第四章小结和体会
经过课外学分设计,过程曲折可谓一语难尽。在此期间我也失落过,也曾一度热情高涨。从开始时激情高涨到最终汗水背后复杂心情,点点滴滴无不令我回味无长。
经过这次课外学分设计,加强了我动手、思索和处理问题能力。考验了我耐心和直面挫折精神。我深知以后要走路将会更长更曲折,不过不要紧, 我有信心和毅力走下去,摔倒了再爬起来, 没有什么,因为我们年轻, 我们有激情和热血。我会用百折不挠决心,去越过每一道沟沟坎坎。 对我而言,知识上收获关键,精神上丰收愈加可喜。挫折是一份财富,
参考文件
[1] 刘皖, 何道君,谭明编著.FPGA设计和应用[M].北京:清华大学出版社, .6: 12-16
[2] 廖日坤.CPLD/FPGA嵌入式应用开发技术白金手册[M].北京:中国电力出版社, : 212-218[3] J.Bhasker著, 徐振林等译.VerilogHDL硬件描述语言[M].北京:机械工业出版社, : 36-42
[4] 侯伯亨,顾新.VHDL硬件描述语言和数字电路逻辑设计[M].西安:西安电子科技大学出版社,: 12-16 [5] 高吉祥.电子技术基础试验和课程设计[M].北京:电子工业出版社, : 67-73
[6] 李国洪,沈明山.可编程器件EDA技术和实践[M].北京:机械工业出版社, : 56-57
[7] 张庆双.电子元器件选择和检测[M].北京:机械工业出版社,: 23-25
[8] 李婷.基于FPGA按键弹跳消除模块研究和应用[J].科技创新导报,, (2):82-83
[9] 邢远秀,陈姚节.键盘消抖电路研究和分析[J].中国科技信息,, (1):20-22
[10] 王开军,姜宇柏.面向CPLD/FPGAVHDL设计[M].北京:机械工业出版社,: 28-65
[11] 刘君,常明,秦娟.基于硬件描述语言(VHDL)数字时钟设计[J].天津理工大学学报,, 23(4): 40- 41
[12] 谭会生,张昌凡.EDA技术及应用[M].西安:西安电子科技大学出版社,: 89-92
[13] 李可.数字钟电路及应用[M].北京:电子工业出版社,1996: 72-76
附录
一、程序清单 | co:out std_logic); |
use ieee.std_logic_1164.all; entity fenpin25k is
port( clk :in std_logic;
signal cqi : integer range 1 to 25000;
begin
co<='1'when cqi=25000 and clk='0'else '0';
process (clk) is
begin useieee.std_logic_1164.all;
ifclk'event and clk='1'then entitycnt200 is
if cqi=25000 then port( clk :in std_logic;
cqi<=1; co:out std_logic);
elsecqi<=cqi+1; endentity;
endif; Architectureart of cnt200 is
endif; signalcqi : integer range 1 to 200;
endprocess; begin
endarchitecture art; co<='1'when cqi=200 and clk='0'else '0';
(2)libraryieee; process(clk) is
useieee.std_logic_1164.all; begin
entitycnt5 is ifclk'event and clk='1'then
port(clk :in std_logic; if cqi=200 then
end entity; co:out std_logic);
Architectureart of cnt5 is end if;
signalcqi : integer range 1 to 5;
begin
co<='1'when cqi=5 and clk='0'else '0'; end architecture art;
process(clk) is (4)libraryieee;
begin useieee.std_logic_1164.all;
ifclk'event and clk='1'then entitycnt50e is
if cqi=5 then port( clk :in std_logic;
cqi<=1; co:out std_logic);
elsecqi<=cqi+1; endentity;
endif; Architectureart of cnt50e is
endif; signalcqi : integer range 1 to 50e3;
endprocess; begin
end architecture art;
co<='1' when cqi=50e3 and clk='0'else '0';
(3)library ieee; | process (clk) is |
|
begin libraryieee;
ifclk'event and clk='1'then useieee.std_logic_1164.all;
if cqi=50e3 then entityDcfq is
cqi<=1; port(d,clk:instd_logic;
elsecqi<=cqi+1; q:outstd_logic);
endif; endentity Dcfq;
endif; architectureart of Dcfq is
endprocess; begin
endarchitecture art; process(clk)is
(5)libraryieee; begin
useieee.std_logic_1164.all; if(clk'eventand clk='1') then
entitycnt250 is q<=d;
port(clk :in std_logic; endif;
end entity; co:out std_logic);
Architectureart of cnt250 is 3.时钟模块
signalcqi : integer range 1 to 250;
begin
co<='1'when cqi=250 and clk='0'else '0'; useieee.std_logic_1164.all;
process(clk) is useieee.std_logic_unsigned.all;
begin entitySECOND is
ifclk'event and clk='1'then port(cp,clr:instd_logic;
if cqi=250 then sqmsl,sqmsh:out std_logic_vector(3
cqi<=1; downto0);
elsecqi<=cqi+1; co:out std_logic);
endif; endSECOND;
endif; architectureSEC of SECOND is
endprocess; begin
end architecture art; process(cp,clr)
2.消抖模块 variable cnt1,cnt0:std_logic_vector(3
downto 0); | port(clk,clr:in std_logic; | std_logic_vector(3 |
begin | co:out std_logic; | |
if clr='0' then | min1,min0:out | |
cnt1:="0000"; | downto 0) | |
cnt0:="0000"; | ); | |
elsif cp'event and cp='1' then | end MINUTE; |
ifcnt1="0101" and cnt0="1000" then
co<='1'; architectureMIN of MINUTE is
cnt0:="1001"; begin
elsifcnt0<"1001" then process(clk,clr)
cnt0:=cnt0+1; variable cnt1,cnt0:std_logic_vector(3
else downto0);
cnt0:="0000"; begin
ifcnt1<"0101" then ifclk'event and clk='1' then
cnt1:=cnt1+1;
else if cnt1="0101" and cnt0="1000" then
co<='0';
end if; elsif cnt0<"1001" then
cnt1:="0000";
endif; cnt0:=cnt0+1;
endif; else
sqmsh<=cnt1; cnt0:="0000";
sqmsl<=cnt0; ifcnt1<"0101" then
endprocess; cnt1:=cnt1+1;
endSEC; else
cnt1:="0000";
(2)分计数模块
co<='0';
libraryieee;
endif;
useieee.std_logic_1164.all;
endif;
use ieee.std_logic_unsigned.all;
endif;
entityMINUTE is
end if;
min1<=cnt1; endif;
min0<=cnt0; endif;
endprocess; endif;
endMIN; endprocess;
(3)时计数模块 endbhv;
libraryieee; (4)调时模块
useieee.std_logic_1164.all; libraryieee;
useieee.std_logic_unsigned.all; useieee.std_logic_1164.all;
entitysh24 is useieee.std_logic_unsigned.all;
port(clk:instd_logic; useieee.std_logic_arith.all;
clr:instd_logic; entitymux2to1 is
sh:bufferstd_logic_vector(3 downto 0); port(
sl:bufferstd_logic_vector(3 downto 0)); key:in std_logic;
architecture bhv of sh24 is c: out std_logic end sh24; a,b: instd_logic;
begin
process(clk,clr)
begin
if (clr='0')then architecture one of mux2to1 is
sh<="0000"; begin
sl<="0000"; process(key)
elsif(clk'eventand clk='1') then begin
if(sh="0010"andsl="0011")then ifkey='0'then
sh<="0000";sl<="0000"; c<=b;
elsesl<=sl+1; else
if(sl<9)thensl<=sl+1; c<=a;
elsesl<="0000"; endif;
if(sh<2)thensh<=sh+1; endprocess;
else sh<="0000"; end one;
endif; 4.闹钟模块
(1)定时模块 THEN
LIBRARYieee; IF k1='1' THEN
USE ieee.std_logic_1164.all; ENTITY ctrl_memo IS
IF Q_tmphb=2 AND Q_tmpha=3 THEN Q_tmphb:=0; Q_tmpha:=0 ;
PORT( reset,k1,up_key: IN STD_LOGIC; | ELSIF | Q_tmpha=9 | THEN |
--k1高电平为调时, 低电平为调分
Q_hourb: OUT INTEGER RANGE 0
Q_tmpha:=0; Q_tmphb:=Q_tmphb+1; ELSE Q_tmpha:=Q_tmpha+1;
END IF;
TO 9;--“时”高位
else
Q_houra : OUT INTEGER RANGE 0
IF Q_tmpmb=5 AND Q_tmpma=9
TO 9;--“时”低位
THEN Q_tmpmb:=0; Q_tmpma:=0 ;
Q_minueb:OUT INTEGER RANGE 0
ELSIF Q_tmpma=9 THEN
TO 9;
Q_tmpma:=0; Q_tmpmb:=Q_tmpmb+1;
Q_minuea:OUT INTEGER RANGE 0
END ctrl_memo; END IF;
ELSE Q_tmpma:=Q_tmpma+1;
TO 9);
END IF;
BEGIN
PROCESS(reset,k1,up_key) ARCHITECTURE a OF ctrl_memo IS
Q_houra<=Q_tmpha;
VARIABLE Q_tmpma: INTEGER
Q_minueb<=Q_tmpmb;
RANGE 0 TO 9;
Q_minuea<=Q_tmpma;
VARIABLE Q_tmpmb: INTEGER
END PROCESS ;
RANGE 0 TO 9;
END a;
VARIABLE Q_tmpha: INTEGER
(2)比较模块
RANGE 0 TO 9;
LIBRARY ieee;
VARIABLE Q_tmphb: INTEGER
USE ieee.std_logic_1164.all;
RANGE 0 TO 9;
ENTITY BIJIAOQI IS
BEGIN
IF reset='0' THEN Q_tmpma:= 0; Q_tmpmb:= 0;Q_tmpha:= 0; Q_tmphb:= 0;
PORT( CLk0: IN STD_LOGIC;
QH_A,QM_A:IN INTEGER RANGE 0
ELSIF up_key'event AND up_key='1' | TO 9; |
|
QH_B:IN INTEGER RANGE 0 TO 9; QM_B:IN INTEGER RANGE 0 TO 9;
ENDCOMP_TIME;
ARCHITECTUREa OF COMP_TIME IS
HARM_A,MARM_A: IN INTEGER SIGNAL
RANGE 0 TO 9; QTIME:STD_LOGIC_VECTOR(15
HARM_B: IN INTEGER RANGE 0 TO 9; DOWNTO 0);
MARM_B: IN INTEGER RANGE 0 TO 9; BEGIN
SPEAK: OUT STD_LOGIC); QTIME<=Q_HB & Q_HA & Q_MB &
END BIJIAOQI; Q_MA;
PROCESS(QTIME)
ARCHITECTURE a OF BIJIAOQI IS BEGIN
SIGNAL Y: STD_LOGIC; IF K3='1' THEN
BEGIN CASE QTIME IS
SPEAK<=CLK0 AND Y; WHEN "0000" => Q_Y<='1';WHEN
Y<='1' WHEN (QH_A=HARM_A)
AND
(QH_B=HARM_B) (QM_A=MARM_A)
"0101" => Q_Y<='1';
WHEN "0101" => Q_Y<='1';WHEN
END a;
5.打铃模块
WHEN "0000" => Q_Y<='1';WHEN (QM_B=MARM_B) ELSE '0';
LIBRARY ieee; "0000" => Q_Y<='1';
USE ieee.std_logic_1164.all; ENTITY COMP_TIME IS
PORT( K3: IN STD_LOGIC;
WHEN "0000" => Q_Y<='1';WHEN "0000" =>Q_Y<='1';
WHEN "0101" => Q_Y<='1';WHEN
Q_HA,Q_MA: IN "0101" => Q_Y<='1';
STD_LOGIC_VECTOR(3 DOWNTO 0); WHEN "0101" => Q_Y<='1';WHEN
Q_HB: IN "0000" => Q_Y<='1';
STD_LOGIC_VECTOR(3 DOWNTO 0); WHEN "0000" => Q_Y<='1';WHEN
Q_MB: IN "0101" => Q_Y<='1';
STD_LOGIC_VECTOR(3 DOWNTO 0); Q_Y: OUT STD_LOGIC);
WHEN "0000" => Q_Y<='1';WHEN
"0101"=> Q_Y<='1';
WHEN "0101" => Q_Y<='1';WHEN "0000" => Q_Y<='1';
WHEN "0101" => Q_Y<='1';WHEN
"0000"=> Q_Y<='1';
WHEN "0000" => Q_Y<='1'; WHEN OTHERS=>Q_Y<='0';
"0000" => Q_Y<='1'; END CASE;
WHEN "0000" => Q_Y<='1'; WHEN END IF;
OTHERS=> Q_Y<='0'; END PROCESS;
END CASE; END a;
ELSE 6.报警模块
CASE QTIME IS (1)报警时长设定模块
WHEN "0000" => Q_Y<='1';WHEN LIBRARY ieee;
"0000" => Q_Y<='1';
WHEN "0101" => Q_Y<='1';WHEN "0101" => Q_Y<='1';
USEieee.std_logic_1164.all;
ENTITYctrl_s IS
PORT(reset,up_key: IN STD_LOGIC; --
"0101" => Q_Y<='1'; speaktime: out INTEGER RANGE 0 WHEN "0101" => Q_Y<='1';WHEN
k1高电平为调时, 低电平为调分
WHEN "0000" => Q_Y<='1';WHEN
"0000" => Q_Y<='1';
"0000" => Q_Y<='1';
begin
WHEN "0101" => Q_Y<='1';WHEN
"0101" => Q_Y<='1';
WHEN "0101" => Q_Y<='1';WHEN
PROCESS(reset,up_key)
variableQ_tmpma: INTEGER RANGE 0
"0000" => Q_Y<='1'; | TO 15; |
"0101" => Q_Y<='1';
WHEN "0000" => Q_Y<='1';WHEN
IFreset='0' THEN Q_tmpma:=0;
ELSIF up_key'event AND up_key='1'
"0101" => Q_Y<='1'; | THEN |
WHEN "0101" => Q_Y<='1';WHEN "0000" => Q_Y<='1';
WHEN "0101" => Q_Y<='1';WHEN
IF Q_tmpma<15THEN
Q_tmpma:=Q_tmpma+1;
ELSe Q_tmpma:=0;
ENDIF ; ENDa;
ENDIF ; 7.显示模块
speaktime<=Q_tmpma; (1)时间切换模块
ENDPROCESS ; LIBRARYieee;
ENDa; USEieee.std_logic_1164.all;
(2)蜂鸣器发声模块 ENTITYNOR_ARM_CTL IS
LIBRARYieee; PORT(
USEieee.std_logic_1164.all; k2:IN STD_LOGIC;
ENTITYs20 IS QSAI,QMAI,QHAI:ININTEGER RANGE
PORT(QY,CLK: IN STD_LOGIC; 0TO 9;
speaktime : in INTEGER RANGE 0 QSBI,QMBI:ININTEGER RANGE 0 TO
TO15; 9;
q_20s: out STD_LOGIC); QHBI:ININTEGER RANGE 0 TO 9;
ARCHITECTURE a OF s20 IS
END s20; QH_ARM_A,QM_ARM_A: ININTEGER
BEGIN
PROCESS(CLK)
0TO 64; TO9;
BEGIN Q_HAO,Q_MAO,Q_SAO:OUTINTEGER
IFCLK'event AND CLK='1' THEN RANGE0 TO 9;
IFQY='1' THEN Q_HBO:OUT INTEGER RANGE 0 TO 9;
IF tmp<=speaktimeTHEN Q_MBO,Q_SBO:OUT INTEGER RANGE
tmp:=tmp+1;Q_20S<='1'; 0TO 9);
ELSE tmp:=tmp+1;Q_20S<='0'; ENDNOR_ARM_CTL;
ENDIF; ARCHITECTUREa OF NOR_ARM_CTL
ELSE tmp:=0;Q_20S<='0'; IS
END IF;
END IF ;
BEGIN
Q_HAO<=QHAI WHEN K2='1' ELSE
END PROCESS ; | QH_ARM_A; |
|
Q_HBO<=QHBI WHEN K2='1' ELSE signaltemp:std_logic_vector(2 downto 0);
QH_ARM_B; signalseg:std_logic_vector(7 downto 0);
Q_MAO<=QMAI WHEN K2='1' ELSE QM_ARM_A;
signalsel:std_logic_vector(7 downto 0);
Q_MBO<=QMBI WHEN K2='1' ELSE begin
QM_ARM_B; process(clk)
Q_SAO<=QSAI WHEN K2='1' ELSE variable num:std_logic_vector(3 0;
downto 0); Q_SBO<=QSBI WHEN K2='1' ELSE begin
0; if (clk'event and clk='1' ) then
END a; if temp>=7 then
temp<="000";
(2)动态扫描模块
else
library ieee;
temp<=temp+1;
use ieee.std_logic_unsigned.all; use ieee.std_logic_1164.all;
entity dongtaism2 is
port(clk:in std_logic; sel<="01111111";
std_logic_vector(3 downto 0);
sh:in std_logic_vector(3 downto 0);
when"110" =>num:=speaktimel(3 downto
fl:in std_logic_vector(3 downto 0); fh:in std_logic_vector(3 downto 0); | 0); |
ml:in std_logic_vector(3 downto 0);
when"101" =>num:=sh(3 downto 0);
mh:in std_logic_vector(3 downto 0); | sel<="11011111"; |
selout:out std_logic_vector(7 downto
when"100" =>num:=sl(3 downto 0);
0); | sel<="11101111"; |
segout:out std_logic_vector(7 downto
when"011" =>num:=fh(3 downto 0);
0)); | sel<="11110111"; |
end dongtaism2;
architecture a of dongtaism2 is
when "010" =>num:=fl(3 downto 0);
sel<="11111011";
when "001" =>num:=mh(3 downto 0);
sel<="11111101";
when"000" =>num:=ml(3 downto 0);
sel<="11111110";
whenothers=>sel<="11111111";
endcase;
casenum is
when"0000"=>seg<="00111111";
when"0001"=>seg<="00000110";
when"0010"=>seg<="01011011";
when"0011"=>seg<="01001111";
when"0100"=>seg<="01100110";
when"0110"=>seg<="01111101";when"0101"=>seg<="01101101";
when"0111"=>seg<="00000111";
when"1001"=>seg<="01101111"; when"1000"=>seg<="01111111";
whenothers=>seg<="00000000";
end case;
end if;
endprocess;
selout<=sel;
segout<=seg;
endarchitecture;
二、学校打铃器顶层原理图
自动打铃器顶层原理图