基于FPGA技术的数字时钟万年历设计

基于FPGA技术的数字时钟万年历设计,第1张

【实验目的】:

设计一个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)

如果你有兴返慧趣,我把细节都拦瞎给你

module top(

input clk,

input rst,

output CE,

output SCLK,

inout IO,

output CS,

output AO,

output SCL,

output SDI

)

reg read_ds1302_start

wire read_ds1302_done

wire[23:0] read_ds1302_time

read_ds1302_time U1 (clk,rst,read_ds1302_start,read_ds1302_done,read_ds1302_time,CE,SCLK,IO)

reg write_lcd_start

wire write_lcd_done

write_lcd_time U2 (clk,rst,CS,AO,SCL,SDI,write_lcd_start,write_lcd_done,read_ds1302_time)

parameter T100ms = 21'd2_000_000

reg[20:0] count

always@(posedge clk,negedge rst)

if(!rst)

count <= 0

else if(count <T100ms)

count <= count + 21'd1

else

count <= 0

reg[1:0] i

reg[3:0] temp

always@(posedge clk,negedge rst)

if(!rst)

begin

read_ds1302_start <= 0

write_lcd_start <= 0

i <= 0

end

else

case(i)

2'd0: if(count == T100ms)

begin

read_ds1302_start <= 1

i <= i + 2'd1

end

2'd1: begin

read_ds1302_start <= 0

if(read_ds1302_done)

if(read_ds1302_time[3:0] != temp)

begin

temp <= read_ds1302_time[3:0]

write_lcd_start <= 1

i <= i + 2'd1

end

else

i <= 0

end

2'd2: begin

write_lcd_start <简世空= 0

if(write_lcd_done)

i <= 0

end

endcase

endmodule


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

原文地址: http://outofmemory.cn/yw/12558219.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存