FPGA期末项目 | 数字时钟

FPGA期末项目 | 数字时钟,第1张

FPGA开发平台、计算机、其它外接器件

选题的意义:个人认为本项目(《数字时钟》)的选题意义有二,其一,时钟和闹钟早已是老生常谈的日常工具,利用课堂上所学习的知识贯通运用到现实生活中,作为 *** 作实践,具有一定的现实意义;其二,数字时钟的功能设计囊括了数码管、LCD屏、开关运用、管教分配等知识,能够对本学期所学的实验知识做一个挽接,在知识的总结上也具备一定意义;

功能要求:

1.用数码管显示时、分、秒:分为两个界面,即时钟界面以及闹钟设置界面,显示时钟的时分秒以及闹钟的时分秒,可以通过开关切换显示,是项目的基本功能;

2.能按比例缩短时间调试:调控时钟或闹钟的频跳速度,方便演示和调试;

3.闹钟功能:用户可以通过sw8切换进入闹钟界面,再利用sw1-3设定具体的闹钟时间,到点即响,同样是项目的基本功能;

4.用LCD屏显示日期(年月日)以及祝福语:作为时钟,显示年月日的功皮仔察能个人觉得也是有必要的,另外关于祝福语,我们对实验和知识的学习其实本身就是快乐的过程,生活也没有必要每天都过得毫无色彩、千篇一律,所以怀揣着这份情怀呢,我在本项目中加了一个显示祝福语的功能,意在表达自己的这份对科学和生活的热爱以及学习的热情。

系统结构图如下所示:

模块的功能及端口介绍:

(这里的模块功能和端口做简要的介绍,详细的用法请移步至《设计思路》部分)

功能:顶层模块,调用其他子模块,统筹整个系统的功能;

端口:

clk_50M,//系统时钟燃茄输入

Reset_n,//系统复位输入

seg7, //数码管显示输出位

ledcom, //数码管位置调控输出位

key,//开关输入号位,主要使用于CLKcounter_60BCD

beep, //蜂鸣器输出信号

LCD_ON1,//LCD供电电源开关

LCD_BLON1, //LCD背景电源开关

LCD_RS1,//寄存器选择信号

LCD_RW1,//液晶读写信号

LCD_EN1,//液晶时钟信号

LCD_DATA1, //LCD的数据端口

功能:LCD屏显示控制模块,用于控制LCD屏显示年月日以及祝福语;

端口:

LCD_ON, //LCD供电电源开关

LCD_BLON, //LCD背景电源开关

LCD_RS, //寄存器选择信号

LCD_RW, //液晶读写信号

LCD_EN, //液晶时钟信号

LCD_DATA, //LCD的数据端口

CLK,//模块时钟输入(项目中输入的是clk_50M)

功能:基于视觉暂留知识,控制时钟界面数码管的显示;

端口:

clk,//模块时钟输入

rst_n, //复位信戚纯号输入

mimute_cnt, //分钟位数据输入

second_cnt, //秒位数据输入

hour_cnt, //时位数据输入

seg7, //数码管显示输出位

ledcom, //数码管位置调控输出位

功能:在顶层模块调用,根据输入的时钟和时|分|秒位数据进行对应的加一计算和进位计算,并在溢出(分秒59加一溢出,时23加一溢出)时返回一个flag供顶层模块使用;

端口:

clk,//模块时钟输入

rst,//复位信号输入

couter_o, //数字时钟部分的时|分|秒位数据输出

flag, //输出一个溢出进位标志

功能:对输入的50MHz的系统时钟分频,调用时根据CLK_DIV变量的复用情况进行运算并返回对应的时钟分频结果;

端口:

clk_in, //模块时钟输入,在顶层模块

rst,//复位信号输入

clk_out,//时钟分频结果输出

hour_cnt,CLKmimute_cnt,CLKsecond_cnt,CLKhour_cnt,ledcom,seg7,sw8)

功能:基于视觉暂留知识,控制闹钟设置界面数码管的显示,并基于sw8的状态控制切换数码管屏显示;

端口:

clk,//模块时钟输入

rst,//复位信号输入

mimute_cnt, //分钟位数据输入(时钟)

second_cnt, //秒位数据输入(时钟)

hour_cnt, //时位数据输入(时钟)

CLKmimute_cnt,//分钟位数据输入(闹钟设置)

CLKsecond_cnt,//秒位数据输入(闹钟设置)

CLKhour_cnt,//时位数据输入(闹钟设置)

seg7, //数码管显示输出位

ledcom, //数码管位置调控输出位

sw8 //开关8的输入信号

功能:在顶层模块调用,根据输入的时钟频率clk和时|分|秒位数据进行对应的加一计算和进位计算,并在溢出(分秒59加一溢出,时23加一溢出)时返回一个flag供顶层模块使用;

端口:

clk,//模块时钟输入

rst,//复位信号输入

couter_o, //数字闹钟设置部分的时|分|秒位数据输出

flag, //输出一个溢出进位标志

sw //开关输入位,作为key的接收变量

功能:顶层模块,调用其他子模块,统筹整个系统的功能;

思路:

A.复用两次分频模块clk_gen,产生两个速度不一样的时钟频——clk_second和clk_second2,分别用来驱动数字时钟和数字闹钟设置;

B.复用三次时钟控制模块counter_60BCD:

第一次,用clk_second作为时钟频输入,传入second_cnt给couter_o作为秒位数据承载,MODULEofCNT设置为60,模块每溢出一次(即每计数到60个秒),产生一个flag,即flag_min;

第二次,用flag_min作为时钟频输入,传入minute_cnt给couter_o作为秒位数据承载,MODULEofCNT设置为60,模块每溢出一次(即每计数到60个分),产生一个flag,即flag_hour;

第三次,用flag_hour作为时钟频输入,传入hour_cnt给couter_o作为秒位数据承载,MODULEofCNT设置为24,模块每计数到24个时溢出一次;

C.复用三次闹钟控制模块CLKcounter_60BCD:

第一次,用clk_second2作为时钟频输入,传入CLKsecond_cnt给couter_o作为秒位数据承载,MODULEofCNT设置为60,sw位传入key[2]信号,即sw3的状态信号;

第二次,用clk_second2作为时钟频输入,传入CLKminute_cnt给couter_o作为秒位数据承载,MODULEofCNT设置为60,sw位传入key[1]信号,即sw2的状态信号;

第三次, 用clk_second2作为时钟频输入,传入CLKhour_cnt给couter_o作为秒位数据承载,MODULEofCNT设置为24,sw位传入key[0]信号,即sw1的状态信号;

D.复用LCD屏控制显示模块lcd_ori,根据本函数定义的变量复用对应的参数;

E.复用闹钟数码管控制显示模块CLKseg_display,根据本函数定义的变量复用对应的参数;

F.接下来,编写了一个状态机,主要设置并使用了state0、state1、state2等三个状态;

state0状态:使用if判断语句

if(second_cnt==CLKsecond_cnt&&minute_cnt==CLKminute_cnt&&hour_cnt==CLKhour_cnt)

等一个在闹钟界面模块设置的时分秒数列,等到这个数列的时候转跳到state1或state2,并设置好蜂鸣器鸣响的延时时间到变量cnt_2;

state1、state2:在计数变量cnt_2归零之前,一直给蜂鸣器管脚输出高电平,直到计数变量cnt_2归零,输出为低电平,停止蜂鸣器鸣响;

功能:LCD屏显示控制模块,用于控制LCD屏显示年月日以及祝福语;

思路:

A.将年月日以及祝福语分别编写成字符串,再分别付给变量lcd_buf_first、data_first和lcd_buf_second、data_second;

B.准备好状态参数常量——

clear_lcd、

set_disp_mode、

disp_on、

shift_down、

write_data_first、

write_data_second;

基于状态机思想,并用current_state变量承载状态常量;

C.初始化LCD模块;

D.clear_lcd状态, 清屏并光标复位 ;

set_disp_mode: 设置显示模式:8位2行5x8点阵;

disp_on: 显示器开、光标不显示、光标不允许闪烁 ;

shift_down: 文字不动,光标自动右移;data_first赋值给lcd_buf_first

write_data_first、write_data_second: 用于写入数据

default: 若current_state为其他值,则将current_state置为clear_lcd;

功能:基于视觉暂留知识,控制时钟界面数码管的显示;

思路:

A.复用分频模块clk_gen分频出一个时钟clk_div,周期约为0.1s;

B.设置一个8位的变量cnt,基于clk_div进行递加一,并在0到满位溢出之间循环(满位溢出时将之归零,再继续加一处理);

C.基于快速递加一的变量cnt,在每个clk时钟上升沿来的是时候,取其低三位(八个数码管格位,刚好三位二进制数可以完整表示)进行case处理,

每个case的子状态中,根据cnt低三位的值,把对应的表示数码管位置的二进制数赋值给ledcom,用于选择数码管格位;再把对应的数据(如秒位数据的低四位second_cnt[3:0],高四位second_cnt[7:4]等)传给dis变量;dis的用法是在下一个always模块里面,case判断dis的值,根据dis的值把对应的二进制数传给seg7变量,用于基于ledcom选择数码管格位之后,显示格位里面的内容;

由此,基于快速跳变的clk时钟和clk_div时钟,ledcom的值也不断地快速变换,由此数码管的每个格位都在被快速地选择和显示,于是这样便是通过了视觉暂留效应,实现了数码管时钟的显示;

功能:在顶层模块调用,根据输入的时钟和时|分|秒位数据进行对应的加一计算和进位计算,并在溢出(分秒59加一溢出,时23加一溢出)时返回一个flag供顶层模块使用;

思路:

A.将MODULEofCNT(分别通过/10和%10运算)切成5/2和9/3两个数,并分别付给变量a和b;

B.通过a和b判断是对分秒位数据(MODULEofCNT为60)还是对时位数据(MODULEofCNT为24)进行计算;

若是分秒位数据:先对couter_o[7:4]进行判断,若小于5,则对couter_o[3:0]判断,若couter_o[3:0]小于9,则couter_o[3:0]数据加一,若couter_o[3:0]不小于于9,则couter_o[3:0]归零处理,couter_o[7:4]加一;若couter_o[7:4]不小于5,则对couter_o[3:0]判断,若couter_o[3:0]小于a(9),则couter_o[3:0]数据加一,若couter_o[3:0]不小于于a(9),则couter_o八个位都归零,并返回一个溢出进位flag(flag<=1);

若是时位数据:逻辑同上,只将b替换为2,将a替换为3进行处理即可;

功能:对输入的50MHz的系统时钟分频,调用时根据CLK_DIV变量的复用情况进行运算并返回对应的时钟分频结果;

思路:简单地基于系统时钟clk_in以及可复用的参数CLK_DIV实现分频的功能;

hour_cnt,CLKmimute_cnt,CLKsecond_cnt,CLKhour_cnt,ledcom,seg7,sw8)

功能:基于视觉暂留知识,控制闹钟设置界面数码管的显示,并基于sw8的状态控制切换数码管屏显示;

思路:

A.复用分频模块clk_gen分频出一个时钟clk_div,周期约为0.1s;

B.(基于sw8的状态控制切换数码管屏显示)If语句判断sw8时候为高电平,如果是,则将CLKsecond_cnt、CLKmimute_cnt、CLKhour_cnt系列数据付给dis变量,如果不是则将second_cnt系统数据付给dis变量;细节处如cnt、ledcom、dis、case(cnt[2:0])等用法则跟seg_display模块的设计思路相同;

功能:在顶层模块调用,根据输入的时钟频率clk和时|分|秒位数据进行对应的加一计算和进位计算,并在溢出(分秒59加一溢出,时23加一溢出)时返回一个flag供顶层模块使用;

思路:同counter_60BCD模块的设计思路;

1.开机状态,初始为数字时钟界面,下图为数码管上规则地显示闪动的时钟,通过分频模块的参数调改可以改变其速度;

LCD屏上显示具体的日期(年月日)以及祝福语(Wish you happy/happiness——祝你幸福),开关状态为全数低电平:

2.上推sw8,令之输出为高电平,数码管即切换到闹钟设置界面:

4.上推sw2,令之输出为高电平,数码管闹钟界面上“分”数位持续加一(图中已加到04):

5.上推sw3,令之输出为高电平,数码管闹钟界面上“秒”数位持续加一(图中已加到05):

顶层文件,用于调用诸多要使用的模块;

管教分配的脚本文件,描述管教的分配;

LCD屏模块,实现LCD屏显示年月日以及祝福语的功能;

时钟模块的数码管显示的相关模块文件;

关于实现时钟界面显示的后台数字计算(相关变量的加一和进位 *** 作等)的文件;

时钟分频模块,用于实现各种参数频率的分频;

闹钟模块的数码管管显示的相关模块文件;

关于实现闹钟界面显示的后台数字计算(相关变量的加一和进位 *** 作等)的文件。

【实验目的】:

设计一个24小时制数字钟,要求能显示时,分,秒,并且可以手动调整时和分

【试验中所用器材】:

开发环境MAX—PLUSII,ZY11EDA13BE 试验系统, VHDL 语言.

【设计原理】

数字钟的主体是计数器,它记录并显示接收到的秒脉冲个数,其中秒和分为模60计数器,小时是模24计数器,分别产生3位BCD码。BCD码经译码,驱动后接数码管显示电路。

秒模60计数器的进位作为分模60计数器的时钟,分模60计数器的进位作为模24计数器的时钟。

为了实搜行现手动调整时间,在外部增加了setm(调整分),seth(调整时)按键,当虚蔽这两个按键为低电平时,电路正常计时,当为高电平时,分别调整分,时。同时在外部还增加了一个清零按键clr.和消抖动电路。

【单元模块设计部分】

消抖动电路关键部分

signal key_in1,key_in2:std_logic:='0'

begin

process(clk,key_in)

begin

if clk'event and clk='1' then

key_in1<=key_inkey_in2<=key_in1

if key_in='1' and key_in1='1' and key_in2='1' then key_out<='1'

else key_out<='0'

时序仿真图

模60计数器程序关键部分:

signal md_temp,mg_temp:std_logic_vector(3 downto 0)

begin

process(clk,clr)

begin

if clr='1' then

md_temp<="0000"mg_temp<="0000"

elsif set='1' then

md_temp<=setlmg_temp<=seth

elsif clk'event and clk='1' then

if md_temp="1001" then

md_temp<="0000"mg_temp<=mg_temp+'1'

else md_temp<=md_temp+'1'

end if

if md_temp="1001" and mg_temp="0101" then

md_temp<="0000"mg_temp<="0000"

秒时序仿真图

分时序仿真

分的清零和调整时间部分

模24计数器程序关键部分

signal hd_temp,hg_temp:std_logic_vector(3 downto 0)

begin

process(clk,clr,set,setl,seth)is

begin

if set='1' then hd_temp<=setlhg_temp<=seth

elsif clr='1' then hd_temp<="0000" hg_temp<="0000"

elsif clk'event and clk='1' then

if hg_temp="0010" and hd_temp="0011" then

hd_temp<="0000"hg_temp<="0000"

elsif hd_temp="1001" then

hg_temp<=hg_temp+'1' hd_temp<="0000"

else hd_temp<=hd_temp+'1'

end if

end if

end process

时时序仿真图

清零和调时

显示部分关键程序

process (sd,sg,md,mg,hd,hg)

begin

case sd is

when "0000" =>sl<="1111110"

when "0001" =>sl<="0110000"

when "0010" =>sl<="1101101"

when "0011"差漏州 =>sl<="1111001"

when "0100" =>sl<="0110011"

when "0101" =>sl<="1011011"

when "0110" =>sl<="1011111"

when "0111" =>sl<="1110000"

when "1000" =>sl<="1111111"

when "1001" =>sl<="1111011"

when others =>sl<="0000000"

end case

if clk_g'event and clk_g='1' then

if sel="101" then

sel<="000"

else sel<=sel+'1'

end if

end if

end process

process(sel,sd,sl,sg,sh,md,ml,mg,mh,hd,hl,hg,hh)

begin

case sel is

when"000"=>led<=sl

led_which<=sd

when"001"=>led<=sh

led_which<=sg

when"010"=>led<=ml

led_which<=md

when"011"=>led<=mh

led_which<=mg

when"100"=>led<=hl

led_which<=hd

when"101"=>led<=hh

led_which<=hg

when others=>led<="0000000"

led_which<="0000"

end case

仿真图

顶层文件关键程序

port(

clk,clk_g:in std_logic-----clk_g是用在数码管显示里面的信号

clr: in std_logic------clr=1时 清零

setm,seth:in std_logic---------setm为1时调分,seth为1时调时

setd,setg:in std_logic_vector(3 downto 0)----调整时间的时候,setd调整的是低位setg调整高位

led:out std_logic_vector(6 downto 0)

sel_out: out std_logic_vector(2 downto 0)

led_which: out std_logic_vector(3 downto 0))---输出的是秒分时的哪一个

begin

u1:de_shake port map (clk=>clk,key_in=>clr,key_out=>clro)

u2:de_shake port map (clk=>clk,key_in=>setm,key_out=>setmo)

u3:de_shake port map (clk=>clk,key_in=>seth,key_out=>setho)

u4:s60 port map (clk=>clk,clr=>clro,sd=>sdl,sg=>sgh,fenmaichong=>fenmaichongo)

u5:m60 port map (clk=>fenmaichongo,clr=>clro,md=>mdl,mg=>mgh,xiaoshimaichong=>xiaoshimaichongo,setl=>setd,seth=>setg,set=>setmo)

u6:h24 port map (clk=>xiaoshimaichongo,clr=>clro,hd=>hdl,hg=>hgh,set=>setho,setl=>setd,seth=>setg)

u7:led_xs port map (clk_g=>clk_g,sd=>sdl,sg=>sgh,md=>mdl,mg=>mgh,hd=>hdl,hg=>hgh,led=>led,sel_out=>sel_out,led_which=>led_which)

首先说芦伏一下我们需要的硬件,至少三个数码管,分别来显示时,分,秒。七个按键,其中包括校对按钮,设置闹钟按钮,确定按钮,向上,向下,如哗森向左,向右(这四个是在校对时钟的渣亩时候使用的)

然后说一下我们需要的模块。我们一共需要四个模块,分别是分频模块,键盘扫描状态控制模块,时分秒计数模块,显示模块。

这里面用到的状态机,三个状态,分别是正常状态,校对状态,设置闹钟状态。

有需要的话可以继续交流


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12491212.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2025-08-25
下一篇2025-08-25

发表评论

登录后才能评论

评论列表(0条)

    保存