module clock_top
(
CLK, RSTn,
KEY,
SEG, DIG,
RST,
SCLK,
SIO,
SEC_Data,
MIN_Data,
HOU_Data,
LED,
YELLOW
);
input CLK;
input RSTn;
input [7:0]KEY;
output [7:0]SEG;
output [7:0]DIG;
output RST;
output SCLK;
inout SIO;
output [7:0]SEC_Data;
output [7:0]MIN_Data;
output [7:0]HOU_Data;
output [7:0]LED;
output [2:0]YELLOW;
/**************************************/
wire [3:0]Data7;
wire [3:0]Data6;
wire [3:0]Data5;
wire [3:0]Data4;
wire [3:0]Data3;
wire [3:0]Data2;
wire [3:0]Data1;
wire [3:0]Data0;
number_swap_module U1
(
.CLK( CLK ),
.RSTn( RSTn ),
.KEY( Number_Data ),
.SEC_Data(SEC_Data),
.MIN_Data(MIN_Data),
.HOU_Data(HOU_Data),
.Data7 ( Data7 ),
.Data6 ( Data6 ),
.Data5 ( Data5 ),
.Data4 ( Data4 ),
.Data3 ( Data3 ),
.Data2 ( Data2 ),
.Data1 ( Data1 ),
.Data0 ( Data0 )
);
/****************************************/
wire [7:0]Bit7;
wire [7:0]Bit6;
wire [7:0]Bit5;
wire [7:0]Bit4;
wire [7:0]Bit3;
wire [7:0]Bit2;
wire [7:0]Bit1;
wire [7:0]Bit0;
seg_encoder_module U2
(
.CLK( CLK ),
.RSTn( RSTn ),
.Data7 ( Data7 ),
.Data6 ( Data6 ),
.Data5 ( Data5 ),
.Data4 ( Data4 ),
.Data3 ( Data3 ),
.Data2 ( Data2 ),
.Data1 ( Data1 ),
.Data0 ( Data0 ),
.Bit7 ( Bit7 ),
.Bit6 ( Bit6 ),
.Bit5 ( Bit5 ),
.Bit4 ( Bit4 ),
.Bit3 ( Bit3 ),
.Bit2 ( Bit2 ),
.Bit1 ( Bit1 ),
.Bit0 ( Bit0 ) );
/*****************************************/
comp_scan_module U3
(
.CLK( CLK ),
.RSTn( RSTn ),
.Bit7 ( Bit7),
.Bit6 ( Bit6 ),
.Bit5 (Bit5 ),
.Bit4 ( Bit4),
.Bit3 ( Bit3 ),
.Bit2 (Bit2 ),
.Bit1 ( Bit1),
.Bit0 ( Bit0 ),
.SEG ( SEG ),
.DIG ( DIG )
);
exp13_demo_module U4
(
.CLK( CLK ),
.RSTn( RSTn ),
.RST(RST),
.SCLK(SCLK),
.SIO(SIO),
.SEC_Data(SEC_Data),
.MIN_Data(MIN_Data),
.HOU_Data(HOU_Data),
.LED(LED),
.YELLOW(YELLOW)
);
/*******************************/
endmodule
module function_module
(
CLK, RSTn,
Start_Sig,
Words_Addr,
Write_Data,
Read_Data,
Done_Sig,
RST,
SCLK,
SIO
);
input CLK;
input RSTn;
input [1:0]Start_Sig;
input [7:0]Words_Addr;
input [7:0]Write_Data;
output [7:0]Read_Data;
output Done_Sig;
output RST;
output SCLK;
inout SIO; //SIO和寄存器isOut组成三态门IO口
/*****************************/
parameter T0P5US = 4'd9;
/*****************************/
reg [3:0]Count1;
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
Count1 <= 4'd0;
else if( Count1 == T0P5US )
Count1 <= 4'd0;
else if( Start_Sig[0] == 1'b1 || Start_Sig[1] == 1'b1 )
Count1 <= Count1 + 1'b1;
else
Count1 <= 4'd0;
/*****************************/
reg [5:0]i; //执行步骤的寄存器
reg [7:0]rData; //暂存数据的寄存器
reg rSCLK; //用来驱动SCLK的寄存器
reg rRST; //用来驱动RST的寄存器
reg rSIO; //用来驱动SIO输出的寄存器
reg isOut; //用来控制IO方向寄存器
reg isDone; //完成标志寄存器
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )
begin
i <= 6'd0;
rData <= 8'd0;
rSCLK <= 1'b0;
rRST <= 1'b0;
rSIO <= 1'b0;
isOut <= 1'b0;
isDone <= 1'b0;
end
/***************************************************************************************
Start_Sig为2'b10 时是“写字节操作”。
步骤0:对rData,rSCL,rRST(CE),isOut等寄存器进行初始化。
步骤1-16:将“第一字节数据”(访问寄存器地址字节)发送出去。传输规则与SPI有点相似,在时间下降
沿设置数据,时间上升沿锁存数据。
步骤17:再次对rData设置为“第二字节数据”。
步骤18-33:将“第二字节数据”发送出去。
步骤34:对rRST(CE)拉低。以示“写字节操作”已经结束。
步骤35-36:反馈完成信号。
Start_Sig为2'b01 时是“读字节操作”。
*****************************************************************************************/
else if( Start_Sig[1] )
case( i )
0 :
begin rSCLK <= 1'b0; rData <= Words_Addr; rRST <= 1'b1; isOut <= 1'b1; i <= i + 1'b1; end
1, 3, 5, 7, 9, 11, 13, 15 :
if( Count1 == T0P5US ) i <= i + 1'b1;
else begin rSIO <= rData[ (i >> 1) ]; rSCLK <= 1'b0; end
2, 4, 6, 8, 10, 12, 14, 16 :
if( Count1 == T0P5US ) i <= i + 1'b1;
else begin rSCLK <= 1'b1; end
17 :
begin rData <= Write_Data; i <= i + 1'b1; end
18, 20, 22, 24, 26, 28, 30, 32 :
if( Count1 == T0P5US ) i <= i + 1'b1;
else begin rSIO <= rData[ (i >> 1) - 9 ]; rSCLK <= 1'b0; end
19, 21, 23, 25, 27, 29, 31, 33 :
if( Count1 == T0P5US ) i <= i + 1'b1;
else begin rSCLK <= 1'b1; end
34 :
begin rRST <= 1'b0; i <= i + 1'b1; end
35 :
begin isDone <= 1'b1; i <= i + 1'b1; end
36 :
begin isDone <= 1'b0; i <= 6'd0; end
endcase
/***************************************************************************************
Start_Sig为2'b01 时是“读字节操作”。在读操作中,第一字节和第二字节数据显然对时间沿的敏感不同。
步骤0:对rData,rSCL,rRST(CE),isOut等寄存器进行初始化。
步骤1-16:将“第一字节数据”(访问寄存器地址字节)发送出去。传输规则与SPI有点相似,在时间下降
沿设置数据,时间上升沿锁存数据。
步骤17:对IO口的方向改变为输入,亦即将isOut设置为逻辑0。
步骤18-33:“读取一个字节数据操作”,该操作在时间的下降沿从SIO读取数据。DS1302的数据传输都是从
LSB开始到MSB结束。
步骤34:对rRST(CE)拉低。以示“写字节操作”已经结束。
步骤35-36:恢复IO口为输出,拉高isOut寄存器,然后产生一个完成信号。
从DS1302芯片读取的数据会暂存在rData寄存器,该寄存器会驱动Read_Data这条信号线。assign Read_Data = rData;
*****************************************************************************************/
else if( Start_Sig[0] )
case( i )
0 :
begin rSCLK <= 1'b0; rData <= Words_Addr; rRST <= 1'b1; isOut <= 1'b1; i <= i + 1'b1; end
1, 3, 5, 7, 9, 11, 13, 15 :
if( Count1 == T0P5US ) i <= i + 1'b1;
else begin rSIO <= rData[ (i >> 1) ]; rSCLK <= 1'b0; end
2, 4, 6, 8, 10, 12, 14, 16 :
if( Count1 == T0P5US ) i <= i + 1'b1;
else begin rSCLK <= 1'b1; end
17 :
begin isOut <= 1'b0; i <= i + 1'b1; end
18, 20, 22, 24, 26, 28, 30, 32 :
if( Count1 == T0P5US ) i <= i + 1'b1;
else begin rSCLK <= 1'b1; end
19, 21, 23, 25, 27, 29, 31, 33 :
if( Count1 == T0P5US ) begin i <= i + 1'b1; end
else begin rSCLK <= 1'b0; rData[ (i >> 1) - 9 ] <= SIO; end
34 :
begin rRST <= 1'b0; isOut <= 1'b1; i <= i + 1'b1; end
35 :
begin isDone <= 1'b1; i <= i + 1'b1; end
36 :
begin isDone <= 1'b0; i <= 6'd0; end
endcase
/********************************/
assign Read_Data = rData; //
assign Done_Sig = isDone;
assign RST = rRST;
assign SCLK = rSCLK;
assign SIO = isOut ? rSIO : 1'bz; //该行定义了SDA这个IO口是由isOut这个寄存器控制着“输入输出”。
//当isOut为逻辑1时,SIO口是输出状态,反之是输入状态
/********************************/
endmodule
相关LED数码动态扫描显示代码省略


点击下载DS1302数字时钟.rar
