多功能数字时钟

1.功能介绍
该时钟具有时、分、秒计时的电子钟电路,24小时制计时。能够准确计时,以数字的形式显示时、分、秒;具有分、时校正功能,校正输出脉冲频率为1HZ;具有仿广播电台整点报时功能,即每逢59分51秒,53秒,57秒时,发出四声500HZ低音,在59分59秒时,发出1声1kHZ高音,他们的持续时间均为1秒;具有定时闹钟功能,且最长闹钟时间为1分钟。
2.模块介绍


图 1  整体框图


图 2  clk模块

(1)clk模块
对系统时钟clk进行分频,产生1HZ、500HZ、1kHZ的信号。
文件:clk.v
module clk
(
clk,rst_n,
clk_1KHZ,clk_500HZ,
clk_1HZ
);
input clk,rst_n;
output clk_1KHZ,clk_500HZ,clk_1HZ;

reg _1KHZ,_500HZ,_1HZ;
parameter F1Khz = 17'd49_999;
//parameter F1Khz = 17'd4;
reg [ 15:0 ]cnt1;//1khz
always @( posedge clk or negedge rst_n )
if( !rst_n ) begin
cnt1 <= 'd0;
_1KHZ <= 'd0; end
else if( cnt1 == F1Khz ) begin
cnt1 <= 'd0;
_1KHZ <= ~_1KHZ; end
else
cnt1 <= cnt1 + 1'b1;

parameter F500hz = 17'd99_999;
//parameter F500hz = 17'd6;
reg [ 16:0 ]cnt2;//500hz
always @( posedge clk or negedge rst_n )
if( !rst_n ) begin
cnt2 <= 'd0;
_500HZ <= 'd0; end
else if( cnt2 == F500hz ) begin
cnt2 <= 'd0;
_500HZ <= ~_500HZ; end
else
cnt2 <= cnt2 + 1'b1;

//parameter F1hz = 32'd29_999_999;
parameter F1hz = 32'd49_999_999;
reg [ 31:0 ]cnt3;//1hz
always @( posedge clk or negedge rst_n )
if( !rst_n ) begin
cnt3 <= 'd0;
_1HZ <= 'd0; end
else if( cnt3 == F1hz ) begin
cnt3 <= 'd0;
_1HZ <= ~_1HZ; end
else
cnt3 <= cnt3 + 1'b1;

assign clk_1KHZ = _1KHZ;
assign clk_500HZ = _500HZ;
assign clk_1HZ = _1HZ;
endmodule


图3  clkock_top模块

图4  clock_top内部模块

图5  counter60模块
(2)clock_top
clock_top模块由小时计数器、分钟计数器、秒计数器组成,而分、秒(10进制)计数器由模6和模10计数器组成。
文件:clock_top.v
module clock_top
(
clk_1HZ,rst_n,
AdjMin,AdjHr,
cHour,cMinute,cSecond
);
input clk_1HZ;
input rst_n;
input AdjMin,AdjHr;

output [ 7:0 ]cHour,cMinute,cSecond;

wire clk1,clk2;
supply1 Vdd;
//Second
counter60 U1
(
.clk( clk_1HZ ),
.rst_n( rst_n ),
.En( Vdd ),
.Timer( cSecond )
);

//Minute
counter60 U2
(
.clk( ~clk1 ),
.rst_n( rst_n ),
.En( Vdd ),
.Timer( cMinute )
);

//Hour
counter24 U3
(

.clk( ~clk2 ),
.rst_n( rst_n ),
.TimerH( cHour[ 7:4 ] ),
.TimerL( cHour[ 3:0 ] ),
.En( Vdd )
);
assign clk1 = AdjMin ? clk_1HZ: ( cSecond == 8'h59 );
assign clk2 = AdjHr ? clk_1HZ: ( cSecond == 8'h59 && cMinute == 8'h59 );
endmodule

文件:counter60.v
module counter60
(
clk,rst_n,
En,Timer
);
input clk,rst_n;
input En;
output [ 7:0 ]Timer;
//wire clk2;
wire ENP;
counter6 U1
(
.clk( clk ),
.rst_n( rst_n ),
.q( Timer[ 7:4 ] ),
.En( ENP )
);

counter10 U2
(
.clk( clk ),
.rst_n( rst_n ),
.q( Timer[ 3:0 ] ),
.En( En )
);
assign ENP = ( Timer[ 3:0 ] == 4'h9 )?1:0;
endmodule

文件:counter24.v
module counter24
( clk,rst_n,
TimerH,TimerL,
En
);
input clk,rst_n;
input En; //En=1 valid
output [ 3:0 ]TimerH,TimerL;

reg [ 3:0 ]rTimerH,rTimerL;
always @( posedge clk or negedge rst_n )
if( !rst_n ) begin
rTimerH <= 'd0;
rTimerL <= 'd0; end
else if( En ) 
begin
if( ( ( rTimerH == 2 )&&( rTimerL >= 3 )) || ( ( rTimerH < 2 )&&( rTimerL >9 ) ))
{ rTimerH,rTimerL } <= 'h0;
else if( rTimerL == 9 ) 
{ rTimerH,rTimerL } <= { rTimerH + 1'b1,4'd0};
else
rTimerL <= rTimerL + 1'b1;
end
else
{ rTimerH,rTimerL } <= { rTimerH,rTimerL };

assign TimerH = rTimerH;
assign TimerL = rTimerL;
endmodule

文件:counter6.v
module counter6
(
clk,rst_n,
q,En
);
input clk,rst_n;
input En;
output [ 3:0 ]q;

reg [ 3:0 ]cnt;
always @( posedge clk or negedge rst_n )
if( !rst_n )
cnt <= 'd0;
else if( !En )
cnt <= cnt;
else if( cnt == 5 )
cnt <= 'd0;

else
cnt <= cnt + 1'b1;

assign q = cnt;
endmodule

文件:counter10.v
module counter10
(
clk,rst_n,
q,En
);
input clk,rst_n;
input En;

output [ 3:0 ]q;

reg [ 3:0 ]cnt;
always @( posedge clk or negedge rst_n )
if( !rst_n )
cnt <= 'd0;
else if( !En )
cnt <= cnt;
else if( cnt == 9 )
cnt <= 'd0;

else
cnt <= cnt + 1'b1;

assign q = cnt;
endmodule

(3)alarm模块

图 6 alarm模块
文件:alarm.v
module alarm
(
rst_n,clk_1HZ,
clk_1KHZ,clk_500HZ,
setHr,setMin,ctrBell,
Hour,Minute,Second,
AlarmClock,aHour,aMinute
);
input rst_n;
input clk_1KHZ,clk_500HZ,clk_1HZ;
input setHr,setMin,ctrBell;
input [ 7:0 ]Hour,Minute,Second;

output AlarmClock;
output [ 7:0 ]aHour,aMinute;
//reg [ 7:0 ]aHour,aMinute;
//wire clk1;
counter60 U1
(
.clk( clk_1HZ ),
.rst_n( rst_n ),
.En( setMin ),
.Timer( aMinute )
);

counter24 U2
(
.clk( clk_1HZ ),
.rst_n( rst_n ),
.TimerH( aHour[ 7:4 ] ),
.TimerL( aHour[ 3:0 ] ),
.En( setHr )
);
//assign AlarmClock = ( 0 == Hour && 1 == Minute && ctrBell) ? ( Second[ 0 ] ? clk_1KHZ : clk_500HZ ):1'b0;
assign AlarmClock = ( aHour == Hour && aMinute == Minute && ctrBell) ? ( Second[ 0 ] ? clk_1KHZ : clk_500HZ ):1'b0;
//assign clk1 = ( set_Hr || set_Min ) ? clk_1HZ: 1'b0;
endmodule

(4)radio模块

图 6  radio模块
文件:radio.v
module radio
(
clk,rst_n,
Second,Minute,
AlarmRadio,
clk_1KHZ,clk_500HZ
);

input clk,rst_n;
input [ 7:0 ]Second,Minute;
input clk_1KHZ,clk_500HZ;
output AlarmRadio;

reg rRadio;
always @( posedge clk or negedge rst_n )
if( !rst_n )
rRadio <= 'd0;
else if( Minute == 8'h59 )
// else if( Minute == 0 )
case( Second )
8'h53,
8'h55,
8'h57: rRadio <= clk_500HZ;
8'h59: rRadio <= clk_1KHZ;
default: rRadio <= 'd0;
endcase
else
rRadio <= 'd0;

assign AlarmRadio = rRadio;
endmodule

(5)数码管模块

图 7  数码管模块

图 8   数码管内部模块
文件:SMG_Interface.v
module SMG_Interface
(
input CLK,
input nRST,
input [15:0]Number_Sig,
output [7:0]SMG_Data,
output [3:0]Scan_Sig
);

wire [3:0]Number_Data;

SMG_Control_Module U1
(

.CLK( CLK ),
.nRST( nRST ),
.Number_Sig( Number_Sig ),
.Number_Data( Number_Data )

);


      

SMG_Encoder_Module U2
(
.CLK( CLK ),
.nRST( nRST ),
.Number_Data( Number_Data ),
.SMG_Data( SMG_Data )

);

SMG_Scan_Module U3
(
.CLK( CLK ),
.nRST( nRST ),
.Scan_Sig( Scan_Sig )

);

endmodule


图 9  数码管控制模块

文件:SMG_Control_Module.v
module SMG_Control_Module
(
CLK,nRST,
Number_Sig,
Number_Data
);
input CLK;
input nRST;
input [15:0]Number_Sig;
output [3:0]Number_Data;

    parameter T1MS=49_999;//1ms
    reg [15:0]Count_1MS;
    always @(posedge CLK or negedge nRST)
        if(!nRST) 
            Count_1MS <= 16'd0;
        else if( Count_1MS == T1MS )
            Count_1MS <= 16'd0;
        else 
            Count_1MS <= Count_1MS + 1'b1;


    reg [ 1:0 ]i;
    reg [ 3:0 ]rData;
    always @( posedge CLK or negedge nRST )
        if( !nRST )
            begin
            i <= 2'd0;
            rData <= 4'd0;
            end
        else
            case( i )
            2'd0:if( Count_1MS==T1MS ) 
                    i <= i + 1'b1;
                  else 
                    rData <= Number_Sig[15:12];
            2'd1:if( Count_1MS == T1MS ) 
                    i <= i + 1'b1;
                  else 
                    rData <= Number_Sig[11:8];
            2'd2:if( Count_1MS == T1MS ) 
                    i <= i + 1'b1;
                  else 
                    rData <= Number_Sig[7:4];
            2'd3:if( Count_1MS == T1MS ) 
                    i <= 2'd0;
                  else 
                    rData <= Number_Sig[3:0];
            endcase

    assign Number_Data=rData;
    endmodule 
			
 图 10   SMG译码模块

文件:SMG_Encoder_Module.v
module SMG_Encoder_Module
(
CLK,
nRST,
Number_Data,
SMG_Data
);
input CLK;
input nRST;
input [ 3:0 ]Number_Data;
output [ 7:0 ]SMG_Data;

parameter _0 = 8'b1100_0000, _1 = 8'b1111_1001, _2 = 8'b1010_0100, _3 = 8'b1010_1000, _4 = 8'b1001_1001, 
_5 = 8'b1000_1010, _6 = 8'b1000_0010, _7 = 8'b1111_1000, _8 = 8'b1000_0000, _9 = 8'b1000_1000;

reg [ 7:0 ]rData;
always @( posedge CLK or negedge nRST )
if( !nRST )
rData <= 8'b1111_1111;
else
case( Number_Data )
4'd0: rData <= _0;
4'd1: rData <= _1;
4'd2: rData <= _2;
4'd3: rData <= _3;
4'd4: rData <= _4;
4'd5: rData <= _5;
4'd6: rData <= _6;
4'd7: rData <= _7;
4'd8: rData <= _8;
4'd9: rData <= _9;
endcase

assign SMG_Data = rData;
endmodule 


图 11 数码管扫描模块
文件:SMG_Scan_Module.v
module SMG_Scan_Module(CLK,nRST,Scan_Sig);
input CLK;
input nRST;
output [ 3:0 ]Scan_Sig;

    parameter T1MS = 16'd49_999;
    reg [15:0]Count_1MS;

    always @( posedge CLK or negedge nRST )
         if(!nRST)
             Count_1MS <= 16'b0;
          else if( Count_1MS == T1MS )
             Count_1MS <= 16'b0;
          else 
             Count_1MS <= Count_1MS + 1'b1;

    reg [ 3:0 ]rData;
    reg [ 1:0 ]i;

    always @( posedge CLK or negedge nRST )
          if( !nRST )
              begin
                i <= 2'd0;
                rData <= 4'b1111;
                end
          else 
          case ( i )
          2'd0: if( Count_1MS==T1MS )
                        i <= i + 1'b1;
                  else
                      rData <= 4'b0111;

          2'd1: if( Count_1MS==T1MS )
                        i <= i + 1'b1;
                  else
                      rData <= 4'b1011; 

          2'd2: if( Count_1MS==T1MS )
                        i <= i + 1'b1;
                  else
                      rData <= 4'b1101;    

          2'd3: if( Count_1MS==T1MS )
                        i <= i + 1'b1;
                  else
                      rData <= 4'b1110;
         endcase

     assign Scan_Sig = rData;

     endmodule 

你可能感兴趣的:(多功能数字时钟)