基于FPGA的自动打铃系统的设计与实现.docx
《基于FPGA的自动打铃系统的设计与实现.docx》由会员分享,可在线阅读,更多相关《基于FPGA的自动打铃系统的设计与实现.docx(17页珍藏版)》请在冰豆网上搜索。
基于FPGA的自动打铃系统的设计与实现
自动打铃系统设计说明书
学生姓名:
罗衡
学号:
14092500060
专业班级:
电子09-2BF
报告提交日期:
2011-11-28
湖南理工学院物电学院
一、题目及要求简介···············································1
1.设计题目····················································1
2.总体要求简介················································1
二、设计方案说明·················································1
三、各部分功能介绍及程序·······································2
1.系统框图····················································2
2.选择的FPGA芯片及配置·······································2
3.各模块(元件)说明··········································2
四、仿真结果·····················································4
1.计时进位····················································4
2.手动校时····················································5
3.六点整闹铃··················································5
五、说明··························································5
1.输入激励信号说明············································5
2.输出结果说明················································6
六、源程序························································6
1.顶层模块····················································6
2.模式控制子模块··············································7
3.计时及调整子模块············································8
4.闹铃及调整子模块············································10
5.显示子模块··················································11
七、参考文献·····················································14
一、设计题目及要求简介
1.设计题目
基于FPGA的自动打铃系统的设计与实现
2.总体要求简介
(1)基本计时和显示功能
①24小时制显示
②动态扫描显示
③显示格式:
88-88-88
(2)能设置当前时间(含时、分)
(3)能实现基本打铃功能,上午06:
00起床铃,打铃5秒
二、设计方案说明
本系统采用自顶向下的模块化设计方法,将数字闹钟按照功能实现分为模式控制模块、计时及调整模块、闹铃及调整模块、显示模块。
系统调整部分软件控制流程示意图如图2-1所示。
图2-1
三、各部分功能介绍及程序
1.系统框图
顶层电路主要由FPGA实现,输出信号接到八位数码管、LED指示灯及扬声器上,系统框图如图3-1所示。
图3-1
2.选择的FPGA芯片及配置
本系统选择ACEX1K系列的EP1K10TC100-3芯片,由于FPGA器件是基于SRAM结构的,具有易失性,在此采用被动串行配置(PS)方式,由外部的计算机控制配置过程,使用USB-Blaster下载电缆下载程序。
3.各模块(元件)说明
3.1顶层文件端口说明
modulealarmclock(clk,clk_1k,mode,change,turn,sel,decodeout,alert,
LD_alert,LD_hour,LD_min);
inputclk,clk_1k,mode,change,turn;
outputalert,LD_alert,LD_hour,LD_min;
output[2:
0]sel;
output[7:
0]decodeout;
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;
regLD_alert,LD_hour,LD_min;
regclk_1HZ,clk_2HZ,minclk,hclk;
regalert1,ear;
regcount1,count2,counta,countb;
wirect1,ct2,cta,ctb,m_clk,h_clk;
reg[2:
0]sel;
reg[7:
0]decodeout;
3.2顶层文件引脚映射说明
输入引脚5个,输出引脚15个,映射关系如图3-2所示。
图3-2
3.23各子模块说明
①模式控制子模块
此模块通过mode信号0、1、2三种状态的控制,使系统分别在计时、闹铃、校时三种模式下工作。
②计时及调整子模块
当mode信号为0时,在基准时钟信号clk下,系统按60进制加1计时;当mode信号为2时,若检测到turn信号的脉冲时,在校对小时和分钟之间作切换,当前的调整状态可通过LD_hour或LD_min指示灯查看,change信号每来一个脉冲,计数器加1,这样可以将系统当前的时间调到任意时刻。
③闹铃及调整子模块
此模块下,mode信号为2,当检测到turn信号的脉冲时,闹铃定时在小时和分钟之间作切换,当前的调整状态可通过LD_hour或LD_min指示灯查看,change信号每来一个脉冲,计数器加1,这样可以给系统设置任意时刻的闹铃,设置完成之后LD_alert指示灯会常亮(注:
此模块程序中已经加入了六点整闹铃控制语句)。
④显示子模块
此模块用于将实时时间(包括调整过程中时钟的状态)输出到八位数码管中,通过sel信号位选的控制动态扫描显示当前时钟。
四、仿真结果
1.计时进位(以23:
59:
59为例)
当秒计时满59时,向分钟进位并重新开始计时;当分钟计时满59时,向小时进位并重新开始计时;当小时计时满23时,清零并重新开始计时,23:
59:
59时刻后从00:
00:
00重新开始计时,仿真波形如图4-1所示。
图4-1
2.手动校时(以06:
05为例)
给mode输入2个连续的高脉冲使系统进入校时模式,再给change输入6个连续高脉冲使小时调到六点,此过程中LD_hour指示灯亮,再给turn一个高脉冲切换到调分钟状态,再给change输入5个连续高脉冲使小时调到五分钟,此过程中LD_min指示灯亮,再给mode一个高脉冲回到计时模式,此后系统从06:
05分开始计时,仿真波形如图4-2所示。
图4-2
3.六点整闹铃
闹铃指示灯LD_alert常亮表明已经设置闹铃,06:
00开始闹铃5秒,仿真波形如图4-3所示。
图4-3
五、说明
1.输入激励信号说明
clk:
标准时钟信号;
clk_1k:
数码管扫描时钟;
mode:
功能模式控制信号,为0:
计时功能;
为1:
闹铃功能;
为2:
校时功能;
turn:
接按键,在手动校时功能时,选择调整小时/分钟;
change:
接按键,手动调整时,每按一次,计数器加1;
2.输出结果说明
alert:
输出到扬声器的信号,用于产生闹铃声;
sel:
数码管位选信号,选择当前要显示的位置;
decodeout:
数码管段选信号,显示当前数字;
LD_alert:
接LED,灯亮表示设置了闹铃;
LD_hour:
接LED,灯亮表示正在调整小时;
LD_min:
接LED,灯亮表示正在调整分钟。
六、源程序
1、顶层电路模块
modulealarmclock(clk,clk_1k,mode,change,turn,sel,decodeout,alert,
LD_alert,LD_hour,LD_min);
inputclk,clk_1k,mode,change,turn;
outputalert,LD_alert,LD_hour,LD_min;
output[2:
0]sel;
output[7:
0]decodeout;
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;
regLD_alert,LD_hour,LD_min;
regclk_1HZ,clk_2HZ,minclk,hclk;
regalert1,ear;
regcount1,count2,counta,countb;
wirect1,ct2,cta,ctb,m_clk,h_clk;
reg[2:
0]sel;
reg[7:
0]decodeout;
//调用子模块
modecontrolmodecontrol(mode,change,turn,m,count1,count2,counta,countb);
timertimer(m,clk,count1,counta,turn,hour1,min1,sec1);
bellbell(clk,ear,ct2,ctb,alert1,hour1,min1,sec1,ahour,amin);
displaydisplay(m,hour1,min1,sec1,ahour,amin,sel,decodeout);
endmodule
2.模式控制子模块
modulemodecontrol(mode,change,turn,m,count1,count2,counta,countb);
inputmode,change,turn;
outputm,count1,count2,counta,countb;
regcount1,count2,counta,countb;
regLD_hour,LD_min;
regfm,m;
always@(posedgemode)//控制系统在三种功能间转换
beginif(m==2)m<=0;elsem<=m+1;end
always@(posedgeturn)
fm<=~fm;
always//产生count1,count2,counta,countb四个信号
begin
case(m)
2:
beginif(fm)//校时模式
begincount1<=change;{LD_min,LD_hour}<=2;end
else
begincounta<=change;{LD_min,LD_hour}<=1;end
{counta,countb}<=0;
end
1:
beginif(fm)//闹铃模式
begincount2<=change;{LD_min,LD_hour}<=2;end
else
begincountb<=change;{LD_min,LD_hour}<=1;end
{count1,countb}<=2'b00;
end
default:
{count1,count2,counta,countb,LD_min,LD_hour}<=0;//计时模式
endcase
end
endmodule
3.计时及调整子模块
moduletimer(m,clk,count1,counta,turn,hour1,min1,sec1);
inputm,clk,count1,counta,turn;
output[7:
0]hour1,min1,sec1;
reg[1:
0]num3,num4,loop3,loop4;
regct1,cta;
regclk_1HZ,clk_2HZ,minclk,hclk,m_clk,h_clk;
always@(posedgeclk)
clk_2HZ<=~clk_2HZ;
always@(posedgeclk_2HZ)
clk_1HZ<=~clk_1HZ;
always@(negedgeclk)
if(count1)begin
if(loop3==3)num3<=1;
elsebeginloop3<=loop3+1;num3<=0;end
end
elsebeginloop3<=0;num3<=0;end
always@(negedgeclk)
if(counta)begin
if(loop4==3)num4<=1;
elsebeginloop4<=loop4+1;num4<=0;end
end
elsebeginloop4<=0;num4<=0;end
assignct1=(num3&clk)|(!
num3&m_clk);
//ct1用于及计时、较时中的分钟计数
assigncta=(num4&clk)|(!
num3&h_clk);
//cta用于及计时、较时中的小时计数
always@(posedgeclk_1HZ)//秒计时和秒调整进程
if(!
(sec1^8'h59)|turn&(!
m))
beginsec1<=0;if(!
(turn&(!
m)))minclk<=1;end
//按住"turn"秒信号清0
elsebegin
if(sec1[3:
0]==4'b1001)
beginsec1[3:
0]<=4'b0000;sec1[7:
4]<=sec1[7:
4]+1;end
elsesec1[3:
0]<=sec1[3:
0]+1;minclk<=0;
end
assignm_clk=minclk||count1;
always@(posedgect1)//分计时和分调整进程
begin
if(min1==8'h59)beginmin1<=0;hclk<=1;end
elsebeginif(min1[3:
0]==9)
beginmin1[3:
0]<=0;min1[7:
4]<=min1[7:
4]+1;end
elsemin1[3:
0]<=min1[3:
0]+1;hclk<=0;
end
end
assignh_clk=hclk||counta;
always@(posedgecta)//小时计时和小时调整进程
if(hour1==8'h23)hour1<=0;
elseif(hour1[3:
0]==9)
beginhour1[7:
4]<=hour1[7:
4]+1;hour1[3:
0]<=0;end
elsehour1[3:
0]<=hour1[3:
0]+1;
endmodule
4.闹铃及调整子模块
modulebell(clk,ear,ct2,ctb,alert1,hour1,min1,sec1,ahour,amin);
inputclk,ct2,ctb,count2,countb;
outputalert,ahour,amin;
reg[1:
0]num1,num2,loop1,loop2;
reg[7:
0]ahour,amin;
regct2,ctb;
regalert,alert1,ear,sound;
always@(posedgeclk)
begin
if(sound==3)beginsound<=0;ear<=1;end
//ear用于产生或屏蔽声音信号
elsebeginsound<=sound+1;ear<=0;end
end
always@(negedgeclk)
//如果长按"change"信号,则生成num1信号用于连续快速加1
if(count2)begin
if(loop1==3)num1<=0;
elsebeginloop1<=loop1+1;num1<=0;end
end
elsebeginloop1<=0;num1<=0;end
always@(negedgeclk)
if(countb)begin
if(loop2==3)num2<=1;
elsebeginloop2<=loop2+1;num2<=0;end
end
elsebeginloop2<=0;num2<=0;end
assignct2=(num1&clk)|(!
num1&count2);
//ct2用于定时状态下调整分钟信号
assignctb=(num2&clk)|(!
num2&countb);
//ctb用于定时状态下调整小时信号
always@(posedgect2)//闹钟定时功能中的分钟调整进程
if(amin==8'h59)amin<=0;
elseif(amin[3:
0]==9)
beginamin[7:
4]<=amin[7:
4]+1;amin[3:
0]<=0;end
elseamin[3:
0]<=amin[3:
0]+1;
always@(posedgectb)//闹钟定时功能中的小时调整进程
if(ahour==8'h23)ahour<=0;
elseif(ahour[3:
0]==9)
beginahour[7:
4]<=ahour[7:
4]+1;ahour[3:
0]<=0;end
elseahour[3:
0]<=ahour[3:
0]+1;
always
begin
ahour=8'h06;amin=8'h00;asec=8'h00;
end
always//六点钟闹铃,持续5秒
begin
if((hour1==ahour)&&(min1==8'h00)&&(sec1<8'h05))
alert1<=1;
elsealert1<=0;
end
assignalert=((alert1)?
clk_1k&clk:
0);//产生闹铃音
Endmodule
5.显示子模块
moduledisplay(m,hour1,min1,sec1,ahour,amin,sel,decodeout);
input[7:
0]hour1,min1,sec1,ahour,amin;
inputclk_1k;
output[2:
0]sel;
outputdecodeout;
reg[7:
0]hour,min,sec,hour1,min1,sec1,ahour,amin;
reg[23:
0]din;
reg[2:
0]sel;
reg[3:
0]dec;
reg[7:
0]decodeout;
always
case(m)
3'b00:
beginhour<=hour1;min<=min1;sec<=sec1;end
//计时状态下的时、分、秒显示
3'b01:
beginhour<=ahour;min<=amin;sec<=8'hzz;end
//定时状态下的时、分、秒显示
3'b10:
beginhour<=hour1;min<=min1;sec<=8'hzz;end
//校时状态下的时、分、秒显示
endcase
assignLD_alert=(ahour|amin)?
1:
0;//指示是否设置了闹铃
always@(posedgeclk_1k)
sel<=sel+1;//数码管扫描时钟
assigndin={hour,min,sec};
always@(sel,din)//数码管位选
begin
case(sel)
3'b000:
dec<=din[23:
20];//显示小时的十位
3'b001:
dec<=din[19:
16];//显示小时的个位
3'b010:
dec<=4'hf;//显示“-”符号
3'b011:
dec<=din[15:
11];//显示分钟的十位
3'b100:
dec<=din[11:
8];//显示分钟的个位
3'b101:
dec<=4'hf;//显示“-”符号
3'b110:
dec<=din[7:
4];//显示秒的十位
3'b111:
dec<=din[3:
0];//显示秒的个位
endcase
end
always@(dec)//数码管段选
begin
case(dec)
4'h0:
decodeout<=8'b00111111;
4'h1:
decodeout<=8'b00000110;
4'h2:
decodeout<=8'b01011011;
4'h3:
decodeout<=8'b01001111;
4'h4:
decodeout<=8'b01100110;
4'h5:
decodeout<=8'b01101101;
4'h6:
decodeout<=8'b01111101;
4'h7:
decodeout<=8'b00000111;
4'