FPGA数字时钟——详解

FPGA数字时钟——详解
FPGA数字时钟——详解

module clock04(//注:本次调试会出现黄色叹号警告,但不影响功能完美实现。

input wire clk,//系统50MHz时钟

input wire clr,//清零开关

input wire settime,//调时开关

input wire myclock,//设置我的闹钟开关

input wire closeclock,//关掉闹钟开关

input btn0,//四个调时按钮

input btn1,

input btn2,

input btn3,

output sled,//秒闪烁LED灯

output reg cled,//闹钟闪烁LED灯

output reg[6:0] duanxuan,//数码管段选

output reg[3:0] weixuan//数码管位选

);

reg[1:0]p;//位选数码管位置

reg[3:0]digit;//指代数码管将要显示的数字

reg[16:0]clktime;//位选刷新用

reg[26:0]cnt;//分频用

reg clk_out;//分频所得时钟信号

reg[3:0]ml;//以下为时钟:时分秒

reg[3:0]hl;

reg[3:0]mh;

reg[3:0]hh;

reg[5:0]s;

reg[3:0]cml; //以下为闹钟时分

reg[3:0]cmh;

reg[3:0]chl;

reg[3:0]chh;

initial//初始时间全部为12:30:00

begin

hh=1;

hl=2;

mh=3;

ml=0;

chh=1;

chl=2;

cmh=3;

cml=0;

s=0;

end

always@(posedge clk)//定义位选刷新时间参数

begin

clktime<=clktime+1;

end

always@(*)

begin

weixuan=4'b1111;//初始位选,数码管全暗

p<=clktime[16:15];//定义位置代数p为参数最高两位

weixuan[p]=0;//选中的p位低电平点亮数码管

if(myclock==1)//if else语句决定位选状态为闹钟时间or时钟时间begin

case(p)//p有4种情况

0:digit<=chh[3:0];//定义digit指代所要显示的数字

1:digit<=chl[3:0];

2:digit<=cmh[3:0];

3:digit<=cml[3:0];

default:digit<=cml[3:0];

endcase

end

else

begin

case(p)//p有4种情况

0:digit<=hh[3:0];//定义digit指代所要显示的数字

1:digit<=hl[3:0];

2:digit<=mh[3:0];

3:digit<=ml[3:0];

default:digit<=ml[3:0];

endcase

end

case(digit)//十六进制数字段选编码

0:duanxuan=7'b0000001;

1:duanxuan=7'b1001111;

2:duanxuan=7'b0010010;

3:duanxuan=7'b0000110;

4:duanxuan=7'b1001100;

5:duanxuan=7'b0100100;

6:duanxuan=7'b0100000;

7:duanxuan=7'b0001111;

8:duanxuan=7'b0000000;

9:duanxuan=7'b0000100;

'hA:duanxuan=7'b0001000;

'hB:duanxuan=7'b1100000;

'hC:duanxuan=7'b1100001;

'hD:duanxuan=7'b1000010;

'hE:duanxuan=7'b0110000;

'hF:duanxuan=7'b0111000;

default:duanxuan=7'b0000001;

endcase

end

always@(posedge clk or posedge clr)//对系统50MHz时钟进行分频,期间进行调时、计时begin

if(clr==1)//首先判断是否清零

begin

cnt<=0;

ml<=0;

mh<=0;

hl<=0;

hh<=0;

chh<=0;

chl<=0;

cmh<=0;

cml<=0;

s<=0;

end

else if(cnt==24999999)//分频中间步骤

begin

clk_out=~clk_out;//定义分频所要得到的1Hz(1秒)时钟信号

cnt<=cnt+1;

end

else if(cnt==1||cnt==25000001)//在所得时钟信号翻转后(每0.5秒)判断是否进行调时操作

begin//定义四个调时按键

cnt<=cnt+1;

if(settime==1)

begin

if(btn0)//分钟-

begin

ml<=ml-1;

if(ml==0)

begin

ml<=9;

mh<=mh-1;

end

if(mh==0&&ml==0)//分钟从00减到59,小时减1

begin

ml<=9;

hl<=hl-1;

if(hl==0)

begin

hl<=9;

hh<=hh-1;

end

if(hl==0&&hh==0)//时钟为24小时制

begin

hh<=2;

hl<=3;

end

end

end

if(btn1)//分钟+

begin

ml<=ml+1;

if(ml==9)

begin

ml<=0;

mh<=mh+1;

end

if(mh==5&&ml==9)//分钟从59加到00,小时加1 begin

ml<=0;

mh<=0;

hl<=hl+1;

if(hl==9)

begin

hl<=0;

hh<=hh+1;

end

if(hl==3&&hh==2)//24:00显示为00:00

begin

hh<=0;

hl<=0;

end

end

end

if(btn2)//小时-

begin

hl<=hl-1;

if(hl==0)

begin

hh<=hh-1;

end

if(hh==0&&hl==0)//00:00减到23:59

begin

hl<=3;

hh<=2;

end

end

if(btn3)//小时+

begin

hl<=hl+1;

if(hl==9)

begin

hl<=0;

hh<=hh+1;

end

if(hh==2&&hl==3)//23:59加到00:00

begin

hl<=0;

hh<=0;

end

end

end

end

else if(cnt==12500000||cnt==37500000)//在四分之一秒和四分之三秒时刻判断是否进行闹钟时间设置操作

begin

cnt<=cnt+1;

if(myclock==1)

begin

if(btn0)//闹钟时间设置分-

begin

cml<=cml-1;

if(cml==0)

begin

cml<=9;

cmh<=cmh-1;

end

if(cmh==0)

begin

cmh<=5;

cml<=9;//分的加减不需要关联时的加减

end

end

if(btn1)//闹钟时间分钟+

begin

cml<=cml+1;

if(cml==9)

begin

cml<=0;

cmh<=cmh+1;

end

if(cmh==5&&cml==9)

begin

cmh<=0;

cml<=0;

end

end

if(btn2)//闹钟时间设置小时-

begin

chl<=chl-1;

if(chl==0)

begin

chl<=9;

chh<=chh-1;

end

if(chh==0&&chl==0)

begin

chh<=2;

chl<=3;

end

end

if(btn3)//闹钟时间设置小时+

begin

chl<=chl+1;

if(chl==9)

begin

chl<=0;

chh<=chh+1;

end

if(chh==2&&chl==3)

begin

chh<=0;

chl<=0;

end

end

end

end

else if(cnt==49999999)

begin

cnt<=0;

clk_out=~clk_out;//得到1Hz时钟信号clk_out

s<=s+1;//每1秒s加1

if(s==59)//时钟计时模块

begin

s<=0;

ml<=ml+1;

if(ml==9)

begin

ml<=0;

mh<=mh+1;

end

if(mh==5&&ml==9)

begin

ml<=0;

mh<=0;

hl<=hl+1;

if(hl==9)

begin

hl<=0;

hh<=hh+1;

end

if(hl==3&&hh==2)

begin

hh<=0;

hl<=0;

end

end

end

end

else

cnt<=cnt+1;//50000000倍分频到此结束

end

always@(*)

begin

if(chh==hh&&chl==hl&&cmh==mh&&cml==ml&&s==0)//在时钟与闹钟相同的0秒点亮cled

cled<=1;

if(closeclock==1)//直到按下关闭闹钟的开关

cled<=0;

end

assign sled=clk_out;//将所得1Hz时钟信号输入给LED灯闪烁endmodule

相关主题
相关文档
最新文档