基于FPGA的自动打铃系统的设计与实现.doc
自动打铃系统设计说明书学 生 姓 名:罗衡学 号:14092500060专 业 班 级:电子09-2BF报告提交日期:201111-28湖 南 理 工 学 院 物 电 学 院目录一、题目及要求简介···············································11. 设计题目····················································12。总体要求简介················································1二、设计方案说明·················································1三、各部分功能介绍及程序·······································21。系统框图····················································22.选择的FPGA芯片及配置·······································23。各模块(元件)说明··········································2四、仿真结果·····················································41.计时进位····················································42.手动校时····················································53。六点整闹铃··················································5五、说明··························································51。输入激励信号说明············································52。输出结果说明················································6六、源程序························································61.顶层模块····················································62. 模式控制子模块··············································73. 计时及调整子模块············································84. 闹铃及调整子模块············································105. 显示子模块··················································11七、参考文献·····················································14一、设计题目及要求简介1.设计题目基于FPGA的自动打铃系统的设计与实现2.总体要求简介(1)基本计时和显示功能 24小时制显示动态扫描显示显示格式:888888(2)能设置当前时间(含时、分)(3)能实现基本打铃功能,上午06:00起床铃,打铃5秒二、 设计方案说明本系统采用自顶向下的模块化设计方法,将数字闹钟按照功能实现分为模式控制模块、计时及调整模块、闹铃及调整模块、显示模块.系统调整部分软件控制流程示意图如图2-1所示。开始mode120校时功能闹铃功能计时功能调整小时LD_hour亮调整小时turn切换切换LD_min亮调整分钟调整分钟changeLD_alert亮返回计时返回计时图2-1三、 各部分功能介绍及程序1。系统框图顶层电路主要由FPGA实现,输出信号接到八位数码管、LED指示灯及扬声器上,系统框图如图31所示。Altera AlertLD_alertLD_hourLD_minseldecodeoutclkclk_1k mode turn change顶层模块八位数码管显示模块图312. 选择的FPGA芯片及配置本系统选择ACEX1K系列的EP1K10TC100-3芯片,由于FPGA器件是基于SRAM结构的,具有易失性,在此采用被动串行配置(PS)方式,由外部的计算机控制配置过程,使用USBBlaster下载电缆下载程序。3.各模块(元件)说明3。1 顶层文件端口说明module alarmclock(clk,clk_1k,mode,change,turn,sel,decodeout,alert,LD_alert,LD_hour,LD_min);input clk,clk_1k,mode,change,turn;output alert,LD_alert,LD_hour,LD_min;output2:0 sel;output7:0 decodeout;reg7:0 hour,min,sec,hour1,min1,sec1,ahour,amin;reg1:0 m,fm,num1,num2,num3,num4;reg1:0 loop1,loop2,loop3,loop4,sound;reg LD_alert,LD_hour,LD_min;reg clk_1HZ,clk_2HZ,minclk,hclk;reg alert1,ear;reg count1,count2,counta,countb;wire ct1,ct2,cta,ctb,m_clk,h_clk;reg 2:0 sel;reg 7:0 decodeout;3。2 顶层文件引脚映射说明输入引脚5个,输出引脚15个,映射关系如图32所示。图323。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重新开始计时,仿真波形如图41所示.图4-12. 手动校时(以06:05为例)给mode输入2个连续的高脉冲使系统进入校时模式,再给change输入6个连续高脉冲使小时调到六点,此过程中LD_hour指示灯亮,再给turn一个高脉冲切换到调分钟状态,再给change输入5个连续高脉冲使小时调到五分钟,此过程中LD_min指示灯亮,再给mode一个高脉冲回到计时模式,此后系统从06:05分开始计时,仿真波形如图4-2所示。图423. 六点整闹铃闹铃指示灯LD_alert常亮表明已经设置闹铃,06:00开始闹铃5秒,仿真波形如图43所示。图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);input clk,clk_1k,mode,change,turn;output alert,LD_alert,LD_hour,LD_min;output2:0 sel;output7:0 decodeout;reg7:0 hour,min,sec,hour1,min1,sec1,ahour,amin;reg1:0 m,fm,num1,num2,num3,num4;reg1:0 loop1,loop2,loop3,loop4,sound;reg LD_alert,LD_hour,LD_min;reg clk_1HZ,clk_2HZ,minclk,hclk;reg alert1,ear;reg count1,count2,counta,countb;wire ct1,ct2,cta,ctb,m_clk,h_clk;reg 2:0 sel;reg 7:0 decodeout;/调用子模块modecontrol modecontrol(mode,change,turn,m,count1,count2,counta,countb);timer timer(m,clk,count1,counta,turn,hour1,min1,sec1);bell bell(clk,ear,ct2,ctb,alert1,hour1,min1,sec1,ahour,amin);display display(m,hour1,min1,sec1,ahour,amin,sel,decodeout);endmodule2。模式控制子模块module modecontrol(mode,change,turn,m,count1,count2,counta,countb);input mode,change,turn;output m,count1,count2,counta,countb;reg count1,count2,counta,countb;reg LD_hour,LD_min;reg fm,m;always (posedge mode) /控制系统在三种功能间转换begin if(m = 2) m <= 0;else m = m+1; end always (posedge turn)fm<= fm;always /产生count1,count2,counta,countb四个信号begincase(m)2:begin if(fm)/校时模式begin count1 <= change; LD_min,LD_hour = 2; endelsebegin counta = change; LD_min,LD_hour <= 1; endcounta,countb = 0; end1:begin if(fm)/闹铃模式begin count2 <= change; LD_min,LD_hour = 2; endelse begin countb = change; LD_min,LD_hour <= 1; end count1,countb <= 2b00; end default:count1,count2,counta,countb,LD_min,LD_hour <= 0; /计时模式endcaseendendmodule3。计时及调整子模块module timer(m,clk,count1,counta,turn,hour1,min1,sec1);input m,clk,count1,counta,turn;output7:0 hour1,min1,sec1;reg1:0 num3,num4,loop3,loop4;reg ct1,cta;reg clk_1HZ,clk_2HZ,minclk,hclk,m_clk,h_clk;always (posedge clk)clk_2HZ<=clk_2HZ;always (posedge clk_2HZ) clk_1HZ<=clk_1HZ;always (negedge clk)if(count1)begin if(loop3 = 3) num3 <= 1;else begin loop3 = loop3+1;num3 = 0; endendelse begin loop3 = 0; num3 = 0; endalways (negedge clk)if(counta)begin if(loop4 = 3) num4 <= 1;else begin loop4 = loop4 + 1; num4 <= 0; endendelse begin loop4 <= 0;num4 <= 0; endassign ct1=(num3&clk)|(!num3m_clk);/ct1用于及计时、较时中的分钟计数assign cta=(num4&clk)|(!num3&h_clk);/cta用于及计时、较时中的小时计数always (posedge clk_1HZ)/秒计时和秒调整进程if(!(sec18h59)turn(!m)begin sec1 <= 0; if(!(turn(!m) minclk = 1; end /按住"turn”秒信号清0else begin if(sec13:0 = 4'b1001)begin sec13:0 = 4'b0000; sec17:4 <= sec17:4 + 1;end else sec13:0 <= sec13:0 + 1; minclk <= 0; endassign m_clk = minclk | count1;always (posedge ct1)/分计时和分调整进程beginif(min1 = 8h59) begin min1 <= 0;hclk <= 1; endelse begin if(min13:0 = 9)begin min13:0 = 0; min17:4 = min17:4 + 1; endelse min13:0 = min13:0 + 1; hclk = 0;endendassign h_clk = hclk counta;always (posedge cta)/小时计时和小时调整进程 if(hour1 = 8h23) hour1 <= 0; elseif(hour13:0 = 9)begin hour17:4 = hour17:4 + 1; hour13:0 <= 0; endelse hour13:0 = hour13:0 + 1; endmodule4。闹铃及调整子模块module bell(clk,ear,ct2,ctb,alert1,hour1,min1,sec1,ahour,amin);input clk,ct2,ctb,count2,countb;outputalert,ahour,amin;reg1:0 num1,num2,loop1,loop2;reg7:0 ahour,amin;reg ct2,ctb;reg alert,alert1,ear,sound;always (posedge clk)begin if(sound = 3) begin sound = 0;ear<=1; end /ear用于产生或屏蔽声音信号else begin sound <= sound + 1;ear <= 0; end endalways (negedge clk) /如果长按”change”信号,则生成num1信号用于连续快速加1if(count2)begin if(loop1 = 3) num1 <= 0;else begin loop1 = loop1 + 1;num1 = 0; endendelse begin loop1 <= 0; num1 <= 0; endalways (negedge clk)if(countb)beginif(loop2 = 3)num2 = 1;else begin loop2 <= loop2+1;num2 = 0;endendelse begin loop2 = 0; num2 <= 0; endassign ct2 = (num1&clk)|(!num1count2);/ct2用于定时状态下调整分钟信号assign ctb = (num2&clk)|(!num2countb);/ctb用于定时状态下调整小时信号always (posedge ct2)/闹钟定时功能中的分钟调整进程if(amin = 8h59) amin = 0;elseif(amin3:0 = 9)begin amin7:4 <= amin7:4 + 1; amin3:0 <= 0; endelse amin3:0 = amin3:0 + 1; always (posedge ctb)/闹钟定时功能中的小时调整进程if(ahour = 8'h23) ahour <= 0;elseif(ahour3:0 = 9)begin ahour7:4 = ahour7:4 + 1; ahour3:0 <= 0; endelse ahour3:0 = ahour3:0 + 1; always begin ahour=8h06;amin=8'h00;asec=8'h00; endalways /六点钟闹铃,持续5秒 begin if((hour1=ahour)(min1=8'h00)&(sec18'h05)) alert1=1; else alert1=0; end assign alert=((alert1)?clk_1kclk:0); /产生闹铃音 Endmodule5。显示子模块module display(m,hour1,min1,sec1,ahour,amin,sel,decodeout);input7:0 hour1,min1,sec1,ahour,amin;input clk_1k;output2:0 sel;output decodeout;reg7:0 hour,min,sec,hour1,min1,sec1,ahour,amin;reg23:0 din;reg2:0 sel;reg3:0 dec;reg7:0 decodeout;alwayscase(m)3'b00: begin hour = hour1; min <= min1; sec = sec1; end/计时状态下的时、分、秒显示3b01: begin hour <= ahour; min <= amin; sec = 8'hzz; end/定时状态下的时、分、秒显示3'b10: begin hour <= hour1; min <= min1; sec <= 8'hzz; end/校时状态下的时、分、秒显示endcaseassign LD_alert = (ahour|amin)?1:0; /指示是否设置了闹铃always (posedge clk_1k)sel<=sel+1;/数码管扫描时钟assign din=hour,min,sec;always (sel,din)/数码管位选begincase(sel)3b000: dec<=din23:20;/显示小时的十位3b001: dec<=din19:16;/显示小时的个位3'b010: dec<=4'hf; /显示“-"符号3'b011: dec<=din15:11;/显示分钟的十位3b100: dec=din11:8; /显示分钟的个位3b101: dec<=4hf; /显示“”符号3b110: dec=din7:4; /显示秒的十位 3b111: dec<=din3:0;/显示秒的个位endcaseendalways (dec)/数码管段选begincase(dec)4'h0:decodeout=8b00111111;4'h1:decodeout<=8b00000110;4'h2:decodeout<=8b01011011;4'h3:decodeout=8'b01001111;4h4:decodeout=8'b01100110;4h5:decodeout<=8'b01101101;4'h6:decodeout<=8b01111101;4'h7:decodeout=8b00000111;4h8:decodeout=8b01111111;4'h9:decodeout<=8b01101111;4'hf:decodeout=8b01000000;endcaseendendmodule七、参考文献1王金明,冷自强.EDA技术与Verilog设计.北京:科学出版社,2008。2夏宇闻.Verilog数字系统设计教程(第2版)。北京:北京航空航天大学出版社,2008。3康华光.电子技术基础数字部分(第五版).北京:高等教育出版社,2006.- 12 -