数字钟(可编程)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
“数字钟”综合设计实验—采用CPLD/FPGA可编程器件设计一、实验目的
1.掌握可编程逻辑器件的层次化设计方法;
2.掌握十进制、六十进制、二十四进制计数器的设计方法;
3.掌握多位计数器相连的设计方法;
4.掌握喇叭的驱动方法。
二、设计任务与要求
1.基本功能:具有小时、分钟、秒计数显示功能,并以24小时循环计时;
2.具有清零和校时的功能,具有整点报时的功能;
3.自由发挥功能:具有到点闹时功能,并且能够预置闹铃时间;4.要求小时、分钟、秒在数码管上的显示格式如下:
三、程序设计思路
本设计的难点在于时钟的计数功能和数码管显示功能,
1.60进制和24进制计数器的实现
VHDL实现计数比较简单,我们只要设置好计数的最终数值,通过简单的加法或者减法就可以实现任意数值的计数状态。
2.小时、分钟、秒计数显示的实现
数字钟的小时、分钟、秒共用8个数码管显示,并有2个数码管用来产生隔离符号“—”,为节省逻辑器件的I/O,时间显
示采用动态扫描的方法。
动态扫描的基本原理是对于一组数码管动态扫描显示需要由两组信号来控制:一组是字段输出口输出的字形代码,用来控制显示的字形,称为段码;另一组是位输出口输出的控制信号,用来选择第几位数码管工作,称为位码。
各位数码管的段线并联,段码的输出对各位数码管来说都是相同的。
因此,在同一时刻如果各位数码管的位选线都处于选通状态的话,8位数码管将显示相同的字符。
若要各位数码管能够显示出与本位相应的字符,就只让这一位的位选线处于导通状态,而其它各位的位选线处于关闭状态。
同时,段线上输出相应位要显示字符的字型码。
这样在同一时刻,只有选通的那一位显示出字符,而其它各位则是熄灭的,如此循环下去,就可以使各位数码管显示出将要显示的字符。
3.动态扫描的实现:
基本思路是利用硬件语言编写一个8进制的计数器,根据计数器的值译出位选通信号来选择哪一个数码管显示;段线上显示的时间用一组减计数器实现,通过7段译码程序将计数器的时间信息按照相应的位信息送到段线上。
四、仿真与硬件测试
1.功能仿真
程序编译后要对其进行功能仿真以此来验证各模块设计的正确性,在仿真过程中,分别改变特殊状态按键,观察输出的仿真运行结果,验证电路的逻辑功能是否达到设计要求。
2.硬件测试
功能仿真正确后,进行管脚锁定,锁定管脚时必须对实验箱的硬件资源有一定的了解,锁定时将设计中的输入输出信号和FPGA的具体管脚相对应,实验中选用器件为EPF10K10LC-84,锁定完后再进行一次编译,保证管脚配置起作用。
五、实验报告要求
课题完成后应认真撰写实验报告,其主要内容如下:
1.课题的任务及要求。
2.叙述所设计的数字钟的工作原理
3.课题分析与编程思路。
对课题认真分析,正确理解,明确设计思路。
4.仿真结果分析。
建立测试向量文件,然后编译该文件,进行功能仿真和时序仿真,给出仿真结果并进行分析。
5.实验设计中各功能模块的源程序。
6.总结。
总结课题存在的问题,提出改进的设想;完成本课题后的收获、体会和建议。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY timer IS
PORT(clk,clk1:IN STD_LOGIC;
clr,prnh,prnm:IN STD_LOGIC;
q,y: OUT STD_LOGIC_VECTOR(7 downto 0);
spk: OUT STD_LOGIC);
END timer;
ARCHITECTURE behav OF timer IS COMPONENT cnt60 IS
PORT(clk,keyclk,clr,prn:IN STD_LOGIC;
qh,ql:OUT STD_LOGIC_VECTOR(3 downto 0);
qcarry: OUT STD_LOGIC);
END COMPONENT;
COMPONENT cnt24 IS
PORT(clk,clr:IN STD_LOGIC;
qh,ql:OUT STD_LOGIC_VECTOR(3 downto 0));
END COMPONENT;
SIGNAL shtem,sltem,mhtem,mltem,hhtem,hltem,da:
STD_LOGIC_VECTOR(3 downto 0); SIGNAL sctem,mctem:STD_LOGIC;
SIGNAL cou:INTEGER RANGE 0 to 10;
SIGNAL dout,tempy:STD_LOGIC_VECTOR(7 DOWNTO 0); BEGIN
U1:cnt60 PORT MAP(CLK1,clk,clr,PRNM,
SHTEM,SLTEM,SCTEM); --clk1 is 1hz,clk is 1024hz U2:cnt60 PORTMAP(SCTEM,clk,clr,PRNH,
mhtem,mltem,MCTEM);
U3:cnt24 PORT MAP(MCTEM,clr,HHTEM,HLTEM);
PROCESS(clk)
BEGIN
IF(clk'EVENT AND clk='1')THEN --clk is 1024hz IF cou<8 THEN
cou<=cou+1;
ELSE
cou<=0;
END IF;
CASE cou IS
WHEN 0=>da<=HHTEM;
TEMPY<="10000000";
WHEN 1=>da<=HLTEM;
TEMPY<="01000000";
WHEN 2=>da<="1010";
TEMPY<="00100000";
WHEN 3=>da<=mhtem;
TEMPY<="00010000";
WHEN 4=>da<=mltem;
TEMPY<="00001000";
WHEN 5=>da<="1010";
TEMPY<="00000100";
WHEN 6=>da<=SHTEM;
TEMPY<="00000010";
WHEN 7=>da<=SLTEM;
TEMPY<="00000001";
WHEN OTHERS=>da<="0000";
TEMPY<="00000000";
END CASE;
END IF;
CASE da IS
WHEN "0000"=>dout<="00111111";
WHEN "0001"=>dout<="00000110";
WHEN "0010"=>dout<="01011011";
WHEN "0011"=>dout<="01001111";
WHEN "0100"=>dout<="01100110";
WHEN "0101"=>dout<="01101101";
WHEN "0110"=>dout<="01111101";
WHEN "0111"=>dout<="00000111";
WHEN "1000"=>dout<="01111111";
WHEN "1001"=>dout<="01101111";
WHEN "1010"=>dout<="01000000";
WHEN "1011"=>dout<="01111100";
WHEN "1100"=>dout<="00111001";
WHEN "1101"=>dout<="01011110";
WHEN "1110"=>dout<="01111001";
WHEN "1111"=>dout<="01110001";
WHEN OTHERS=>dout<="00000000"; END CASE;
IF(mhtem="0000" AND mltem="0000")THEN spk<=mCTEM AND clk AND CLK1; END IF;
END PROCESS;
Q<=dout;y<=TEMPY;
END BEHAV;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cnt60 IS
PORT(clk,keyclk,clr,prn:IN STD_LOGIC;
qh,ql:OUT STD_LOGIC_VECTOR(3 downto 0);
qcarry: OUT STD_LOGIC);
END cnt60;
ARCHITECTURE behav OF cnt60 IS
SIGNAL qtemh,qteml:STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL qc:STD_LOGIC;
SIGNAL cou:INTEGER RANGE 0 TO 200;
BEGIN
PROCESS(keyclk)
BEGIN
IF(keyclk 'EVENT AND keyclk='1')THEN
cou<=cou+1;
END IF;
END PROCESS;
PROCESS(clk,keyclk)
BEGIN
IF(cou=0)AND(PRN='1')THEN
qc<=keyclk;
ELSIF clr='0'THEN
qtemh<=(OTHERS=>'0');
qteml<=(OTHERS=>'0');
ELSIF(clk 'EVENT AND clk='1')THEN
IF(qteml<9)THEN
qteml<=qteml+1;
ELSE
qteml<=(OTHERS=>'0');
qc<='0';
IF(qtemh<5)THEN
qtemh<=qtemh+1;
ELSE
qtemh<=(OTHERS=>'0');
qc<='1';
END IF;
END IF;
END IF;
END PROCESS;
QH<=qtemh;QL<=qteml;qcARRY<=qc; END behav;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cnt24 IS
PORT(clk,clr:IN STD_LOGIC;
qh,ql:OUT STD_LOGIC_VECTOR(3 downto 0));
END cnt24;
ARCHITECTURE behave OF cnt24 IS
SIGNAL qtemh,qteml:STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN
PROCESS(clk)
BEGIN
IF clr='0'THEN
qtemh<=(OTHERS=>'0');
qteml<=(OTHERS=>'0');
ELSIF(clk'EVENT AND clk='1')THEN
IF(qtemh<2)THEN
IF qteml<9 THEN
qteml<=qteml+1;
ELSE
qteml<=(OTHERS=>'0');
qtemh<=qtemh+1;
END IF;
ELSIF(QTEMh=2)THEN
IF qteml<3 THEN
qteml<=qteml+1;
ELSE
qtemh<=(OTHERS=>'0');
qteml<=(OTHERS=>'0');
END IF;
END IF;
END IF;
END PROCESS;
QH<=qtemh;QL<=qteml; END behave;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity dzz is
port(clk,clk_scan,reset,setm,seth:in std_logic;
dlh2:std_logic_vector(3 downto 0);
time,sm:out std_logic_vector(7 downto 0);
--7段显示段码和位码
spk:out std_logic);
end dzz;
architecture SZ of dzz is
signal cou:integer range 0 to 8;
signal bs,nl:std_logic;
signal h1,h2,m1,m2,s1,s2:std_logic_vector(3 downto 0); signal da:std_logic_vector(3 downto 0);
begin
process(clk)
begin
if (clk'event and clk='1') then
--清零
if reset='0' then
h1<="0000";h2<="0000";m1<="0000";m2<="0000"; s1<="0000";s2<="0000";
--校分
elsif setm='1' then
m2<=m2+1;
if m2="1001" then
m2<="0000";
m1<=m1+1;
if m1="0101" then
m1<="0000";
end if;
end if;
--校时
elsif seth='1' then
h2<=h2+1;
if h2="1001" then
h2<="0000";
h1<=h1+1;
if h1="0010" and h2<="0011" then
h1<="0000";h2<="0000";
end if;
end if;
end if;
--正常计数
if s2="1001" then
s2<="0000";
else s2<=s2+1;
end if;
if (s1="0101" and s2="1001") then
s1<="0000";
elsif s2="1001" then --秒低位为9,高位不为5;
s1<=s1+1;
end if;
if m2="1001" and (s1="0101" and s2="1001") then
m2<="0000";
elsif (s1="0101" and s2="1001") then --分低不为9;
m2<=m2+1;
end if;
if (m1="0101" and m2="1001") and
( s1="0101" and s2="1001") then
--59分59秒
m1<="0000";
elsif m2="1001" and (s1="0101" and s2="1001") then --分高不为5,分低9,且59秒
m1<=m1+1;
end if;
if h2="1001" and (m1="0101" and m2="1001") and (s1="0101" and s2="1001") then
--9时59分秒59秒;
h2<="0000";
elsif (m1="0101" and m2="1001") and
(s1="0101" and s2="1001") then h2<=h2+1;
end if;
if (h1="0010" and h2="0011") and
(m1="0101" and m2="1001") and
( s1="0101" and s2="1001") then
--23时59分秒59秒
h1<="0000";h2<="0000";
elsif h2="1001" and (m1="0101" and m2="1001") and ( s1="0101" and s2="1001") then
h1<=h1+1;
end if;
end if;
--整点报时
if (m1="0000" and m2="0000")
and (s1="0000" and s2="0000") then bs<='1';
elsif (m1="0000" and m2="0001")
and (s1="0010" and s2="0000") then bs<='0';
--报时20秒
end if;
--到点闹钟
if h2=conv_integer(dlh2) and
(m1="0000" and m2="0000") then
nl<='1';
elsif h2=conv_integer(dlh2) and
(m1="0000" and m2="0001") then
nl<='0';
--闹铃1分钟,
end if;
end process;
process(clk_scan)
begin
if(clk_scan'EVENT and clk_scan='1')then if cou<7 then
cou<=cou+1;
else
cou<=0;
end if;
case cou is
when 0=>da<=h1;
sm<="10000000";
when 1=>da<=h2;
sm<="01000000";
when 2=>da<="1010";
sm<="00100000";
when 3=>da<=m1;
sm<="00010000";
when 4=>da<=m2;
sm<="00001000";
when 5=>da<="1010";
sm<="00000100";
when 6=>da<=s1;
sm<="00000010";
when 7=>da<=s2;
sm<="00000001";
when others=>da<="0000";
sm<="00000000";
end case;
end if;
case da is
when "0000"=>time<="00111111";
when "0001"=>time<="00000110";
when "0010"=>time<="01011011";
when "0011"=>time<="01001111";
when "0100"=>time<="01100110";
when "0101"=>time<="01101101";
when "0110"=>time<="01111101";
when "0111"=>time<="00000111";
when "1000"=>time<="01111111";
when "1001"=>time<="01101111";
when "1010"=>time<="01000000";
when others=>time<="00000000";
end case;
spk<=(bs or nl) and clk and clk_scan;
end process;
end SZ;。