stopwatch

更新时间:2022-12-29 02:15:08 阅读: 评论:0


2022年12月29日发(作者:前缀)

实际要求:

设计二0.01秒~1小时的秒表设计

1、设计一个能显示0.01秒~1小时的秒表。

2、具有启动/停止按键和清零按键。

3、利用GW48-PK2中提提供的3MHz信号做为时钟信号。

4、计数结果在GW48-PK2中提供的数码管中显示。

功能实现:

基本功能:

1、设计一个能显示0.01秒~1小时的秒表。

2、具有启动/停止按键和清零按键。

3、利用GW48-PK2中提提供的3MHz信号做为时钟信号。

4、计数结果在GW48-PK2中提供的数码管中显示。

提高功能:

5.计时时间在0.01秒~24小时范围内

6.增加了一个功能按键,可以在单道和双道模式之间切换

7.可以双道计时,

8.在双道模式显示时,可以切换两道的计时结果

程序思路:

本程序的输入为三个按键,分别为功能按键(SW1)、启动停止按键(SW2)

和清零按键(SW3);输出为八位数码管的时间显示,分别显示小时、分钟、秒

和百分秒。

本程序有两个模式:单道模式(mode0)和双道模式(mode1)。

单道模式(mode0):按SW2按键时,启动秒表计时,以后每按一次秒表就

在启动和停止之间切换,同时数码管会显示计时器中的数值;当按下SW3键时,

计数器和显示都清零,并且停止计数。

双道模式(mode1):在单道模式(mode0)下按一次SW1键就切换到双道

模式(mode1)。在双道模式(mode1)下,第一次按SW2按键时,启动秒表计

时;第二次按SW2按键时,其中一道结束计时,并把此时的时间按存储起来,

同时秒表还在继续计时;第三次按SW2按键时,秒表停止计时,并把此时的时

间存储起来,表示另一道结束;以后每按一次SW2按键数码管输出显示就在两

道计时结果之间切换;按下SW3键时计数器清零,数码管显示清零;此时按下

SW1键可以切换到单道模式(mode0)。

本程序将各个功能单元用不同的模块写出来,一共有个模块,分别是顶层模

块、分频模块、模式转换模块、按键处理模块、时间计数主模块(包括小时计时

模块、分钟计时模块、秒计时模块和百分秒计时模块)、单双道时间数据选择模

块、时间显示数据选择模块和模式输出显示模块。

各个模块的详细功能已在程序中注释。

程序实现:

//顶层模块

//用于连接各个底层模块

modulestopwatch_mode2(clk_3M,SW1,SW2,SW3,

disp_ms_l,disp_ms_h,

disp_c_l,disp_c_h,

disp_min_l,disp_min_h,

disp_hour_l,disp_hour_h,

mode_out);

inputclk_3M;//系统时钟

inputSW1,SW2,SW3;//按键

outputmode_out;//模式输出,用于模式显示

output[3:0]disp_ms_l,disp_ms_h;//输出至数码管显示

output[3:0]disp_c_l,disp_c_h;

output[3:0]disp_min_l,disp_min_h;

output[3:0]disp_hour_l,disp_hour_h;

wireclk_3M;

wireSW1,SW2,SW3;

wireclk_100;

wiretime_EN;

wiremode;

wire[3:0]ms_l,ms_h,c_l,c_h,min_l,min_h,hour_l,hour_h;

wire[3:0]ms_l_0,ms_h_0,c_l_0,c_h_0,min_l_0,min_h_0,hour_l_0,hour_h_0;

wire[3:0]ms_l_1,ms_h_1,c_l_1,c_h_1,min_l_1,min_h_1,hour_l_1,hour_h_1;

wire[3:0]disp_ms_l,disp_ms_h,disp_c_l,disp_c_h,

disp_min_l,disp_min_h,disp_hour_l,disp_hour_h;

wireflag_ds;

wireflag_st0;

wireflag_st1;

//分频模块,把3MHZ的时钟分频为100HZ用于计数器计数

f_divm1(.clk_3M(clk_3M),

.clr(SW3),

.clk_100(clk_100));

//模式转换模块

maincontrolm2(.SW1(SW1),.mode(mode));

//按键处理模块

SW_ctrlm3(.mode(mode),

.clr(SW3),.SW_2(SW2),.flag_st(time_EN),

.flag_ds(flag_ds),.flag_st0(flag_st0),.flag_st1(flag_st1));

//时间计数主模块

time_counter_mainm4(.clk_100(clk_100),.clr(SW3),.time_EN(time_EN),

.ms_l(ms_l),.ms_h(ms_h),.c_l(c_l),.c_h(c_h),

.min_l(min_l),.min_h(min_h),.hour_l(hour_l),.hour_h(hour_h));

//单双道时间数据选择模块

doublem5(.mode(mode),.flag_st0(flag_st0),.flag_st1(flag_st1),

.ms_l(ms_l),.ms_h(ms_h),.c_l(c_l),.c_h(c_h),

.min_l(min_l),.min_h(min_h),.hour_l(hour_l),.hour_h(hour_h),

.ms_l_0(ms_l_0),.ms_h_0(ms_h_0),.c_l_0(c_l_0),.c_h_0(c_h_0),

.min_l_0(min_l_0),.min_h_0(min_h_0),.hour_l_0(hour_l_0),.hour_h_0(hour_h_0),

.ms_l_1(ms_l_1),.ms_h_1(ms_h_1),.c_l_1(c_l_1),.c_h_1(c_h_1),

.min_l_1(min_l_1),.min_h_1(min_h_1),.hour_l_1(hour_l_1),.hour_h_1(hour_h_1));

//时间显示数据选择模块

disp_muxm6(.mode(mode),.flag_ds(flag_ds),.ms_l_0(ms_l_0),.ms_h_0(ms_h_0),

.c_l_0(c_l_0),.c_h_0(c_h_0),.min_l_0(min_l_0),

.min_h_0(min_h_0),.hour_l_0(hour_l_0),.hour_h_0(hour_h_0),

.ms_l_1(ms_l_1),.ms_h_1(ms_h_1),.c_l_1(c_l_1),.c_h_1(c_h_1),

.min_l_1(min_l_1),.min_h_1(min_h_1),.hour_l_1(hour_l_1),.hour_h_1(hour_h_1),

.disp_ms_l(disp_ms_l),.disp_ms_h(disp_ms_h),.disp_c_l(disp_c_l),

.disp_c_h(disp_c_h),.disp_min_l(disp_min_l),

.disp_min_h(disp_min_h),.disp_hour_l(disp_hour_l),.disp_hour_h(disp_hour_h));

//模式输出显示模块

mode_outputm7(.mode(mode),.mode_out(mode_out));

endmodule

//********************************************************************

//分频模块

//用计数器实现分频

//把3MHZ的时钟分频为100HZ用于计数器计数输入

modulef_div(clk_3M,clr,clk_100);

inputclk_3M;

inputclr;

outputclk_100;

regclk_100;

reg[14:0]cnt_div;

always@(podgeclk_3M)begin

if(clr)begin

clk_100<=1'b0;

cnt_div<=14'b0;

end

elif(cnt_div==15000)begin

clk_100<=1'b0;

cnt_div<=cnt_div+15'b00_0000_0000_0001;

end

elif(cnt_div==30000)begin

clk_100<=1'b1;

cnt_div<=15'b0;

end

elbegin

cnt_div<=cnt_div+15'b00_0000_0000_0001;

end

end

endmodule

//********************************************************************

//模式转换模块

//本程序一共有两个模式,分别是单道计时和双道计时

//每按一次SW1键就切换一次模式

modulemaincontrol(SW1,mode);

inputSW1;

outputmode;

regmode;

always@(podgeSW1)

begin

if(mode==1'b1)

mode<=1'b0;

el

mode<=1'b1;

end

endmodule

//********************************************************************

//按键处理模块

//接收按键,输出标志位

//通过标志位实现双道时的开始计时、停止计时和双道计时结果的显示

moduleSW_ctrl(mode,clr,SW_2,flag_st,flag_ds,flag_st0,flag_st1);

inputmode;

inputSW_2;

inputclr;

outputflag_st;//flag_st=1,start;flag_st=0,stop;

outputflag_ds;//flag_clr=1,clear;flag_clr=0,noaction;

outputflag_st0,flag_st1;//单双道停止控制标志位

regflag_st,flag_ds;

reg[1:0]flag_one;//双道模式时用于记忆SW2按键的次数

regflag_st0,flag_st1;

always@(podgeSW_2orpodgeclr)

begin

if(clr)

begin

flag_st<=1'b0;flag_st0<=1'b0;flag_st1<=1'b0;

flag_one<=2'b0;flag_ds<=1'b0;

end

elca(mode)

1'b0:

begin

flag_st<=~flag_st;flag_ds<=1'b0;

end

1'b1:

begin

ca(flag_one)

2'b00:

begin

flag_st<=1'b1;flag_one<=flag_one+2'b01;

flag_ds<=1'b0;

end

2'b01:

begin

flag_st1<=1'b1;//1daostop

flag_one<=flag_one+2'b01;flag_ds<=1'b0;

end

2'b10:

begin

flag_st0<=1'b1;//0daostop

flag_one<=flag_one+2'b01;flag_ds<=1'b0;

end

2'b11:

begin

flag_one<=flag_one;flag_ds<=~flag_ds;

end

endca

if(flag_st0||flag_st1)flag_st<=1'b0;

end

default:

begin

flag_st<=1'b0;flag_ds<=1'b0;

end

endca

end

endmodule

//********************************************************************

//时间计数主模块

//用于计时,可以通过time_EN控制启停

//底层四个计时模块为串行方式相连,百分秒、秒和分钟计时单个子模块各有一

//个EO计数溢出标志,当本模块记满时会输出一个正脉冲给下一个模块使

//下一个模块计数加一,其他以此类推

module

time_counter_main(clk_100,clr,time_EN,ms_l,ms_h,c_l,c_h,min_l,min_h,hour_l,

hour_h);

inputclk_100;

inputclr;

inputtime_EN;

output[3:0]ms_l,ms_h;

output[3:0]c_l,c_h;

output[3:0]min_l,min_h;

output[3:0]hour_l,hour_h;

wirems_EO;

wirec_EO;

wiremin_EO;

ms_counteri1(.clk(clk_100),.clr(clr),.EN(time_EN),.EO(ms_EO),

.ms_l(ms_l),.ms_h(ms_h));

c_counteri2(.clk(ms_EO),.clr(clr),.EN(time_EN),.EO(c_EO),

.c_l(c_l),.c_h(c_h));

min_counteri3(.clk(c_EO),.clr(clr),.EN(time_EN),.EO(min_EO),

.min_l(min_l),.min_h(min_h));

hour_counteri4(.clk(min_EO),.clr(clr),.EN(time_EN),

.hour_l(hour_l),.hour_h(hour_h));

endmodule

//********************************************************************

//百分秒计时模块

modulems_counter(EN,clk,clr,ms_h,ms_l,EO);

inputclk,clr,EN;

output[3:0]ms_h;

output[3:0]ms_l;

outputEO;

reg[3:0]ms_h;

reg[3:0]ms_l;

regEO;

always@(podgeclkorpodgeclr)

begin

if(clr)

begin

ms_h<=4'b0;ms_l<=4'b0;EO<=1'b0;

end

el

begin

if(EN==1'b1)

begin

if(ms_l<4'b1001)

begin

ms_l<=ms_l+4'b0001;

end

el

begin

EO<=1'b0;ms_l<=4'b0;

if(ms_h<4'b1001)

ms_h<=ms_h+4'b1;

el

begin

ms_h<=4'b0;EO<=1'b1;

end

end

end

end

end

endmodule

//********************************************************************

//秒计时模块

modulec_counter(EN,clk,clr,c_h,c_l,EO);

inputclk,clr,EN;

output[3:0]c_h;

output[3:0]c_l;

outputEO;

reg[3:0]c_h;

reg[3:0]c_l;

regEO;

always@(podgeclkorpodgeclr)

begin

if(clr)

begin

c_h<=4'b0;c_l<=4'b0;EO<=1'b0;

end

el

begin

if(EN==1'b1)

begin

if(c_l<4'b1001)

begin

c_l<=c_l+4'b0001;

end

el

begin

EO<=1'b0;c_l<=4'b0;

if(c_h<4'b0101)

c_h<=c_h+4'b1;

el

begin

c_h<=4'b0;EO<=1'b1;

end

end

end

end

end

endmodule

//********************************************************************

//分钟计时模块

modulemin_counter(EN,clk,clr,min_h,min_l,EO);

inputclk,clr,EN;

output[3:0]min_h;

output[3:0]min_l;

outputEO;

reg[3:0]min_h;

reg[3:0]min_l;

regEO;

always@(podgeclkorpodgeclr)

begin

if(clr)

begin

min_h<=4'b0;min_l<=4'b0;EO<=1'b0;

end

el

begin

if(EN==1'b1)

begin

if(min_l<4'b1001)

begin

min_l<=min_l+4'b0001;

end

el

begin

EO<=1'b0;min_l<=4'b0;

if(min_h<4'b0101)

min_h<=min_h+4'b1;

el

begin

min_h<=4'b0;EO<=1'b1;

end

end

end

end

end

endmodule

//********************************************************************

//小时计时模块

modulehour_counter(EN,clk,clr,hour_h,hour_l);

inputclk,clr,EN;

output[3:0]hour_h;

output[3:0]hour_l;

reg[3:0]hour_h;

reg[3:0]hour_l;

always@(podgeclkorpodgeclr)

begin

if(clr)

begin

hour_h<=4'b0;hour_l<=4'b0;

end

el

begin

if(EN==1'b1)

begin

if((hour_l<4'b1001)&&(hour_h<4'b0010))

hour_l<=hour_l+4'b0001;

elif((hour_l<4'b0011)&&(hour_h==4'b0010))

hour_l<=hour_l+4'b0001;

el

begin

hour_l<=4'b0;

if(hour_h<4'b0010)

hour_h<=hour_h+4'b0001;

el

begin

hour_h<=4'b0;

end

end

end

end

end

endmodule

//********************************************************************

//单双道时间数据选择模块

//输入为计时主模块的输出,输出为单双道时间的数据

//根据mode,flag_st0,flag_st1输入来判断单双道计时存储

moduledouble(mode,flag_st0,flag_st1,ms_l,ms_h,c_l,c_h,

min_l,min_h,hour_l,hour_h,ms_l_0,ms_h_0,c_l_0,c_h_0,

min_l_0,min_h_0,hour_l_0,hour_h_0,

ms_l_1,ms_h_1,c_l_1,c_h_1,

min_l_1,min_h_1,hour_l_1,hour_h_1);

input[3:0]ms_l,ms_h;

input[3:0]c_l,c_h;

input[3:0]min_l,min_h;

input[3:0]hour_l,hour_h;

inputflag_st0,flag_st1;

inputmode;

output[3:0]ms_l_0,ms_h_0;

output[3:0]c_l_0,c_h_0;

output[3:0]min_l_0,min_h_0;

output[3:0]hour_l_0,hour_h_0;

output[3:0]ms_l_1,ms_h_1;

output[3:0]c_l_1,c_h_1;

output[3:0]min_l_1,min_h_1;

output[3:0]hour_l_1,hour_h_1;

reg[3:0]ms_l_0,ms_h_0;//0daoflag_ds=0;

reg[3:0]c_l_0,c_h_0;

reg[3:0]min_l_0,min_h_0;

reg[3:0]hour_l_0,hour_h_0;

reg[3:0]ms_l_1,ms_h_1;//1daoflag_ds=1;

reg[3:0]c_l_1,c_h_1;

reg[3:0]min_l_1,min_h_1;

reg[3:0]hour_l_1,hour_h_1;

always@(*)

begin

ca(mode)

1'b0:

begin

ms_l_0<=ms_l;ms_h_0<=ms_h;

c_l_0<=c_l;c_h_0<=c_h;

min_l_0<=min_l;min_h_0<=min_h;

hour_l_0<=hour_l;hour_h_0<=hour_h;

ms_l_1<=4'b0;ms_h_1<=4'b0;

c_l_1<=4'b0;c_h_1<=4'b0;

min_l_1<=4'b0;min_h_1<=4'b0;

hour_l_1<=4'b0;hour_h_1<=4'b0;

end

1'b1:

begin

ca({flag_st0,flag_st1})

2'b00:

begin

ms_l_0<=ms_l;ms_h_0<=ms_h;

c_l_0<=c_l;c_h_0<=c_h;

min_l_0<=min_l;min_h_0<=min_h;

hour_l_0<=hour_l;hour_h_0<=hour_h;

ms_l_1<=ms_l;ms_h_1<=ms_h;

c_l_1<=c_l;c_h_1<=c_h;

min_l_1<=min_l;min_h_1<=min_h;

hour_l_1<=hour_l;hour_h_1<=hour_h;

end

2'b01:

begin

ms_l_0<=ms_l;ms_h_0<=ms_h;

c_l_0<=c_l;c_h_0<=c_h;

min_l_0<=min_l;min_h_0<=min_h;

hour_l_0<=hour_l;hour_h_0<=hour_h;

ms_l_1<=ms_l_1;ms_h_1<=ms_h_1;

c_l_1<=c_l_1;c_h_1<=c_h_1;

min_l_1<=min_l_1;min_h_1<=min_h_1;

hour_l_1<=hour_l_1;hour_h_1<=hour_h_1;

end

2'b10:

begin

ms_l_0<=ms_l_0;ms_h_0<=ms_h_0;

c_l_0<=c_l_0;c_h_0<=c_h_0;

min_l_0<=min_l_0;min_h_0<=min_h_0;

hour_l_0<=hour_l_0;hour_h_0<=hour_h_0;

ms_l_1<=ms_l;ms_h_1<=ms_h;

c_l_1<=c_l;c_h_1<=c_h;

min_l_1<=min_l;min_h_1<=min_h;

hour_l_1<=hour_l;hour_h_1<=hour_h;

end

2'b11:

begin

ms_l_0<=ms_l_0;ms_h_0<=ms_h_0;

c_l_0<=c_l_0;c_h_0<=c_h_0;

min_l_0<=min_l_0;min_h_0<=min_h_0;

hour_l_0<=hour_l_0;hour_h_0<=hour_h_0;

ms_l_1<=ms_l_1;ms_h_1<=ms_h_1;

c_l_1<=c_l_1;c_h_1<=c_h_1;

min_l_1<=min_l_1;min_h_1<=min_h_1;

hour_l_1<=hour_l_1;hour_h_1<=hour_h_1;

end

endca

end

endca

end

endmodule

//********************************************************************

//时间显示数据选择模块

//选择输出显示的数据,主要用于双道切换模式

//根据SW_ctrl模块的输出标志flag_ds来判断是单道计时输出还是双道计时输出

//flag_ds=0时,是单道输出

//flag_ds=1时,是双道中的另一个道输出

moduledisp_mux(mode,flag_ds,ms_l_0,ms_h_0,c_l_0,c_h_0,//mode0

min_l_0,min_h_0,hour_l_0,hour_h_0,

ms_l_1,ms_h_1,c_l_1,c_h_1,//mode1(sdao)

min_l_1,min_h_1,hour_l_1,hour_h_1,

disp_ms_l,disp_ms_h,disp_c_l,disp_c_h,

disp_min_l,disp_min_h,disp_hour_l,disp_hour_h);

inputflag_ds;

inputmode;

input[3:0]ms_l_0,ms_h_0;

input[3:0]c_l_0,c_h_0;

input[3:0]min_l_0,min_h_0;

input[3:0]hour_l_0,hour_h_0;

input[3:0]ms_l_1,ms_h_1;

input[3:0]c_l_1,c_h_1;

input[3:0]min_l_1,min_h_1;

input[3:0]hour_l_1,hour_h_1;

output[3:0]disp_ms_l,disp_ms_h;

output[3:0]disp_c_l,disp_c_h;

output[3:0]disp_min_l,disp_min_h;

output[3:0]disp_hour_l,disp_hour_h;

reg[3:0]ms_ll,ms_hh;

reg[3:0]c_ll,c_hh;

reg[3:0]min_ll,min_hh;

reg[3:0]hour_ll,hour_hh;

assigndisp_ms_l=ms_ll;

assigndisp_ms_h=ms_hh;

assigndisp_c_l=c_ll;

assigndisp_c_h=c_hh;

assigndisp_min_l=min_ll;

assigndisp_min_h=min_hh;

assigndisp_hour_l=hour_ll;

assigndisp_hour_h=hour_hh;

always@(*)

begin

ca(mode)

1'b0:

begin

ms_ll=ms_l_0;ms_hh=ms_h_0;

c_ll=c_l_0;c_hh=c_h_0;

min_ll=min_l_0;min_hh=min_h_0;

hour_ll=hour_l_0;hour_hh=hour_h_0;

end

1'b1:

begin

if(flag_ds==1'b1)

begin

ms_ll=ms_l_1;ms_hh=ms_h_1;

c_ll=c_l_1;c_hh=c_h_1;

min_ll=min_l_1;min_hh=min_h_1;

hour_ll=hour_l_1;hour_hh=hour_h_1;

end

el

begin

ms_ll=ms_l_0;ms_hh=ms_h_0;

c_ll=c_l_0;c_hh=c_h_0;

min_ll=min_l_0;min_hh=min_h_0;

hour_ll=hour_l_0;hour_hh=hour_h_0;

end

end

endca

end

endmodule

//********************************************************************

//模式输出显示模块

//用于显示当前的模式状态,输出连接到LED灯,灯灭为单道模式(mode0)

//灯亮为双道模式(mode1)

modulemode_output(mode,mode_out);

inputmode;

outputmode_out;

assignmode_out=mode;

endmodule

本文发布于:2022-12-29 02:15:08,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/50478.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:snapdragon
标签:stopwatch
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图