"); //-->
/* 信号定义:
clk:
clk_1k:
mode:
turn:
change:
标准时钟信号,本例中,其频率为 4Hz;
产生闹铃音、报时音的时钟信号,本例中其频率为 1024Hz;
功能控制信号;为 0:计时功能;
为 1:闹钟功能;
为 2:手动校时功能;
接按键,在手动校时功能时,选择是调整小时,还是分钟;
若长时间按住该键,还可使秒信号清零,用于精确调时;
接按键,手动调整时,每按一次,计数器加 1;
如果长按,则连续快速加 1,用于快速调时和定时;
hour,min,sec:此三信号分别输出并显示时、分、秒信号,
皆采用 BCD 码计数,分别驱动 6 个数码管显示时间;
alert:
输出到扬声器的信号,用于产生闹铃音和报时音;
闹铃音为持续 20 秒的急促的“嘀嘀嘀”音,若按住“change”键,
则可屏蔽该音;整点报时音为“嘀嘀嘀嘀—嘟”四短一长音;
LD_alert: 接发光二极管,指示是否设置了闹钟功能;
LD_hour: 接发光二极管,指示当前调整的是小时信号;
LD_min:
*/
接发光二极管,指示当前调整的是分钟信号。
module clock(clk,clk_1k,mode,change,turn,alert,hour,min,sec,
LD_alert,LD_hour,LD_min);
input clk,clk_1k,mode,change,turn;
output alert,LD_alert,LD_hour,LD_min;
output[7:0] hour,min,sec;
reg[7:0] hour,min,sec,hour1,min1,sec1,ahour,amin;
reg[1:0] m,fm,num1,num2,num3,num4;
reg[1:0] loop1,loop2,loop3,loop4,sound;
reg LD_hour,LD_min;
reg clk_1Hz,clk_2Hz,minclk,hclk;
reg alert1,alert2,ear;
reg count1,count2,counta,countb;
wire ct1,ct2,cta,ctb,m_clk,h_clk;
always @(posedge clk)
begin
clk_2Hz<=~clk_2Hz;
if(sound==3) begin sound<=0; ear<=1; end
//ear 信号用于产生或屏蔽声音
else begin sound<=sound+1; ear<=0; end
end
always @(posedge clk_2Hz) //由 4Hz 的输入时钟产生 1Hz 的时基信号
clk_1Hz<=~clk_1Hz;
always @(posedge mode) //mode 信号控制系统在三种功能间转换
begin if(m==2) m<=0; else m<=m+1; end
always @(posedge turn)
fm<=~fm;
always
begin
case(m)
2: begin if(fm)
//该进程产生 count1,count2,counta,countb 四个信号
end
begin count1<=change; {LD_min,LD_hour}<=2; end
else
begin counta<=change; {LD_min,LD_hour}<=1; end
{count2,countb}<=0;
1: begin if(fm)
begin count2<=change; {LD_min,LD_hour}<=2; end
else
begin countb<=change; {LD_min,LD_hour}<=1; end
{count1,counta}<=2'b00;
end
default: {count1,count2,counta,countb,LD_min,LD_hour}<=0;
endcase
end
程序文本
always @(negedge clk)
//如果长时间按下“change”键,则生成“num1”信号用于连续快速加 1
if(count2) begin
if(loop1==3) num1<=1;
else
begin loop1<=loop1+1; num1<=0; end
end
else begin loop1<=0; num1<=0; end
always @(negedge clk)
if(countb) begin
if(loop2==3) num2<=1;
else
//产生 num2 信号
begin loop2<=loop2+1; num2<=0; end
end
else begin loop2<=0; num2<=0; end
always @(negedge clk)
if(count1) begin
if(loop3==3) num3<=1;
else
begin loop3<=loop3+1; num3<=0; end
end
else begin loop3<=0; num3<=0; end
always @(negedge clk)
if(counta) begin
if(loop4==3) num4<=1;
else
begin loop4<=loop4+1; num4<=0; end
end
else begin loop4<=0; num4<=0; end
assign ct1=(num3&clk)|(!num3&m_clk); //ct1 用于计时、校时中的分钟计数
assign ct2=(num1&clk)|(!num1&count2); //ct2 用于定时状态下调整分钟信号
assign cta=(num4&clk)|(!num4&h_clk); //cta 用于计时、校时中的小时计数
assign ctb=(num2&clk)|(!num2&countb); //ctb 用于定时状态下调整小时信号
always @(posedge clk_1Hz)
if(!(sec1^8'h59)|turn&(!m))
begin
//秒计时和秒调整进程
- 66 -
sec1<=0; if(!(turn&(!m))) minclk<=1;
end
else begin
//按住“turn”按键一段时间,秒信号可清零,该功能用于手动精确调时
if(sec1[3:0]==4'b1001)
begin sec1[3:0]<=4'b0000; sec1[7:4]<=sec1[7:4]+1; end
else sec1[3:0]<=sec1[3:0]+1; minclk<=0;
end
assign m_clk=minclk||count1;
always @(posedge ct1) //分计时和分调整进程
begin
if(min1==8'h59) begin min1<=0; hclk<=1; end
else begin
if(min1[3:0]==9)
begin min1[3:0]<=0; min1[7:4]<=min1[7:4]+1; end
else min1[3:0]<=min1[3:0]+1; hclk<=0;
end
end
assign h_clk=hclk||counta;
always @(posedge cta)
if(hour1==8'h23) hour1<=0;
else if(hour1[3:0]==9)
//小时计时和小时调整进程
begin hour1[7:4]<=hour1[7:4]+1; hour1[3:0]<=0; end
else hour1[3:0]<=hour1[3:0]+1;
always @(posedge ct2)
if(amin==8'h59) amin<=0;
else if(amin[3:0]==9)
//闹钟定时功能中的分钟调节进程
begin amin[3:0]<=0; amin[7:4]<=amin[7:4]+1; end
else amin[3:0]<=amin[3:0]+1;
always @(posedge ctb)
if(ahour==8'h23) ahour<=0;
else if(ahour[3:0]==9)
//闹钟定时功能中的小时调节进程
always
begin ahour[3:0]<=0; ahour[7:4]<=ahour[7:4]+1; end
else ahour[3:0]<=ahour[3:0]+1;
//闹铃功能
if((min1==amin)&&(hour1==ahour)&&(amin|ahour)&&(!change))
//若按住“change”键不放,可屏蔽闹铃音
if(sec1<8'h20) alert1<=1; //控制闹铃的时间长短
else alert1<=0;
else alert1<=0;
always
case(m)
//时、分、秒的显示控制
3'b00: begin hour<=hour1; min<=min1; sec<=sec1; end
//计时状态下的时、分、秒显示
3'b01: begin hour<=ahour; min<=amin; sec<=8'hzz; end
//定时状态下的时、分、秒显示
3'b10: begin hour<=hour1; min<=min1; sec<=8'hzz; end
//校时状态下的时、分、秒显示
endcase
assign LD_alert=(ahour|amin)?1:0; //指示是否进行了闹铃定时
assign alert=((alert1)?clk_1k&clk:0)|alert2; //产生闹铃音或整点报时音
always
begin
//产生整点报时信号 alert2
if((min1==8'h59)&&(sec1>8'h54)||(!(min1|sec1)))
if(sec1>8'h54) alert2<=ear&clk_1k; //产生短音
else alert2<=!ear&clk_1k;
else alert2<=0;
end
endmodule
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
NCL30000单段式功率因数校正LED驱动器原理及TRIAC调光LED驱动器设计方案(上)
NCL30000单段式功率因数校正LED驱动器原理及TRIAC调光LED驱动器设计方案(下)
Keil C51 V7.0中文界面汉化程序
电源产品的可靠性设计(上)
电源产品的可靠性设计(中)
Keil C51 V7.0安装程序(2K代码限制)
SCALE驱动器的半桥接线图
[下载]有DSP下载原理图免费下载
Keil C51 安装程序 版本6.12(2k代码限制)
应用材料携手美光 加速HBM、闪存及DRAM技术研发
发布一款真正的bootloader软件
伊朗局势紧张,亚洲汽车供应链面临冲击
Nordic扩展nRF54L系列,推出入门级低功耗蓝牙SoC
更快实现HD触觉反馈集成:24小时从概念到功能原型
请问8019网卡寄存器的定义
SCALE驱动器接线图
EXB系列驱动器的功能方框图
Keil C51 V7.0中文汉化程序
vivi能做2410的nor flash 启动吗?
Ceva新一代UWB IP具有更远的传输距离和更高的吞吐量
Groq向三星提出AI芯片扩产需求,推论芯片市场或迎爆发
Emerson推出NI USRP X420软件定义无线电
SEALSQ推出量子系统PQC栈
专业PCB抄板、设计、开模、开测试架一条龙服务!
EXB841的原理图
电动汽车磁铁市场预计到2030年达到95亿美元
电源产品的可靠性设计(下)
IAR扩展嵌入式开发平台,推出面向安全关键型应用的长期支持(LTS)服务
Keil C51 V7.07a中文界面汉化程序
IGBT的驱动保护电路