FPGA数字时钟计数器

FPGA数字时钟计数器

好久没有登博客了,周末出去浪了一转!!!
今天给大家讲一下数字时钟计数器,上个月写的。只是简单的数字时钟计数,没有设置闹钟、设置时间和秒表的功能,下次我会发一个带有功能的数字时钟,今天只是简单的数字时钟计数器。
由于我的板子只有4位数码管,因此该数字时钟我将用两位数码管进行分钟显示,两位数码管进行时钟显示,用一个LED灯进行秒钟闪烁。
(1)分频
数字时钟计数器,最重要的是分频系数。数字时钟所要进行的计数有秒钟计数、分钟计数、和时钟计数。

我所使用的板子内部时钟是50Mhz,首先要进行秒钟分频,由于要利用LED灯闪烁一次(高电平、低电平交替一次)代表1s,因此秒钟输出Ts=0.5s为一个周期,fs=1/Ts = 2Hz,分频系数为n_s=50Mhz/2hz-1=24999999;

接下来是时钟分频,时钟分频由秒钟输出时钟来计算,当秒钟上升沿到30次时,分钟时钟翻转一次,到59次时,再翻转一次,实现分钟计数(分钟时钟高电平、低电平交替一次为1分钟);

接下来是时钟分频,时钟分频原理类似于由秒钟时钟分频分钟时钟。

(2)有了秒钟时钟、分钟时钟、小时时钟,可以在各自的always块中设置对应数码管显示的参数,秒钟到分钟数字进制为60进制,分钟到时钟数字进制为60进制,时钟到天的数字进制为24进制,由于个位、十位在数码管上分开显示,我使用个位、十位分别计数(hg,hs,sg,ss)。
(3)然后我们还需要一个数码管动态显示的时钟,分频系数我设置为499,这个时钟大家可以根据人眼暂停原理自己设置满足该定理的分频系数即可。
(4)最后就是我们的动态显示,利用case语句和设置i变量循环实现动态显示。
代码如下:


//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:       Grace
// 
// Create Date:    19:59:03 10/17/2018 
// Design Name: 
// Module Name:    D_CLOCK 
// Project Name:   D_clock
// Target Devices: 
// Tool versions: 
// Description:    
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module D_CLOCK(
input clk,                                     //系统时钟输入
output reg [3:0] wei,                          //数码管位选
output reg [6:0] data_out,                     //数码管段选
output reg clk_s                               //秒钟输出
);
parameter n_s=24999999;                        //秒钟分频系数
parameter n_m=59;                              //分钟计数系数
parameter n_h=23;                              //时钟计数系数
parameter n_kj=499;                            //数码管显示时钟系数
reg clk_m;                                     //分钟时钟
reg clk_h;                                     //时钟时钟
reg [24:0] counts ;                            //秒钟计数器
reg [5:0]  countm ;                            //分钟计数器
reg [4:0]  counth ;                            //时钟计数器
reg [5:0]  count_s;                            //秒钟计数器2,当此计数器为59时,分钟计数器+1
reg [5:0]  count_m;                            //分钟计数器2,当此计数器为59时,时钟计数器+1
reg [3:0]  hg;                                 //时钟个位(用于显示)
reg [3:0]  hs;                                 //时钟十位(用于显示)
reg [3:0]  mg;                                 //分钟个位(用于显示)
reg [3:0]  ms;                                 //分钟十位(用于显示)
reg [8:0] count_kj;                            //数码管显示计数
reg clk_kj;                                    //数码管显示时钟
integer i = 0;

initial                                        //初始化个计数器
begin
counts = 25'b0;
counth = 5'b0;
countm = 6'b0;
count_s = 6'b0;
count_m = 6'b0;
clk_h = 1'b1;
clk_m = 1'b1;
hg = 4'b0;
hs = 4'b0;
ms = 4'b0;
mg = 4'b0;
end
/**********************************************************************************
数码管显示时钟分频
***********************************************************************************/
always @(posedge clk)
begin
	if (count_kj == n_kj)
	begin
	clk_kj <= ~clk_kj;
	count_kj <= 9'b0;
	end
	else
	count_kj <= count_kj + 1'b1;
end
/***********************************************************************************
秒钟分频
***********************************************************************************/
always @(posedge clk)
begin
   if (counts == n_s)                           //当秒钟计数到达时
	begin
		clk_s <= ~clk_s;                          //秒钟电平翻转,秒钟灯暗(亮)
		counts <=25'b0;                           //秒钟计数器清零,用于重新计数
	end
	else                                         //若秒钟计数未达到翻转值
		counts <= counts + 1'b1;                  //秒钟计数+1
end

/************************************************************************************
分钟分频
************************************************************************************/
always @(posedge clk_s)
begin
count_s <= count_s + 1'b1;
if(count_s  == 5'd30) 
	begin 
		count_s <= 6'b0;
		clk_m <= ~clk_m;
	end
else if(count_s == 6'd59)
	begin 
		count_s <= 6'b0;
		clk_m <= ~clk_m;
	end
else
	count_s <= count_s +1'b1;
end
end
/*************************************************************************************
分钟计数显示
*************************************************************************************/
always @(posedge clk_m)
begin
	countm <= countm +1'b1;
	if(count_m == n_m)
	begin
		countm <= 6'b0;
		mg <= 6'b0;
		ms <= 6'b0;
	end
	else
	begin
		mg <= mg +1'b1;
		if(mg == 4'd9)
		begin
			mg <= 4'd0;
			ms <= ms +1'b1;
		end
	end
end

/****************************************************************************************
时钟计数分频
****************************************************************************************/
always @(posedge clk_m)
begin
	count_m <= count_m + 1'b1;
if(count_m  == 5'd30) 
	begin 
		count_m <= 6'b0;
		clk_h <= ~clk_h;
	end
else if(count_m == 6'd59)
	begin 
		count_m <= 6'b0;
		clk_h <= ~clk_h;
	end
else
	count_m <= count_m +1'b1;
end
/****************************************************************************************
时钟计数显示
****************************************************************************************/
always @(posedge clk_h)
begin
	counth <= counth +1'b1;
	if(counth == n_h)
	begin
		counth <= 6'b0;
		hg <= 6'b0;
		hs <= 6'b0;
	end
	begin
		hg <= hg +1'b1;
		if(hg == 4'd9)
		begin
			hg <= 4'd0;
			hs <= hs +1'b1;
		end
	end
end


/******************************************************************************************
数码管显示
*******************************************************************************************/

always @(posedge clk_kj)
begin
	i = i +1;
	if(i == 1)
	begin
	wei <= 4'b1110;
	case (mg)
			4'b0000: data_out <= 7'b1000000; // 0
			4'b0001: data_out <= 7'b1111001; // 1
			4'b0010: data_out <= 7'b0100100; // 2
			4'b0011: data_out <= 7'b0110000; // 3
			4'b0100: data_out <= 7'b0011001; // 4
			4'b0101: data_out <= 7'b0010010; // 5
			4'b0110: data_out <= 7'b0000011; // 6
			4'b0111: data_out <= 7'b1111000; // 7
			4'b1000: data_out <= 7'b0000000; // 8
			4'b1001: data_out <= 7'b0011000; // 9
			default: data_out <= 7'b1000000; // 0
	endcase
	end
	else if(i == 2)
	begin
	wei <= 4'b1101;
	case (ms)
			4'b0000: data_out <= 7'b1000000; // 0
			4'b0001: data_out <= 7'b1111001; // 1
			4'b0010: data_out <= 7'b0100100; // 2
			4'b0011: data_out <= 7'b0110000; // 3
			4'b0100: data_out <= 7'b0011001; // 4
			4'b0101: data_out <= 7'b0010010; // 5
			default: data_out <= 7'b1000000; // 0
	endcase
	end
	if(i == 3)
	begin
	wei <= 4'b1011;
	case (hg)
			4'b0000: data_out <= 7'b1000000; // 0
			4'b0001: data_out <= 7'b1111001; // 1
			4'b0010: data_out <= 7'b0100100; // 2
			4'b0011: data_out <= 7'b0110000; // 3
			4'b0100: data_out <= 7'b0011001; // 4
			4'b0101: data_out <= 7'b0010010; // 5
			4'b0110: data_out <= 7'b0000011; // 6
			4'b0111: data_out <= 7'b1111000; // 7
			4'b1000: data_out <= 7'b0000000; // 8
			4'b1001: data_out <= 7'b0011000; // 9
			default: data_out <= 7'b1000000; // 0
	endcase
	end
	else if(i == 4)
	begin
	wei <= 4'b0111;
	case (hs)
      	4'b0000: data_out <= 7'b1000000; // 0
			4'b0001: data_out <= 7'b1111001; // 1
			4'b0010: data_out <= 7'b0100100; // 2
			default: data_out <= 7'b1000000; // 0
	endcase
	i = 0;
	end
	
end 
endmodule

你可能感兴趣的:(FPGA学习)