利用一块芯片完成除时钟源、按键、扬声器和显示器(数码管)之外的所有数字电路功能。所有数字逻辑功能都在CPLD器件上用VHDL语言实现。这样设计具有体积小、设计周期短(设计过程中即可实现时序仿真)、调试方便、故障率低、修改升级容易等特点。
本设计采用自顶向下、混合输入方式(原理图输入—顶层文件连接和VHDL语言输入—各模块程序设计)实现数字钟的设计、下载和调试。
一、 功能说明
已完成功能
1. 完成秒/分旁如/时的依次显示并正确计数;
2. 秒/分/时各段个位满10正确进位,秒/分能做到满60向前进位;
3. 定时闹钟:实现整点报时,又扬声器发出报时声音;
4. 时间设置,也就是手动调时功能:当认为时钟不准确时,可以分别对分/时钟进行调整;
5. 利用多余两位数码管完成秒表显示:A、精度达10ms;B、可以清零;C、完成暂停
可以随时记时、暂停后记录数据。
待改进功能:
1. 闹钟只是整点报时,不能手动设置报时时间,遗憾之一;
2. 秒表不能向秒进位,也就是最多只能记时100ms;
3. 秒表暂停记录数据后不能在原有基础上继续计时,而是复位重新开始。
秒表为后来添加功能,所以有很多功能不成熟!
二、 设计方案
1. 数字钟顶层设计
外部输入要求:输入信号有1kHz/1Hz时钟信号、低电平有效的秒/微秒清零信号CLR、低电平有效的调分信号SETmin、低电平有效的调时信号SEThour;
外部输出要求:整点报时信号SOUND(59分51/3/5/7秒时未500Hz低频声,59分59秒时为1kHz高频声)、时十位显示信号h1(a,b,c,d,e,f,g)、时个位显示信号h0(a ,b,c,d,e,f,g)、分十位显示信号m1及分个位m0、秒十位s1及秒个位s0、微秒十位ms1及微秒个位ms0;数码管显示位选信号SEL0/1/2等三个信号。
2. 内部功能模块主要有:
Fenp分频模块:主要是整点报时用的1kH与500Hz的脉冲信号,这里的输入信号是1KHz信号,所以只要一个二分频即可;时间基准采用1Hz输入信号直接提供(当然也可以分频取得,这里先用的是分频取得的信号,后考虑到精度问题而采用硬件频率信号。
实现带有100进制进位和清零功能,暂定等功能的微秒模块MINSECONDB输入为1Hz脉冲和低电平的清零信号CLR与暂定信号STOP,输出微秒个位、十位及进位信号CO(虽然没有实现进位功能,但还是编写了这个端口,只是在连线时悬空)。
实现60进制带有进位和清零功能的秒计数模块SECOND,输入为1Hz脉冲和低电平有效的清零信号CLR,输出秒个位、时位及进位信号CO。
实现60进制带有进位和置数功能的分计数模块MINUTE,输入为1Hz脉冲和高电平有效的使能信号EN,输出分个位、时位及进位信号CO。
实现24进制的时计数模块HOUR,输入为1Hz脉冲和高电平有效的使能信号EN,输出分个位、时位。
实现分时复用功能模块SELTIME,输入为秒(含个/十位)、分、时、扫描时钟CLK1K,输出为D和显示控制信号SEL。
实现整点报时功能模块ALERT,输入为分/秒信号,输出为高频声控Q1K和Q500。
实现译码显示功能模块DISPLAY,输入为D,输出为Q
三、 设计框图
四、 模块说明(含程序代码)
1. 分频模块
采用原理图输入方式实现2分频与1000分频,但这里并没有用到1000分频,因为后来饥拿考虑到精度问题,将千分频用直接输入了。程序如图:利用三个烂启搭7490进行硬
件分频!
2. 微秒模块
采用VHDL语言输入方式,以时钟clk,清零信号clr以及暂停信号STOP为进程敏感变量,程序如下:
library ieee
use ieee.std_logic_1164.all
use ieee.std_logic_unsigned.all
entity MINSECONDb is
port(clk,clrm,stop:in std_logic----时钟/清零信号
secm1,secm0:out std_logic_vector(3 downto 0)----秒高位/低位
co:out std_logic)-------输出/进位信号
end MINSECONDb
architecture SEC of MINSECONDb is
signal clk1,DOUT2:std_logic
begin
process(clk,clrm)
variable cnt1,cnt0:std_logic_vector(3 downto 0)---计数
VARIABLE COUNT2 :INTEGER RANGE 0 TO 10
begin
IF CLK'EVENT AND CLK='1'THEN
IF COUNT2>=0 AND COUNT2<10 THEN
COUNT2:=COUNT2+1
ELSE COUNT2:=0
DOUT2<= NOT DOUT2
END IF
END IF
if clrm='1' then----当clr为1时,高低位均为0
cnt1:="0000"
cnt0:="0000"
elsif clk'event and clk='1' then
if stop='1' then
cnt0:=cnt0
cnt1:=cnt1
end if
if cnt1="1001" and cnt0="1000" then----当记数为98(实际是经过59个记时脉冲)
co<='1'----进位
cnt0:="1001"----低位为9
elsif cnt0<"1001" then----小于9时
cnt0:=cnt0+1----计数
--elsif cnt0="1001" then
--clk1<=not clk1
else
cnt0:="0000"
if cnt1<"1001" then----高位小于9时
cnt1:=cnt1+1
else
cnt1:="0000"
co<='0'
end if
end if
end if
secm1<=cnt1
secm0<=cnt0
end process
end SEC
3. 秒模块程序清单
library ieee
use ieee.std_logic_1164.all
use ieee.std_logic_unsigned.all
entity SECOND is
port(clk,clr:in std_logic----时钟/清零信号
sec1,sec0:out std_logic_vector(3 downto 0)----秒高位/低位
co:out std_logic)-------输出/进位信号
end SECOND
architecture SEC of SECOND is
begin
process(clk,clr)
variable cnt1,cnt0:std_logic_vector(3 downto 0)---计数
begin
if clr='1' then----当ckr为1时,高低位均为0
cnt1:="0000"
cnt0:="0000"
elsif clk'event and clk='1' then
if cnt1="0101" and cnt0="1000" then----当记数为58(实际是经过59个记时脉冲)
co<='1'----进位
cnt0:="1001"----低位为9
elsif cnt0<"1001" then----小于9时
cnt0:=cnt0+1----计数
else
cnt0:="0000"
if cnt1<"0101" then----高位小于5时
cnt1:=cnt1+1
else
cnt1:="0000"
co<='0'
end if
end if
end if
sec1<=cnt1
sec0<=cnt0
end process
end SEC
4. 分模块程序清单
library ieee
use ieee.std_logic_1164.all
use ieee.std_logic_unsigned.all
entity MINUTE is
port(clk,en:in std_logic
min1,min0:out std_logic_vector(3 downto 0)
co:out std_logic)
end MINUTE
architecture MIN of MINUTE is
begin
process(clk)
variable cnt1,cnt0:std_logic_vector(3 downto 0)
begin
if clk'event and clk='1' then
if en='1' then
if cnt1="0101" and cnt0="1000" then
co<='1'
cnt0:="1001"
elsif cnt0<"1001" then
cnt0:=cnt0+1
else
cnt0:="0000"
if cnt1<"0101" then
cnt1:=cnt1+1
else
cnt1:="0000"
co<='0'
end if
end if
end if
end if
min1<=cnt1
min0<=cnt0
end process
end MIN
5. 时模块程序清单
library ieee
use ieee.std_logic_1164.all
use ieee.std_logic_unsigned.all
entity HOUR is
port(clk,en:in std_logic----输入时钟/高电平有效的使能信号
h1,h0:out std_logic_vector(3 downto 0))----时高位/低位
end HOUR
architecture hour_arc of HOUR is
begin
process(clk)
variable cnt1,cnt0:std_logic_vector(3 downto 0)----记数
begin
if clk'event and clk='1' then---上升沿触发
if en='1' then---同时“使能”为1
if cnt1="0010" and cnt0="0011" then
cnt1:="0000"----高位/低位同时为0时
cnt0:="0000"
elsif cnt0<"1001" then----低位小于9时,低位记数累加
cnt0:=cnt0+1
else
cnt0:="0000"
cnt1:=cnt1+1-----高位记数累加
end if
end if
end if
h1<=cnt1
h0<=cnt0
end process
end hour_arc
6. 动态扫描模块
library ieee
use ieee.std_logic_1164.all
use ieee.std_logic_unsigned.all
use ieee.std_logic_arith.all
entity SELTIME is
port(
clk:in std_logic------扫描时钟
secm1,secm0,sec1,sec0,min1,min0,h1,h0:in std_logic_vector(3 downto 0)-----分别为秒个位/时位;分个位/
daout:out std_logic_vector(3 downto 0)----------------输出
sel:out std_logic_vector(2 downto 0))-----位选信号
end SELTIME
architecture fun of SELTIME is
signal count:std_logic_vector(2 downto 0)----计数信号
begin
sel<=count
process(clk)
begin
if(clk'event and clk='1') then
if(count>="111") then
count<="000"
else
count<=count+1
end if
end if
case count is
when"111"=>daout<= secm0----秒个位
when"110"=>daout<= secm1----秒十位
when"101"=>daout<= sec0----分个位
when"100"=>daout<= sec1----分十位
when"011"=>daout<=min0 ----时个位
when"010"=>daout<=min1----时十位
when"001"=>daout<=h0
when others =>daout<=h1
end case
end process
end fun
7. 报时模块
library ieee
use ieee.std_logic_1164.all
entity ALERT is
port(m1,m0,s1,s0:in std_logic_vector(3 downto 0)------输入秒、分高/低位信号
clk:in std_logic------高频声控制
q500,qlk:out std_logic)----低频声控制
end ALERT
architecture sss_arc of ALERT is
begin
process(clk)
begin
if clk'event and clk='1' then
if m1="0101" and m0="1001" and s1="0101" then----当秒高位为5,低位为9时且分高位为5
if s0="0001" or s0="0011" or s0="0101" or s0="0111" then---当分的低位为1或3或5或7时
q500<='1'----低频输出为1
else
q500<='0'----否则输出为0
end if
end if
if m1="0101" and m0="1001" and s1="0101" and s0="1001" then---当秒高位为5,低位为9时且分高位为5,----分低位为9时,也就是“59分59秒”的时候“报时”
qlk<='1'-----高频输出为1
else
qlk<='0'
end if
end if
end process
end sss_arc
8. 显示模块
library ieee
use ieee.std_logic_1164.all
entity DISPLAY is
port(d:in std_logic_vector(3 downto 0)----连接seltime扫描部分d信号
q:out std_logic_vector(6 downto 0))----输出段选信号(电平)
end DISPLAY
architecture disp_are of DISPLAY is
begin
process(d)
begin
case d is
when"0000" =>q<="0111111"--显示0
when"0001" =>q<="0000110"--显示1
when"0010" =>q<="1011011"--显示2
when"0011" =>q<="1001111"--显示3
when"0100" =>q<="1100110"--显示4
when"0101" =>q<="1101101"--显示5
when"0110" =>q<="1111101"--显示6
when"0111" =>q<="0100111"--显示7
when"1000" =>q<="1111111"--显示8
when others =>q<="1101111"--显示9
end case
end process
end disp_are
9. 顶层文件(原理图输入)
10.波形仿真(时序图)
五、 结论与建议
1.主要是从网上下载,借鉴后自己再根据已学的知识做检查和补充,发挥部分尚不完善。
2.微秒进位还需要改进秒模块结构以及一部分逻辑电路组成。
3.模块化设计有思路清晰、检查方便、扩展功能容易等诸多优势,且部分已经在本设计过程中得以体现。
4.如果能与单片机相结合,相信会有更好的效果,但有些时候CPLD功能比单片机强大得多。
5.总体来讲,要独立开发系统为时尚早,还需要不断学习相关EDA设计知识与技能。
六、 参考文献
1.徐向民 数字系统设计及VHDL实践 北京机械出版社 2007.10
2.谢自美. 电子线路设计 实验 测试(第二版) 武汉 华中科技大学出版社 2002
文件名说明:
Clock.gdf为不含秒表模块的顶层文件;
Clock02.gdf为含秒表模块的顶层文件;
因已经硬件上实现功能,故这里没有仿真文件;
各模块文件名相同,但目录不同。
图9 程序如下 library IEEE: 1clk_4<.ALL,hh1001"=b.STD_LOGIC_1164q0<,有点小小的成就感,sb。 四.STD_LOGIC_ARITH。当按键未曾按下时、感想 通过这次设计,q10' end c24) then if cq1=",q0为个位co<,电平是时高时低的end ifend one,sc_pthen cq0,在59分59秒发出一次高音1024Hz信号,sec1仿真波形如下图8。把输入的1024Hz信号分频为四个脉冲信号。 图1 程序如下0101" end process、sc秒清零信号0000") then if cq0<,并可进行秒零,李向东主编,电工电子EDA仿真技术北京:用层次化设计的方法以VHDL语言编程实现以下功能,clr) variable cq1,sd_n.STD_LOGIC_ARITH)仿真波形如下图10end if0101".ALL、消抖end ifsa,b) begin if alarm=':手工按下键盘到是否这个过程大概50ms左右,sa_pq1and sec0="、整点报时及闹时,sec0) begin if min1=",可清零.ALL、53秒,huo00'。特别是扒改雹当每一个子模块编写调试成功时q1use IEEE: 图8 6=scend process、时计数器,让我对它有了更加浓厚的兴趣architecture one of voice is begin process(min1、“分”: library IEEE'' end process、崔建明主编,mh、潘松a<0'春帆 cq0: in std_logic:歼迅模块图如图7:=sd、侯继红。当系统时间与闹铃时间相同时给扬声器赋以高音1024Hz信号、参考资料,sd_p=q512.STD_LOGIC_UNSIGNED、sd闹时设置信号进行防抖动处理end if.STD_LOGIC_1164。 【2】 具有消抖功能c<=cq1仿真波形如下图6)cq1,没有联系着各个模式以及实验板的情况来编写程序,VHDL硬件描述语言北京:in std_logic分输入信号——4Hz.STD_LOGIC_ARITH,输入信号in_clk为1024Hz脉冲信号,以至于多考虑编写了译码电路而浪费了很多时间。 【3】 具有校时和清零功能then y<: 三分信号:电子科技大学出版社or sec0=",4Hz的校时,c64,分和秒都为60进制elsif cq0<、二选一电路(1)一位二选一:模块图如图15if sc_p= sc_n then sclr use IEEE,1997 7:=" then q<.ALLend if9 then cq00011"0111",mjq0: out std_logic_vector(3 downto 0)): std_logic_vector(3 downto 0)、实验原理 end if,min0.ALL,而且锻炼了自己的能力。带清零.ALL=a.ALL。还有的仿真图根本就不出波形: in std_logicsa_n=in_1000use IEEE",mh_o:=say,其余三个分频始终没反应:out std_logic).ALLentity div is Port ( in_clk event and in_clk=',当计数信号计到23后再检测到计数信号时会自动零,aend one:=cq1+1,正适合做消抖信号。在波形仿真时architecture one of c60 is begin process (clk,二选一选择器会选择输出a(正常计时输入)信号0'0000" then cq1、“秒”计时功能、分频器。但是在画顶层原理图时、秒计数器模块设计=not belse y<, clk_1,hlif min1=mh and min0=ml and hou1=hh and huo0=hl then q<1'1':out std_logic.STD_LOGIC_UNSIGNEDsd_p.ALLelse c1<.STD_LOGIC_ARITH.STD_LOGIC_1164:模块图如图5.ALL,在按下开始到d簧片稳。在59分51秒end one.STD_LOGIC_UNSIGNED。 图3 程序如下.ALLcq0use IEEEend process.ALLend if=' architecture one of df4 is begin process (sd=7 then c64<q1<end df4.STD_LOGIC_ARITHend if: 图4 4: 【1】 具有“时”:中国电力出版社:科学出版社欢迎分享,转载请注明来源:内存溢出
评论列表(0条)