基于vhdl多功能电子钟设计说明书.doc_第1页
基于vhdl多功能电子钟设计说明书.doc_第2页
基于vhdl多功能电子钟设计说明书.doc_第3页
基于vhdl多功能电子钟设计说明书.doc_第4页
基于vhdl多功能电子钟设计说明书.doc_第5页
已阅读5页,还剩51页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

数字系统课程设计报告课程设计题目:基于vhdl语言的电子钟组员:陈洪彬,麦俊辉,缪超课程设计要求:设计一个用4位数码管显示的电子钟,包括整点报时,闹钟功能,4按键输入采用 VHDL 语言描述系统功能,并在 QUARTUS II 工具软件中进行仿真,下载到 EDA 实验板进行验证。编写设计报告,要求包括方案选择、程序代码清单、调试过程、测试结果及心得体会。一、软硬件资源分析实验室提供了Altera公司的cyclone系列EP1C6Q240C8实验开发板,该开发板提供了四个自由按键,八个发光LED,蜂鸣器,四个七段数码管,四位拨码开关等等硬件资源。我们所设计的数字钟用到了四个自由按键用于对显示的选择,对设置时间的选择,还有用于用于设置时间时的加一操作,四个七段数码管用于显示,蜂鸣器用于整点报时和闹钟,还有四个发光LED用于判断自由按键的通断。以下列表对数字钟中用到的硬件资源进行说明:硬件名称程序中的标识符开发板中的标号对应芯片中管脚数功能操作方式备注EP1C6Q240C8-Alter公司Cyclone系列发光LEDLed1LED0P_113Key1in按下时点亮-指示作用发光LEDLed2LED1P_114Key2in按下时点亮-指示作用 发光LEDLed3LED2P_115Key3in按下时点亮-指示作用发光LEDLed4LED3P_116Key4in按下时点亮-指示作用蜂鸣器SpeakbeepP_124当低电平时发声当低电平时发声指示作用自由按键Key1inKey0P_125确定工作状态(见下表)长按一下 脉冲来时改变,消抖自由按键Key2inKey1P_126确定工作状态(见下表)长按一下 脉冲来时改变,消抖自由按键Key3inKey2P_127确定工作状态(见下表)长按一下 脉冲来时改变,消抖自由按键Key4inKey3P_128修改时间时加一,停止闹钟长按一下脉冲来时改变,消抖七段数码管dout,selout7LED1_C1C3P_168P_169P_170P_173显示正常时间及修改状态动态扫描法实现显示四个数码管全用总体设计框图:操作说明: 按键状态Key4outKey3outKey2outKey1out实现功能上升沿100修改小时(时钟)上升沿110修改分钟(时钟)上升沿101修改小时(闹钟)上升沿111修改分钟(闹钟)X(0或1)010显示时分(时钟)x000显示分秒(时钟)x001显示时分(闹钟)x011显示分(闹钟)注:1.key3的1表示修改,0表示显示;Key1的1表示闹钟,0表示时钟;Key2则是时-分切换 或者 时分-分秒 切换。各模块介绍(1) 分频器 在数字钟的设计中,采用了芯片内部提供的 50MHz 全局时钟,将其分频率后产生一个接近 1Hz 秒时钟 clk1,一个 2Hz 左右的闪烁时钟clk2,一个显示模块800Hz的clk3,一个用于消抖模块的20000Hz的clk4。clk1作用是:每秒产生一个脉冲,触发“秒”的累加。clk2作用是:在修改状态下通过判断clk2的电平值来决定数码管的亮灭。clk3作用是:作为扫描频率刷新数码管的示数。具体做法是令clk不断产生50MHz的方波,同时clk作为累加器的触发源。当累加器累计到一定数目时,使clk1,clk2,clk3,clk4的电平发生跳转,从而输出不同频率的方波。设计要点:例如要产生20000Hz,即周期50us。50,000,000/20000=2500,即使50MHz的晶振频率作为累加触发源,累计到1250个方波则使clk4状态反转。程序:LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;ENTITY distribu1 ISPORT(clk:IN STD_LOGIC;-晶振时钟clk1: BUFFER STD_LOGIC; -1Hz,用于秒的增加clk2: BUFFER STD_LOGIC;-2Hz,用于修改时间的闪烁clk3: BUFFER STD_LOGIC;-800Hz,显示模块的扫描时钟clk4: BUFFER STD_LOGIC);-20000Hz消除抖动的扫描时钟END ENTITY distribu1;ARCHITECTURE one OF distribu1 ISBEGIN dividefreq1Hz:PROCESS(clk) -1HzVARIABLE z1: integer range 0 to 25000000; BEGINIF(clkevent AND clk=1)THEN z1:=z1+1; if z1=25000000 then z1:=0; clk1= not clk1; -25,000,000 END IF;END IF;END PROCESS dividefreq1Hz; dividefreq2Hz:PROCESS(clk) -2HzVARIABLE z2: integer range 0 to 12500000; BEGINIF(clkevent AND clk=1)THEN z2:=z2+1; if z2=12500000 then z2:=0; clk2= not clk2; END IF;END IF;END PROCESS dividefreq2Hz; dividefreq800Hz:PROCESS(clk) -800HzVARIABLE z3: integer range 0 to 31250; BEGINIF(clkevent AND clk=1)THEN z3:=z3+1; if z3=31250 then z3:=0; clk3= not clk3; END IF;END IF;END PROCESS dividefreq800Hz; dividefreq02MS:PROCESS(clk) -0.05ms,20000HzVARIABLE z4 : integer range 0 to 1250; BEGIN IF(clkevent AND clk=1)THEN z4:=z4+1; if z4=1250 then z4:=0; clk4= not clk4; END IF; END IF; END PROCESS dividefreq02mS;END one;仿真:由于信号频率相差较大,所以仿真结果以clk4为代表,另外几个信号没有显示得出来:(2) 消除抖动模块 该数字钟将用到 4个自由按键,故程序只对这四个开关进行去抖。去抖原理如下:机械开关在按下时都会一定的抖动,对应信号线电平的变化有一个不稳定期,在读取按键状态时必须避开这个不稳定期,以免造成误判。本文采用了这延迟算法进行去抖。利用频率较高的时钟(本文采用了扫描时钟 clk)反复读取按键状态,并利用一个寄存器来记录当前状态出现的次数,如果当前状态与前一次读取的状态不一样,则将计数寄存器清零;如果当前状态与前一次读取的状态一致,刚计数寄存器加 1。当计数寄存器达到一定值 N 时便认为按键已按下并产生了一个电平改变。设计要点:虽然我们采用4位自由开关,实际上其中key1,key2,和key3充当拨码开关的功能,而key4实现按键功能拨码开关与自由按键的处理是不同的,因为拨码开关是有两个稳定状态的,即可任意长时间处于0或1态,而自由按键只有一个稳态,例如在实验板上,未进行操作时自由按键的输出默认是高电平,如果按一下,变为低电平,操作者一旦松手,按键输出自动恢复为高电平。因此在处理时,让自由按键一次按便输出一个脉冲(相当于进行了两次电平转换,而不是一次)。程序:LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY debounce2 ISPORT(clk4: IN STD_LOGIC; -消除抖动的扫描时钟key1in:IN STD_LOGIC;-按键的输入key1out:BUFFER STD_LOGIC;-按键的输出key2in:IN STD_LOGIC;key2out:BUFFER STD_LOGIC;key3in:IN STD_LOGIC;key3out:BUFFER STD_LOGIC;key4in:IN STD_LOGIC;key4out:BUFFER STD_LOGIC);END debounce2 ;ARCHITECTURE behave OF debounce2 ISBEGINpkey1:PROCESS(clk4,key1out)VARIABLE count1 : integer range 0 to 100; -处理抖动的时为0.2msX100=20ms BEGINif key1in=0 then IF(clk4EVENT AND clk4 = 1) THEN if count1=100 then count1:=count1;-20ms后结束处理 else count1:=count1+1; end if; if count1=99 then key1out= not key1out; -延时到后状态反转 else key1out=key1out; end if; end if;else count1:=0; end if; END PROCESS pkey1;pkey2:PROCESS(clk4,key2out)VARIABLE count2 : integer range 0 to 100; BEGINif key2in=0 then IF(clk4EVENT AND clk4 = 1) THEN if count2=100 then count2:=count2; else count2:=count2+1; end if; if count2=99 then key2out= not key2out; else key2out=key2out; end if; end if;else count2:=0;end if;END PROCESS pkey2;pkey3:PROCESS(clk4,key3out)VARIABLE count3 : integer range 0 to 100; beginif key3in=0 then IF(clk4EVENT AND clk4 = 1) THEN if count3=100 then count3:=count3; else count3:=count3+1; end if; if count3=99 then key3out=not key3out; else key3out=key3out; end if; end if;else count3:=0;end if;END PROCESS pkey3; pkey4:PROCESS(clk4,key4out) -Key4out不同以上处理VARIABLE count4 : integer range 0 to 100; BEGINif key4in=0 then IF(clk4EVENT AND clk4 = 1) THEN if count4=100 then count4:=count4; else count4:=count4+1; end if; if count4=99 then key4out= 1;-延时20ms后给key4out 一个上升沿 else key4out=0;-其余时间key4out都为0 end if; end if;else count4:=0;end if;END PROCESS pkey4;END behave; 我们在仿真时,由于消抖时时钟周期要求过大,我们对消抖时间对应的时钟周期进行改动,将其改小,从而从仿真中可以看出消抖的效果,我们设消抖的延迟时间为八个时钟周期,则仿真结果如下:从图中看出,已经实现消抖。(3)时间设置模块: 主要分为手动增值和自动增值两个进程。当key4按下,且key3out=1时进入手动增值模式。Key2和key1在不同状态对应不同的情况,分别是时钟小时,时钟分钟,闹钟小时,闹钟分钟。自动增值和手动增值都要在更新了要加的值之后才进行上述的增值。由于更新的需要,要把输出端的“a”和“b”互相传输,所以设置了一组“ain”和“bin”来过渡,且VHDL不能把输出口值赋给输入口,所以在原理图上强制把输出口连接到输入口。小时部分:将小时分成两位分别设置,当小时十位为0010,个位是0011,即为23点的时候,再加一就将十位个位都设置为0000。而其他情况中,小时将加从0000到0010(2)循环运行。而小时个位为从0000到1001(即为9)循环运行。当分钟部分,十位为0101,而个位为1001(即59分)再加一时,小时个位加一;当小时个位从1001(9)加一时,小时十位加一。时间设置时,选定设置位,key4in按下时,选定位加一。分钟部分:分钟部分也分为十位及个位分别设置,当小时为十位0101而个位是1001(即59分)时,再加一就将十位和个位都清零。而其他情况,十位按照0000到0101(0到5)循环,个位从0000到1001(0到9)循环。当秒钟部分,十位为0101,而个位为1001(即59秒)再加一时,分钟个位加一;当分钟个位从1001(9)加一时,分钟十位加一。时间设置时,选定设置位,key4in按下时,选定位加一。秒钟部分:跟分钟一样,秒钟部分也分为十位及个位分别设置,当十位0101而个位是1001(即59分)时,再加一就将十位和个位都清零。而其他情况,十位按照0000到0101循环,个位从0000到1001(0到9)循环。其正常时间工作时个位在1HZ脉冲上升沿来到时加一。时间设置时,选定设置位,key4in按下时,选定位加一。闹钟时间设置:本模块分4个进程,分别对闹钟时间的小时十位,小时个位,分钟十位,分钟个位进行检测,每个进程均以芯片的晶振50MHz进行触发。对分钟个位,来一个时钟的上升沿,检测按键输出状态,当key1out=1 and key2out=0 and key3out=1 时 每输入一个key4in信号脉冲使得key4out来上升沿则闹钟设置的分钟个位加1,当个位加到9,再加一次则复位为0;下一个进程检测分钟十位,每来一个时钟上升沿,在对应的按键状态下,当个位为9时,再来一个key4out上升沿脉冲则分钟十位加1,当加到十位为5,个位为9,则再加一次就复位为0。同样原理设计闹钟小时部分。自动增值则是由每一个1Hz的clk上升沿触发,每秒加一次。程序如下:library ieee;use ieee.std_logic_1164.all;use IEEE.STD_LOGIC_ARITH.ALL;use ieee.std_logic_unsigned.all;entity shijian2 isport( clk:in std_logic;key1out:in std_logic; -按键状态key2out:in std_logic;key3out:in std_logic;key4out:in std_logic; hou1a:buffer std_logic_vector(3 downto 0); - 手动修改后的时间数据hou2a:buffer std_logic_vector(3 downto 0);min1a:buffer std_logic_vector(3 downto 0);min2a:buffer std_logic_vector(3 downto 0);seth1a: buffer std_logic_vector(3 downto 0); -手动修改后或没有修改的闹钟数据seth2a: buffer std_logic_vector(3 downto 0);setm1a: buffer std_logic_vector(3 downto 0);setm2a: buffer std_logic_vector(3 downto 0);hou1b:buffer std_logic_vector(3 downto 0); -每1秒自动加1的时钟数据hou2b:buffer std_logic_vector(3 downto 0);min1b:buffer std_logic_vector(3 downto 0);min2b:buffer std_logic_vector(3 downto 0);sec1b:buffer std_logic_vector(3 downto 0);sec2b:buffer std_logic_vector(3 downto 0); hou1ain:in std_logic_vector(3 downto 0); -若之前为手动修改时间模式的数据,hou2ain:in std_logic_vector(3 downto 0); -要把修改后的时钟数据赋值给“b”代表显示模式的数据(即刷新)min1ain:in std_logic_vector(3 downto 0);min2ain:in std_logic_vector(3 downto 0);hou1bin:in std_logic_vector(3 downto 0); -用于更新a的值hou2bin:in std_logic_vector(3 downto 0);min1bin:in std_logic_vector(3 downto 0);min2bin:in std_logic_vector(3 downto 0) );end entity shijian2;architecture one of shijian2 is begin-hou1ain=hou1a;-已在电路图上连线-hou2ain=hou2a;-min1ain=min1a;-min2ain=min2a;-hou1bin=hou1b;-hou2bin=hou2b;-min1bin=min1b;-min2bin=min2b;shoudong:process(key1out,key2out,key3out,key4out) -手动修改 beginif key3out=0 then hou1a=hou1bin; -更新a的值 hou2a=hou2bin; min1a=min1bin; min2a=min2bin; elsif(key4outevent and key4out=1) then if(key3out=1AND key2out=0 AND key1out=0)then -校时钟小时位,手动加1脉冲 if hou2a=0011 and hou1a=0010 then -检查进位,“a代表手动修改模式的数据 hou2a=0000; hou1a=0000; elsif hou2a=1001 then hou1a=hou1a+1; hou2a=0000; else hou2a=hou2a+1; end if; elsif (key3out=1AND key2out=1 AND key1out=0)then-校时钟分钟位,手动加1脉冲 if min2a=1001 and min1a=0101 then -检查进位 min2a=0000; min1a=0000; elsif min2a=1001 then min2a=0000; min1a=min1a+1; else min2a=min2a+1; end if; elsif (key3out=1AND key2out=0 AND key1out=1)then -校闹钟小时位,手动加1脉冲 if seth2a=0011 and seth1a=0010 then -检查进位 seth2a=0000; seth1a=0000; elsif seth2a=1001 then seth1a=seth1a+1; seth2a=0000; else seth2a=seth2a+1; end if; elsif (key3out=1AND key2out=1 AND key1out=1)then -校闹钟分钟位,手动加1脉冲 if setm2a=1001 and setm1a=0101 then -检查进位 setm2a=0000; setm1a=0000; elsif setm2a=1001 then setm2a=0000; setm1a=setm1a+1; else setm2a=setm2a+1; end if; end if; end if;end process;zidong:process(key1out,key3out,key4out,clk) -每1秒自动加1begin if( key3out=1 and key1out=0) then -若之前为手动修改时间模式,要把修改后的时钟数据赋给“b”(即刷新) -key3out的“1”代表修改,key1out的“0”代表时钟而不是闹钟 hou1b=hou1ain; -“b”代表显示模式的数据 hou2b=hou2ain; min1b=min1ain; min2b=min2ain; elsif key4out=0 then -key4没有按下 if( clkevent and clk=1) then if sec2b=1001 then sec2b=0000; sec1b=sec1b+1; if sec1b=0101 then sec1b=0000; min2b=min2b+1; if min2b=1001 then min2b=0000; min1b=min1b+1; if min1b=0101 then min1b=0000; if hou1b=0010 and hou2b=0011 then hou1b=0000; hou2b=0000; elsif hou2b=1001 then hou2b=0000; hou1b=hou1b+1; else hou2b=hou2b+1; end if; end if; end if; end if; ELSE sec2b=sec2b+1; end if; END IF; END IF;end process; end one;仿真:(由于仿真限制,仿真用了clk代替clk1)1)手动增值2)自动增值(4)按键显示发光LED模块:此模块主要功能是帮助确认按键所处的状态,从而确定数字钟显示的内容。这个模块利用发光LED与按键消抖后的输出相连,当输出为低电平时,即按键按下时,点亮LED,而输出为高电平时,即没有按下按键时,LED熄灭。 仿真结果:程序:LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;-按键显示模块,按键按下,相应的led则发光或熄ENTITY ledkey ISPORT( key1out:IN STD_LOGIC; architecture behave of ledkey is key2out:IN STD_LOGIC; begin key3out:IN STD_LOGIC; process(key1out,key2out,key3out) key4out:IN STD_LOGIC; begin led1out: out STD_LOGIC; if key1out=0 then led1out=0; led2out: out STD_LOGIC; else led1out=1; led3out: out STD_LOGIC; end if; led4out: out STD_LOGIC); if key2out=0 then led2out=0;end entity; else led2out=1; end if; if key3out=0 then led3out=0; else led3out=1; end if; if key4out=0 then led4out=0; else led4out=1; end if; end process; end behave; 仿真结果:(5)声音模块: 本模块只包括1个进程,进程分为3个判断的部分。分别为闹钟时间到的发声和整点报时到的发声。第一个部分判断是否处于时钟显示模式且key4是否按下,如果都满足则赋高电平给蜂鸣器输出端口beep,使其不发出声音。第二个部分判断时钟时间是否与闹钟时间相等,若是,则把低电平信号赋给蜂鸣器输出端口beep,直到手动按停。如果期间按键按下key4out=0则停止发声。第三个部分判断是否整点到了。到了59分,52秒,54秒,56秒时把clk3赋给beep,使其发声,58秒时赋一个高电平给beep, 达到最后一个音的音调变高的效果。其余的50,21,53,55,57,59秒赋低电平给蜂beep高电平停止发声。程序:library ieee;use ieee.std_logic_1164.all;use IEEE.STD_LOGIC_ARITH.ALL;use ieee.std_logic_unsigned.all;entity alarm is port( key1out:in std_logic; key2out:in std_logic; key3out:in std_logic; key4out:in std_logic; seth1a:in std_logic_vector(3 downto 0); seth2a:in std_logic_vector(3 downto 0); setm1a:in std_logic_vector(3 downto 0); setm2a:in std_logic_vector(3 downto 0); hou1b:in std_logic_vector(3 downto 0); hou2b:in std_logic_vector(3 downto 0); min1b:in std_logic_vector(3 downto 0); min2b:in std_logic_vector(3 downto 0); sec1b:in std_logic_vector(3 downto 0); sec2b:in std_logic_vector(3 downto 0); clk3:in std_logic;-用于整点报时的音调变化 beep:out std_logic ); end entity alarm;architecture one of alarm isbegin process(key4out,seth1a,seth2a,setm1a,setm2a,hou1b,hou2b,min1b,min2b,sec1b,sec2b) begin if key4outevent and key4out=1 then-手动按停声音 if(key3out=0 AND key2out=0 AND key1out=0) or (key3out=0 AND key2out=1 AND key1out=0)then beep=1; end if; end if; if(seth1a=hou1b and seth2a=hou2b and setm1a=min1b and setm2a=min2b and sec1b=0000 and sec2b=0000)then -闹钟时间到 beep=0; end if; if(min1b=0101 and min2b=1001) then-整点时间到 if(sec1b=0101) then if(sec2b=0010 or sec2b=0100 or sec2b=0110) then beep=clk3;-从52,54,56秒响 elsif(sec2b=1000) then beep=0;-58秒的音调变高 else beep=1;-59秒自动停止声音 end if; else beep=1; end if; end if; end process;end one;仿真:以下18:00前后,先是整点闹钟响,接着整点报时响。(6)译码显示以及闪烁模块: 思路:此模块包含4位数码管位选,段选,判断输出显示状态或者设置(修改)状态,判断是否闪烁等功能。通过判断key1key3的状态来确定给4位数码管输出的内容。程序分为两个进程,第一个进程用来决定位选与段选。位选部分使用累加器实现每进入一次程序依次循环选中每一位数码管。然后根据检测的情况(时间时-分,时间分秒,闹钟时-分,闹钟分-秒)把要显示的内容从“中间量”以BCD码的形式赋值给“最终量”,再判断“最终量”代表的数字值,再把数字值相应的段选码送给段选。位选与段选的数据送至数码管就能实现译码显示功能。 第二个进程有两个用途:a.用来更新显示内容,通过不断把即时要显示的内容(时-分或分-秒或不显示)送至“中间量”,由第一个进程送出去输出。b.用来控制闪烁,由clk2(2Hz)判断数码管的亮灭,当clk2=1,把时分或分秒的BCD码赋值给“中间量”,即为数码管“亮”;当clk2=0,按情况把选择要闪烁的那两位用“1111”(在进程一内被判定为“灭”)代替BCD码赋值给“中间量”,这样进程一可表现为“灭”。程序:LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY display2 ISPORT(clk2:IN STD_LOGIC; -半秒的驱动clk3:IN STD_LOGIC; -扫描数码管的驱动频率dout:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -段选selout:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -位选hou1a:in std_logic_vector(3 downto 0); -修改模式的时钟数据hou2a:in std_logic_vector(3 downto 0);min1a:in std_logic_vector(3 downto 0);min2a:in std_logic_vector(3 downto 0);seth1a:in std_logic_vector(3 downto 0); -闹钟数据(只有一种模式)seth2a:in std_logic_vector(3 downto 0);setm1a:in std_logic_vector(3 downto 0);setm2a:in std_logic_vector(3 downto 0);hou1b:in std_logic_vector(3 downto 0); -显示模式的时钟数据hou2b:in std_logic_vector(3 downto 0);min1b:in std_logic_vector(3 downto 0);min2b:in std_logic_vector(3 downto 0);sec1b:in std_logic_vector(3 downto 0);sec2b:in std_logic_vector(3 downto 0);key1out:in

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论