数字时钟的设计源码解析.docx
- 文档编号:6560181
- 上传时间:2023-01-07
- 格式:DOCX
- 页数:24
- 大小:20KB
数字时钟的设计源码解析.docx
《数字时钟的设计源码解析.docx》由会员分享,可在线阅读,更多相关《数字时钟的设计源码解析.docx(24页珍藏版)》请在冰豆网上搜索。
数字时钟的设计源码解析
此程序是工作在开发板模式七下
//LHB2_1文件下,顶层,实现了对所有模块的输出和例化
moduleLHB2_1(
clk,//12m信号产生引脚
o_miao_1,//秒低四位数码管输出
o_miao_2,//秒高四位数码管输出
o_fen_1,//分低四位数码管输出
o_fen_2,//分高四位数码管输出
o_shi_1,//时高四位数码管输出
o_shi_2,//时高四位数码管输出
mode,//设置按键
set,//时间选择按键
accum,//时间累加按键
voice,//蜂鸣器开启关闭选择按键
o_led1,//指示灯D1指示工作在模式一下:
时间显示
o_led2,//指示灯D2指示工作在模式二下:
闹钟设置
o_led3,//指示灯D3指示工作在模式三下:
时间设置
o_led4,//指示灯D4指示秒时间设置:
可以对秒进行累加
o_led5,//指示灯D6指示分时间设置:
可以对分进行累加
o_led6,//指示灯D7指示时分钟设置:
可以对时进行累加
o_led7,//指示灯D8蜂鸣器报警指示灯:
当整点或闹钟到来时,会量20秒
led,//蜂鸣器开关指示灯
nl_kz//蜂鸣器开启关闭选择按键
);
inputclk;//因为是时钟输入,所以设置为输入型
inputmode;//按键输入
inputset;//按键输入
inputaccum;//按键输入
inputvoice;//按键输入
inputnl_kz;//按键输入
outputo_led1;//因为要点亮LED,所以设置为输出
outputo_led2;//因为要点亮LED,所以设置为输出
outputo_led3;//因为要点亮LED,所以设置为输出
outputo_led4;//因为要点亮LED,所以设置为输出
outputo_led5;//因为要点亮LED,所以设置为输出
outputo_led6;//因为要点亮LED,所以设置为输出
outputo_led7;//因为要点亮LED,所以设置为输出
outputled;//因为要点亮LED,所以设置为输出
output[3:
0]o_miao_1;//数码管驱动输出:
接译码器所以用四位
output[3:
0]o_miao_2;//数码管驱动输出:
接译码器所以用四位
output[3:
0]o_fen_1;//数码管驱动输出:
接译码器所以用四位
output[3:
0]o_fen_2;//数码管驱动输出:
接译码器所以用四位
output[3:
0]o_shi_1;//数码管驱动输出:
接译码器所以用四位
output[3:
0]o_shi_2;//数码管驱动输出:
接译码器所以用四位
wireclk1s;//同下
wire[7:
0]miao;//秒保存缓存区,因为例化模块要调用,所以定义为WIRE型变量
wire[7:
0]fen;/分保存缓存区,因为例化模块要调用,所以定义为WIRE型变
wire[7:
0]shi;/时保存缓存区,因为例化模块要调用,所以定义为WIRE型变量
wire[7:
0]fen_1;//分输出,因为例化模块要调用,所以定义为WIRE型变量
wire[7:
0]shi_1;//时输出,因为例化模块要调用,所以定义为WIRE型变量
wirenz_bz;//蜂鸣器是否开启标志位,应为只有1或0两种情况,所以一个字节
wire[2:
0]m_mode;//模式设置标志位,因为有三个模式,所以建立了3个字节
wire[7:
0]m_fen;//闹钟分保存缓存区,因为例化模块要调用,所以定义为WIRE型变量
wire[7:
0]m_shi;//闹钟时保存缓存区,因为例化模块要调用,所以定义为WIRE型变量
wire[7:
0]m_miao;//闹钟秒保存缓存区,因为例化模块要调用,所以定义为WIRE型变量
wire[7:
0]m_m_fen;//因为在Verilog语法中不允许一个变量多次赋值,所以特地建立了一个修改时间的缓存区(PS:
不允许多次赋值是应为Verilog是可以并行执行的,所以多次赋值会出现变量的不确定性,因此不允许多次赋值)
wire[7:
0]m_m_shi;//同上
wire[7:
0]m_m_miao;//同上
wire[2:
0]m1;//时分秒设置标志位,因为例化模块要调用,所以定义为WIRE型变量
LHB_1HZU_LHB_1HZ(//在12M主频下1秒钟产生模块
.clk(clk),//12M输入
.clk1s(clk1s)//1秒输出
);
LHB_JSU_LHB_JS(//实现对时间的技术模块和时间设置模块
.clk1s(clk1s),//1秒输入
.miao(miao),//秒输出送到显示模块显示
.fen(fen),//分输出送到显示模块显示
.shi(shi),//时输出送到显示模块显示
.m_mode(m_mode),//模式标志位,判断处于什么模式
.m_shi(m_m_shi),//时间设置缓存,通过在闹钟模块中赋值,送入这里赋值给miao
.m_miao(m_m_miao),//同上
.m_fen(m_m_fen)//同上
);
LHB_DSU_LHB_DS(//显示模块
.i_miao(miao),//时间缓存输入
.i_fen(fen),//同上
.i_shi(shi),//同上
.o_miao_1(o_miao_1),//秒低四位数码管输出
.o_miao_2(o_miao_2),/秒高四位数码管输出
.o_fen_1(o_fen_1),/分低四位数码管输出
.o_fen_2(o_fen_2),/分高四位数码管输出
.o_shi_1(o_shi_1),/时低四位数码管输出
.o_shi_2(o_shi_2),/时低低四位数码管输出
.o_led5(o_led5),//LED输出指示模式
.o_led6(o_led6),//同上
.o_led7(o_led7),//同上
.m_fen(m_fen),//同上
.m_shi(m_shi),//同上
.m_miao(m_miao),//闹钟设置时间显示
.m_mode(m_mode),//同上
.clk1s(clk),//显示刷新频率输入
.o_led1(o_led1),/LED输出指示模式
.o_led2(o_led2),/LED输出指示模式
.o_led3(o_led3),/LED输出指示模式
.o_led4(o_led4),/LED输出指示模式
.nz_bz(nz_bz),//蜂鸣器鸣叫标志位
.led(led),//蜂鸣器
.m1(m1),//时分秒设置标志位
.nl_kz(nl_kz),//蜂鸣器开启关闭选择按键
.m_m_fen(m_m_fen),//时间缓存区
.m_m_shi(m_m_shi),//时间缓存区
.m_m_miao(m_m_miao)//时间缓存区
);
LHB_NZU_LHB_NZ(//闹钟设置及时间设置模块
.miao(miao),//秒时间输入,主要用于判断脑中时间是否到和整点时间
.fen(fen),//同上
.shi(shi),//同上
.set(set),//按键
.accum(accum),//按键
.mode(mode),//按键
.m_mode(m_mode),//模式按键
.clk1s(clk1s),//1秒频率输入,主要做一些判断
.nz_bz(nz_bz),//闹钟标志
.m_fen(m_fen),//时间缓存
.m_shi(m_shi),//同上
.m_miao(m_miao),//同上
.m1(m1),//时分秒设置标志位
.m_m_fen(m_m_fen),//时间缓存
.m_m_shi(m_m_shi),//同上
.m_m_miao(m_m_miao)//同上
);
Endmodule
注:
由于顶层定义定义,已在上面的文件中解释,所以下面的文件,顶层不再解释
//1HZ分频模块
moduleLHB_1HZ(
clk,
clk1s
);
inputclk;
outputclk1s;
reg[22:
0]pll;//计数缓存区
regclk1s;//因为在always中赋值所以定义成reg型变量(PS在always中使用而不赋值,不需要定义成reg型)
always@(posedgeclk)//上升沿检测
begin
if(pll>=23'h5B8D7F)//判断是否到计数值
begin
pll<=23'h0;//清零
clk1s<=~clk1s;//取反,输出秒跳变
end
else
pll<=pll+1;//未到计数值时,移植累加
end
endmodule
//时钟计数模块
moduleLHB_JS(
clk1s,
miao,
fen,
shi,
m_mode,
m_fen,
m_shi,
m_miao
);
inputclk1s;
output[7:
0]miao;
output[7:
0]fen;
output[7:
0]shi;
input[2:
0]m_mode;
input[7:
0]m_fen;
input[7:
0]m_shi;
input[7:
0]m_miao;
reg[7:
0]miao;
reg[7:
0]fen;
reg[7:
0]shi;
always@(posedgeclk1s)//判断一秒是否到来,来了就进行处理
begin
if(clk1s==1)//判断秒到来没
begin
if(m_mode==0)//判断是否在模式一,已有模式一才可以累加
begin
if(miao>=59)//判断秒是否超过计数值,超过清零,否则进行累加
begin
miao<=8'h00000000;
if(fen>=59)//判断分是否超过计数值,超过清零,否则进行累加
begin
fen<=8'h00000000;
if(shi>=23)//判断时是否超过计数值,超过清零,否则进行累加
begin
shi<=8'h00000000;
end
else
begin
shi<=shi+1;
end
end
else
fen<=fen+1;
end
else
begin
miao<=miao+1;
end
end
elseif(m_mode==2)//判断是否工作在模式三,是的话吧缓存区的值进行赋值,从而达到更改时间的目的
begin
miao<=m_miao;
fen<=m_fen;
shi<=m_shi;
end
else;//有IF就有else,就算是不执行任何的代码
end
else;//有IF就有else,就算是不执行任何的代码
end
endmodule
//显示模块,所有外部显示都在这个文件中显示
moduleLHB_DS(
i_miao,
i_fen,
i_shi,
o_miao_1,
o_miao_2,
o_fen_1,
o_fen_2,
o_shi_1,
o_shi_2,
m_fen,
m_shi,
m_miao,
m_mode,
clk1s,
o_led1,
o_led2,
o_led3,
o_led4,
o_led5,
o_led6,
o_led7,
nz_bz,
led,
m1,
nl_kz,
m_m_fen,
m_m_shi,
m_m_miao
);
input[2:
0]m_mode;
input[7:
0]i_miao;
input[7:
0]i_fen;
input[7:
0]i_shi;
input[2:
0]m1;
input[7:
0]m_fen;
input[7:
0]m_shi;
input[7:
0]m_miao;
input[7:
0]m_m_fen;
input[7:
0]m_m_shi;
input[7:
0]m_m_miao;
inputnz_bz;
inputnl_kz;
inputclk1s;
outputo_led1;
outputo_led2;
outputo_led3;
outputo_led4;
outputo_led5;
outputo_led6;
outputo_led7;
outputled;
output[3:
0]o_miao_1;
output[3:
0]o_miao_2;
output[3:
0]o_fen_1;
output[3:
0]o_fen_2;
output[3:
0]o_shi_1;
output[3:
0]o_shi_2;
reg[3:
0]o_miao_1;
reg[3:
0]o_miao_2;
reg[3:
0]o_fen_1;
reg[3:
0]o_fen_2;
reg[3:
0]o_shi_1;
reg[3:
0]o_shi_2;
rego_led1;
rego_led2;
rego_led3;
rego_led4;
rego_led5;
rego_led6;
rego_led7;
regled;
reg[2:
0]m7;
always@(posedgenl_kz)//判断闹钟开关是否被按下
begin
if(nl_kz==1)
o_led4=~o_led4;//一旦按下就对指示灯取反,指示闹钟是否开
else;
end
always@(posedgeclk1s)//显示刷新频率是否到来,这个决定是的显示的数值显示灵敏度
begin
if(m_mode==0)//判断是否工作在模式一
begin
o_miao_1=i_miao%10;//对秒进行取余运算,由于很多人问我关于这个问题,我就在这里详细解释一下(取余:
举个例子15/10=1---5取余就是15%10=5这样就把各位和百位分开了,这是在数值分离中常用的一种手段)
o_miao_2=i_miao/10;//同上
o_fen_1=i_fen%10;
o_fen_2=i_fen/10;
o_shi_1=i_shi%10;
o_shi_2=i_shi/10;
o_led1=1;//因为工作在模式一,所以指示灯亮,其他灭
o_led2=0;
o_led3=0;
if(nz_bz==1)//判断闹钟时间是否都到来
begin
begin
if(o_led4==1)//判断闹钟开关是否开启
led=1;//开启闹钟
else;
end
end
else
begin
led=0;//关闭闹钟
end
end
elseif(m_mode==1)//模式二
begin
o_miao_1=m_miao%10;//同上
o_miao_2=m_miao/10;
o_fen_1=m_fen%10;
o_fen_2=m_fen/10;
o_shi_1=m_shi%10;
o_shi_2=m_shi/10;
o_led1=0;//模式二灯2亮
o_led2=1;
o_led3=0;
if(m1==0)//指示时间更改,现在是更改秒
begin
o_led5=1;
o_led6=0;
o_led7=0;
end
elseif(m1==1)//指示时间更改,现在是更改分
begin
o_led5=0;
o_led6=1;
o_led7=0;
end
else//指示时间更改,现在是更改时
begin
o_led5=0;
o_led6=0;
o_led7=1;
end
if(nz_bz==1)//同上
begin
if(o_led4==1)
led=1;
else;
end
else
led=0;
end
else
begin
if(m1==0)
begin
o_led5=1;
o_led6=0;
o_led7=0;
end
elseif(m1==1)//模式二,闹钟参数显示
begin
o_led5=0;
o_led6=1;
o_led7=0;
end
else
begin
o_led5=0;
o_led6=0;
o_led7=1;
end
o_miao_1=m_m_miao%10;//同上
o_miao_2=m_m_miao/10;
o_fen_1=m_m_fen%10;
o_fen_2=m_m_fen/10;
o_shi_1=m_m_shi%10;
o_shi_2=m_m_shi/10;
o_led1=0;//同上
o_led2=0;
o_led3=1;
if(nz_bz==1)//同上
begin
if(o_led4==1)
led=1;
else;
end
else
led=0;
end
end
endmodule
//闹钟设置模块,主要对闹钟设置,和模式设置
moduleLHB_NZ(
miao,
fen,
shi,
set,
accum,
mode,
m_mode,
clk1s,
nz_bz,
m_fen,
m_shi,
m_miao,
m_m_fen,
m_m_shi,
m_m_miao,
m1
);
input[7:
0]miao;
input[7:
0]fen;
input[7:
0]shi;
inputset;
inputaccum;
inputmode;
inputclk1s;
outputnz_bz;
output[2:
0]m1;
output[7:
0]m_fen;
output[7:
0]m_shi;
output[7:
0]m_miao;
output[7:
0]m_m_fen;
output[7:
0]m_m_shi;
output[7:
0]m_m_miao;
output[2:
0]m_mode;
reg[2:
0]m1;
reg[7:
0]m_fen;
reg[7:
0]m_shi;
reg[7:
0]m_miao;
reg[7:
0]m_m_fen;
reg[7:
0]m_m_shi;
reg[7:
0]m_m_miao;
reg[2:
0]m_mode;
regnz_bz;
//regaccum_bz;
reg[7:
0]m8;
always@(posedgeaccum)//判断累加按键是否按下
begin
if(accum==1)//判断累加按键是否按下,其实这些再判断只是为语法服务,没多少意义
begin
if(m_mode==1)//判断是否在模式二
begin
if(m1==0)//判断是否累加秒
begin
if(m_miao>=59)//对秒进行累加
m_miao=8'h00;
else
m_miao=m_miao+1;
end
elseif(m1==1)判断是否累加分
begin
if(m_fen>=59)//对分进行累加
m_fen=8'h00;
else
m_fen=m_fen+1;
end
elseif(m1==2)//判断是否累加时
if(m_shi>=23)//对时进行累加
m_shi=8'h00;
else
m_shi=m_shi+1;
end
elseif(m_mode==2)//判断是否工作在模式三
begin
if(m1==0)//同上
begin
if(m_m_miao>=59)//对缓存区的时间进行累加,应为一个变量只能赋值一次,在计数模块中会把这个变量的值赋值给真正的监视
m_m_miao=8'h00;
else
m_m_miao=m_m_miao+1;
end
elseif(m1==1)//判断是否工作在模式二
begin
if(m_m_fen>=59)
m_m_fen=8'h00;
else
m_m_fen=m_m_fen+1;
end
elseif(m1==2)
if(m_m_shi>=23)
m_m_shi=8'h00;
else
m_m_shi=m_m_shi+1;
end
else;
end
end
always@(posedgeset)//判断时间设置按键是否按下
begin
if(set==1)//判断时间设置按键是否按下,其实这些再判断只是为语法服务,没多少意义
begin
if(m_mode==1)//判断是否在模式二
begin
if(m1>=3)//对时间设置标志位进行累加,从而设置对应的时间
m1=3'h0;
else
m1=m1+1;
end
else
begin
if(m1>=3)//同上
m1=3'h0;
else
m1=m1+1;
end
end
else;
end
always@(posedgemode)//判断模式设置按键是否按下
begin
if(mode==1)//判断模式设置按键是否按下,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数字 时钟 设计 源码 解析