2019-02-18 回答
去年做过这个,给你我的程序你参考看看,能调的通。
1.设计要求
设计一个数字时钟,要求用数码管分别显示时、分、秒的计数,同时可以进行时间设置,并且设置的时间显示要求闪烁。
2.设计原理
计数器在正常工作下是对1hz的频率计数,在调整时间状态下是对需要调整的时间模块进行计数;控制按键用来选择是正常计数还是调整时间并决定调整时、分、秒;当置数键按下时,表示相应的调整块要加一,如果对小时调整时,显示时间的led数码管将闪烁且当置数按键按下时,相应的小时显示要加一。显示时间的led数码管均用动态扫描显示来实现。其原理图如9-7-1所示。
module clock(seg7,scan,clk,clr,en,mode,inc);
output[6:0] seg7;
output[5:0] scan;
input clk; //时钟输入20mhz
input clr; //清零端
input en; //暂停信号
input mode; //控制信号,用于选择模式
input inc; //置数信号
reg[6:0] seg7; //7段显示控制信号(abcdefg)
reg[5:0] scan; //数码管地址选择信号
reg[1:0] state; //定义4种状态
reg[3:0] qhh,qhl,qmh,qml,qsh,qsl; //小时、分、秒的高位和低位
reg[3:0] data;
reg[2:0] cnt; //扫描数码管的计数器
reg clk1khz,clk1hz,clk2hz; //1khz、1hz、2hz的分频信号
reg[2:0] blink; //闪烁信号
reg inc_reg;
reg[7:0] sec,min;
reg[7:0] hour;
parameter state0=2'b00,state1=2'b01,state2=2'b10,state3=2'b11;
reg[13:0] count1;
reg[8:0] count2;
reg[8:0] count3;
//-----------------------------1khz分频,用于扫描数码管地址--------
always @(posedge clk)
begin
if(count1=='d10000)
begin clk1khz<=~clk1khz;count1<=0; end
else
begin count1<=count1+1; end
end
//---------------------- 1hz分频,用于计时-----------------------------
always @(posedge clk1khz)
begin
if(count2=='d500)
begin clk1hz<=~clk1hz;count2<=0; end
else
begin count2<=count2+1; end
if(count3=='d250) //2hz分频,用于数码管闪烁
begin clk2hz<=~clk2hz;count3<=0; end
else
begin count3<=count3+1; end
if(cnt=='d5) //数码管动态扫描计数
begin cnt<='d0; end
else
begin cnt<=cnt+1; end
end
//------------------------- 模式转换-------------------------
always @(posedge mode)
begin
if(clr)
begin state<=state0; end
else
begin state<=state+1; end
end
//-------------------------状态控制-----------------------------
always @(posedge clk1hz)
begin
if(en)
begin hour<=hour;
min<=min;
sec<=sec;
end
else if(clr)
begin hour<=0;
min<=0;
sec<=0;
end
else
begin
case(state)
state0:begin //模式0,正常计时
if(sec==8'd59)
begin sec<='d0;
if(min==8'd59)
begin min<='d0;
if(hour==8'd23)
begin hour<=8'd0; end
else
begin hour<=hour+1; end
end
else
begin min<=min+1; end
end
else
begin sec<=sec+1; end
end
state1:begin //模式1,设定小时时间
if(inc)
begin
if(!inc_reg)
begin inc_reg<=1;
if(hour==8'd23)
begin hour<=8'd0; end
else
begin hour<=hour+1; end
end
end
else
begin inc_reg<=0; end
end
state2:begin //模式2,设定分钟时间
if(inc)
begin
if(!inc_reg)
begin inc_reg<=1;
if(min==8'd59)
begin min<=8'd0; end
else
begin m