基于FPGA的电子时钟设计与实现 (在EDA开发板上实现电子时钟功能)

开发板:此款开发板使用的是 ALTERA 公司的 Cyclone IV 系列 FPGA,型号为 EP4CE6F17C8, 256 个引脚的 FBGA 封装。

 题目:在EDA开发板上实现电子时钟功能

要求:实现电子时钟程序编写,实现在7段数码管显示时、分、秒,使用4x4矩阵按键模拟调节时钟指令输入按键,并实现整点报时功能。按键功能包括但不限以下功能:选择(时分秒选择按键、可以一一对应,也可以只用1个按键)、复位、+(时分秒加)、-(时分秒减)。

程序设计步骤:

1、七段数码管显示

1

2.

4

6.

5

7

图1  开机显示画面,其中.为时分秒的间隔

2、 数据输入:在图1所示的状态下,用4x4矩阵按键来进行时分秒的调节。

3、整点报时:到整点时,自动播放一段音乐。

 4、一键复原:完成时间调节后,按“复原”按键,七段数码管显示最初的状态,回到图1所示状态。


以上既是该电子时钟的设计要求。

功能设计部分,分为以下7个模块。

各功能模块简介
EDA_clock 顶层模块文件 将各个模块进行整合
clk1hz 时钟频率 将50MHz晶振频率转化为1秒钟的频率,1Hz=1s
cnt24 24计数器 时钟中 “时”的计数,并判断
cnt60 60计数器 时钟中“分”、“秒”的计数,并判断个位十位实时状态
key4x4_clock 4x4矩阵键盘 矩阵键盘功能设置
seg_dynamic 七段数码管 接收当前计数器值
buzzer 蜂鸣器控制 当整点时播放音乐3秒钟

对于以下各个代码块有较为详细的标注,请自行对照理解,有疑惑的可以评论区,看到回复

1. EDA_clock.v

创建工程后,该模块为顶层文件

代码如下:

/**
 * @copyright: 2782978674@qq.com
 * @author: xietiancheng
 * @date: 2023.6.4
 * 
 **/

​module EDA_clock(
    input	wire	sys_clk,
    input	wire	rst_n,
	input 	wire 	[3:0]	key_in_y,	// 输入矩阵键盘的列信号(KEY0~KEY3)
	output 	wire	[3:0]	key_out_x,	// 输出矩阵键盘的行信号(KEY4~KEY7)
	output	wire	[5:0] sel 	, //数码管位选信号
	output	wire	[7:0] seg	, //数码管段选信号	
	output	wire		buzzer
);

wire clk_1hz;
wire count_s;
wire count_m;
wire [6:0]  Sec;		//秒
wire [6:0]  Sec_out;		//秒输出
wire [6:0]  Min;		//分
wire [6:0]  Min_out;		//分输出
wire [6:0]  Hour; 		//时
wire [6:0]  Hour_out; 		//时输出
wire [4:0]  Sec1;  		//秒的个位
wire [4:0]  Sec2;		//秒的十位
wire [4:0]  Min1;		//分的个位
wire [4:0]  Min2;       //分的十位
wire [4:0]  Hour1;		//时的个位
wire [4:0]  Hour2;      //时的十位

wire en_s;	//秒的使能信号
wire en_m;	//分的使能信号
wire en_h;	//时的使能信号
wire time_en;//当设置时间时,设置使能信号,当有效时时间停止,进行时钟各位赋值。

// assign en_s=1'b1;
assign en_m=count_s && en_s;
assign en_h= (Min_out == 7'd59 && Sec_out == 7'd58)?1:0;

//1hz代表一秒钟,时钟频率设置
clk1hz 
#(
	.N	(26'd25_000_000	)	//代表
)
clk1hz_inst
(
    .clk(sys_clk),
    .rst_n(rst_n),
    .clk_out(clk_1hz)
);
/*********秒和分使用使能信号en_s和en_m来控制*********/
//秒的代码
cnt60 cnt60_inst1(
    .clk(clk_1hz),
    .rst_n(rst_n),
    .en(en_s),
	.time_en(time_en),
	.cnt0(Sec),
	.cnt_out(Sec_out),
    .cnt1(Sec1),	//秒的个位
    .cnt2(Sec2),	//秒的十位
    .flag(count_s)	//秒的使能信号
    );
//分的代码
cnt60 cnt60_inst2(
    .clk(clk_1hz),
    .rst_n(rst_n),
    .en(en_m),
	.time_en(time_en),
	.cnt0(Min),
	.cnt_out(Min_out),
    .cnt1(Min1),	//分的个位
    .cnt2(Min2),	//分的十位
    .flag(count_m)
    );
//时间的设置
cnt24 cnt24_inst(
    .clk(clk_1hz),
    .rst_n(rst_n),
    .en(en_h),
	.time_en(time_en),
	.cnt0(Hour),
	.cnt_out(Hour_out),
    .cnt1(Hour1),
    .cnt2(Hour2)
    );

//数码管控制显示模块
seg_dynamic seg_dynamic_inst
(
	.clk(sys_clk),
	.rst_n(rst_n),
	.Sec1(Sec1),	//秒的个位
	.Sec2(Sec2),	//秒的十位
	.Min1(Min1),	//分的个位
	.Min2(Min2),	//分的十位
	.Hour1(Hour1),	//时的个位
	.Hour2(Hour2),	//时的十位
	.sel (sel), //数码管位选信号
	.seg(seg) //数码管段选信号	
);



//矩阵键盘设置调节时间
key4x4_clock key4x4_clock_inst(
	.clk(sys_clk)			,
	.rst_n(rst_n)			,
	.Sec_out	(Sec_out)	,	
	.Min_out	(Min_out)	,
	.Hour_out	(Hour_out)	,
	.key_in_y(key_in_y)		,	// 输入矩阵键盘的列信号(KEY0~KEY3)
	.key_out_x(key_out_x)	,	// 输出矩阵键盘的行信号(KEY4~KEY7)
	.Sec(Sec)				,	//秒修改
	.Min(Min)				,	//分修改
	.Hour(Hour)				,	//时修改	
	.en(en_s) 				,	//时钟是否运行的使能信号
	.time_en(time_en)
);
	
	
buzzer buzzer_inst(
	.clk	(sys_clk),
	.rst_n	(rst_n	),
	.Sec_out(Sec_out),
	.Min_out(Min_out),
	.buzzer (buzzer)

);
endmodule	


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

quartusII综合报错(Error (10028): Can't resolve multiple constant drivers for net "txd_cnt[3]")

出现这个错误的原因在于,在不同的always逻辑块中,对同一个reg变量进行了赋值。
在多个alwasy逻辑块同时并行工作的时候,会出现冲突。解决的办法就是,对于一个变量,只在一个always块中,进行赋值。

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

2. clk1hz.v

将50MHz转化为1Hz的频率,可通过parameter参数N进行更改转化为其他频率

代码如下:

module clk1hz
#(parameter N = 26'd25_000_000)
(
    input clk,
    input rst_n,
    output reg clk_out
);
reg [32:0] tmp;
always @(posedge clk or negedge rst_n) 
begin
    if(!rst_n) begin
        tmp <= 0;
		  clk_out<=0;
    end
    else if (tmp == N-1)
		begin 
			clk_out<= ~clk_out;
			tmp <= 0;
		end
		else
		begin
			tmp <= tmp+1;
			clk_out <=clk_out;
		end
end
endmodule

3. cnt24.v

代码如下:

module cnt24
// #(parameter CNT = 5'd0)
(
    input	wire		clk		,
    input	wire		rst_n	,
    input	wire		en		,
    input 	wire		time_en	,
    input 	wire	[6:0]	cnt0,
	output 	reg     [6:0]	cnt_out,	//控制cnt的传入传出
    output	reg		[4:0]	cnt1,
    output	reg		[4:0]	cnt2
    );
reg  [6:0]	cnt;

always @(posedge clk or negedge rst_n) 
begin
     if(!rst_n) begin
		cnt<=cnt0;
		cnt1<=cnt%10;
		cnt2<=cnt/10;
		cnt_out<=cnt;
	  end
     else 
	  begin 
		if(en==1) 
		begin
			if(cnt<23)
			begin
				cnt<=cnt+1;
				cnt1<=cnt%10;
				cnt2<=cnt/10;
				cnt_out<=cnt;
			end
			else begin
				cnt<=0;
				cnt1<=cnt%10;
				cnt2<=cnt/10;
				cnt_out&
  • 4
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@xiaoxie001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值