EDA技术及应用课程设计说明书
2013 届 电子信息工程 专业 班级
题 目 数字时钟 学 号 姓 名 指导教师
二О一五年 月 日
1
一、基本原理
一个完整的时钟应由三部分组成:秒脉冲发生电路、计数显示部分和时钟调整部分。
秒脉冲发生电路原理:一个时钟的准确与否主要取决于秒脉冲的精确度。为了保证计时准确我们对系统时钟48MHz进行了48000000分频,从而得到1Hz的秒脉冲。
计数显示部分原理:显示部分是用数码管LED实现的,这里使用的是共阳极的数码管如图所示8个数码管,其中左边两个数码管用来显示时的个位和十位、中间的显示分的个位和十位、最右边两个显示分的个位和十位。
时钟调整部分原理:校时电路里定义key[0]、key[1]和k2、k3分别用于控制时钟的计时开始、清零和调整功能中的时的加1、分的加1处理,从而完成对现在的时间调整。本实验电路校时电路在此完成了暂停、清零、时调整和分调整。
2
二、硬件设计
芯片图:
图1 数字时钟原理图
的建立、管脚分配、编译、仿真、再下载到芯片进行运行。
程序的调试工作都是在电脑上完成的,通过程序的输入、原理图
3
来显示时钟的时-分-秒。
电路中采用共阳极连接的七段数码管,通过程序的控制扫描驱动
4
程序中的按键设定为K1暂停、K2清零、K3调时、K4调分
元件清单:
三、数字时钟的Verilog实现
管脚的分配:
程序:
module clock(clk,s1,,s2,key,dig,seg); //模块名clock input clk,s1,s2; //输入时钟 input[1:0]key; //输入按键
output[7:0]dig; //数码管选择输出引脚
5
output[7:0]seg; //数码管段输出管脚 reg[7:0]seg_r; //定义数码管输出寄存器 reg[7:0]dig_r; //定义数码管选择输出寄存器 reg[3:0]disp_dat; //定义显示数据寄存器 reg[24:0]count; //定义计数寄存器 reg[23:0]hour; //reg sec,en; //reg[1:0]dout1,dout2,dout3; //wire[1:0]key_done; //assign dig=dig_r; //assign seg=seg_r; ////秒信号产生部分
always@(posedge clk) //begin
count=count+1'b1;
if(count==25'd24000000) // begin
count=25'd0; // sec=~sec; // end end
//按键消抖处理部分
定义现在时刻寄存器 定义标志位 寄存器 按键消抖输出 输出数码管选择 输出数码管译码结果 定义clock上升沿触发 是否到0.5秒 计数器清零 置位秒标志 6
assign key_done=(dout1|dout2|dout3); //按键消抖输出 always@(posedge count[17]) begin dout1<=key; dout2<=dout1; dout3<=dout2; end
always@(negedge key_done[0]) begin
en=~en; //将琴键开关转换为乒乓开关 end
always @(posedge clk) //count[17:15]大约1ms改变一次 begin
case(count[17:15]) //选择扫描显示数据 3'd0:disp_dat = hour[3:0]; //秒个位 3'd1:disp_dat = hour[7:4]; //秒十位 3'd2:disp_dat = 4'ha; //显示“-” 3'd3:disp_dat = hour[11:8]; //分个位 3'd4:disp_dat = hour[15:12]; //分十位 3'd5:disp_dat = 4'ha; //显示“-” 3'd6:disp_dat = hour[19:16]; //时个位 3'd7:disp_dat = hour[23:20]; //时十位
7
endcase
case(count[17:15]) //选择数码管显示位 3'd0:dig_r = 8'b11111110; 3'd1:dig_r = 8'b11111101; 3'd2:dig_r = 8'b11111011; 3'd3:dig_r = 8'b11110111; 3'd4:dig_r = 8'b11101111; 3'd5:dig_r = 8'b11011111; 3'd6:dig_r = 8'b10111111; 3'd7:dig_r = 8'b01111111; endcase end
always @(posedge clk) begin
case(disp_dat)
4'h0:seg_r = 8'hc0; // 4'h1:seg_r = 8'hf9; 4'h2:seg_r = 8'ha4; 4'h3:seg_r = 8'hb0; 4'h4:seg_r = 8'h99; 4'h5:seg_r = 8'h92; 4'h6:seg_r = 8'h82;
8
显示0 4'h7:seg_r = 8'hf8; 4'h8:seg_r = 8'h80; 4'h9:seg_r = 8'h90; 4'ha:seg_r = 8'hbf; default:seg_r = 8'hff; endcase
if((count[17:15]==3'd2)&sec) seg_r = 8'hff; end
always @(negedge sec or negedge key_done[1]) //Begin if(!key_done[1]) //是否为清零键 hour=24'h0; //是,则清零 else if(en) begin if(!s1) begin
if(hour[23:16]==8'd35) begin
hour[19:16]=0; hour[23:20]=0; end
9
计时处理 else begin
if(hour[19:16]==9) begin
hour[19:16]<=0;
hour[23:20]<=hour[23:20]+1; end else
hour[19:16]<=hour[19:16]+1; end end
else if(!s2) begin
if(hour[11:8]==9) begin
hour[11:8]<=0; if(hour[15:12]==5) hour[15:12]<=0; else
hour[15:12]<=hour[15:12]+1;
10
end else
hour[11:8]=hour[11:8]+1; end end else begin
hour[3:0]=hour[3:0]+1; // if(hour[3:0]==4'ha) begin
hour[3:0]=4'h0;
hour[7:4]=hour[7:4]+1; // if(hour[7:4]==4'h6) begin
hour[7:4]=4'h0;
hour[11:8]=hour[11:8]+1; // if(hour[11:8]==4'ha) begin
hour[11:8]=4'h0;
hour[15:12]=hour[15:12]+1; // if(hour[15:12]==4'h6) begin
11
秒加1 秒的十位交1 分个位加1 分十位加1 hour[15:12]=4'h0;
hour[19:16]=hour[19:16]+1; //十个位加1 if(hour[19:16]==4'ha) begin
hour[19:16]=hour[4'h0];
hour[23:20]=hour[23:20]+1; //时十位加1 end
if(hour[23:16]==8'h24) hour[23:16]=8'h0; end end end end end end endmodule
一、 课程设计总结
在这两周的课程设计中,我学到了很多新的知识。通过动手实践
12
对数字时钟程序的编写和多次修改,不仅对Verilog HDL的自顶向下设计思想有了深入的了解,而且感到这种模块化的设计不仅增强了程序的可读性,而且使程序的编写更方便。其次,虽然我们在修改程序的过程中,遇到了很多的问题,但是通过我们的齐心协力的努力,在修改了很多次之后,终于成功的把校时功能添加了进去。这次实验不仅考察了我们对EDA的基础知识的运用,而且考察了我们对VHDL语言的掌握能力。同时,这次实验还增加了我学习VHDL语言的兴趣,我会努力学习好这门课程,并将它运用的生活中。 二、 指导教师评语
13
成绩 指导教师签名
14