090910064-基于FPGA的多功能万年历
【优秀WORD论文】基于FPGA的全功能万年历电子钟的设计
基于FPGA的全功能万年历电子钟的设计提要本文主要介绍了基于FPGA的万年历电子钟的设计方案,从而介绍了可编程逻辑器件的发展及应用。
基于FPGA的电子钟的设计与实现介绍了基于FPGA芯片的系统设计,并对系统的软硬件构成、FPGA内部逻辑设计工作原理等进行了详细说明。
论文第一部分对FPGA进行概述,讲述了可编程逻辑器件的发展与应用及论文题目的意义、目的和内容编排;第二部分:叙述了系统设计方案,介绍了FPGA应用的特点和电子钟的方案概述及实现语言和调试平台MAX+plusⅡ开发工具;第三部分:叙述了基于FPGA的电子钟系统的设计的硬件设计和软件设计;第四部分:对系统实现的外围电路进行概述。
第五部分:再次说明本设计的系统方案和得到的结论。
目录第一章序论 (1)1.1研究目的和意义: (1)1.2可编程逻辑器件的发展与应用: (1)1.2.1可编程逻辑单元CLB (3)1.2.2输入/输出模块IOB (3)1.2.3可编程内部连线PI (4)1.2.4 FPGA芯片的特点 (4)1.3FPGA国内外的发展状况及应用 (5)1.4本课题所能实现的功能: (8)第二章总体方案的设计 (9)2.1万年历电子钟的设计原理: (9)2.2FPGA的设计方法 (11)2.2.1 FPGA的器件设计流程 (11)2.2.2 MAX+plusⅡ开发工具 (13)2.2.3 VHDL语言 (17)2.3系统设计方案 (18)第三章系统的硬件设计与实现 (19)3.1功能模块设计 (19)3.2系统功能实现 (21)3.2.1底层元件设计 (22)3.2.2顶层元件设计 (32)3.3芯片的选择 (41)第四章设计应用电路 (45)4.1整体电路 (45)4.2电源电路 (46)4.3键盘部分 (49)4.4主动配置电路 (53)第五章总结 (61)5.1概述: (61)5.2设计方案: (62)参考文献 (64)致谢 (67)摘要 (I)ABSTRACT (II)第一章序论1.1研究目的和意义:通过对FPGA的了解,我们要应用FPGA来设计全功能万年历的设计,主要实现电子钟的所有功能,万年历是一种应用非常广泛的日常计时工具,具有时分秒计时功能,还有日历、年历功能,涉及计数、显示、参数输入技术,能够实时显示年、月、日和时间,并具有校准和闹铃等功能。
基于PFGA的万年历的设计
郑州大学西亚斯国际学院本科毕业论文(设计)题目基于FPGA的万年历的设计指导教师周晓平职称讲师学生姓名陈重学号20111521131 专业电子信息工程班级电信(1)班院(系)电子信息工程学院完成时间2015年4月7号基于FPGA的万年历的设计摘要基于FPGA的万年历的设计,基本功能是用来显示年月日时分秒及时间修改功能。
数字日历是采用数字电路实现对ho、mi、se计时的装置,主要包括组合逻辑电路与时序电路,主要完成的功能是使用VerilogHDL语言,在QuartusII上完成电路设计,模拟程序开发,基本功能是能够显示/修改ho、mi、se,主要有:主要遥控模块、时间及其数据显示调设、时间多路选择、显示调整、日期的自动工作与设置、秒表计时模块、钟表模块、频率选取模块、译码器组成万年历的系统电路设计。
软件模拟直接在FPGA软件上进行编译仿真与实验开发板共同完成。
对于程序的编写使用VerilogHDL语言,根据不同模块的功能和各个模块之间的相互作用控制关系进行编译仿真。
电子万年历是采用的是以秒表计时显示时间的工具,大量运用于居室、办公室、商场、汽车站、火车站等场合。
与古老的钟表进行比较拥有较好的精准性、灵活性、美观性、并拥有较长的使用年限。
数字万年历主要包括组合逻辑电路与时序电路,还能展现自动报警、定时广播信息等功能。
数字电子万年历采用软件开发模拟,使开发生产的成本大大降低,而且功能上有很强的灵活性,如果想改变它的功能只需要在软件上进行修改就能完成。
相对于老式钟表来讲精度大大增加,并且维修改动更为方便,也不用像日历一样每天翻页,使人们的的生活更加方便。
因此研究数字万年历有非常重要现实意义,匹配当前电子仪器的开发优势,对于当前市场也有相当大的潜力。
关键词FPGA /万年历/VerilogHDL/QuartusIIBASED ON THE DESIGN OF THECALENDARFPGA CIRCULTABSTRACTCalendar design based on FPGA, which basic function is to display date with the change of time. Digital calendar is realized by using digital circuit to record time . Digital circuits mainly includes the combinational logic and sequential circuits , Its main task is to use VerilogHDL language to complete circuit design and simulation on the QuartusII .its basic function is to be able to display or modify time Circuit is divided into combination logic andsequential,mainlyincludefrequency division ,control ,adjustment of time display ,date ,time ,display control ,code translator.software simulation directly conducted on QuartusII and FPGA adaptor .For the writing of the program use VerilogHDL language ,according to the features of different modules and interaction control of the relationship between various modules compiled simulation.The digital Calendar is realized by using digital circuit minutes and seconds for timing device .it is widely used in home .office shopping malls ,railway stations etc .Compared with the old clock has better accuracy ,flexibility ,beautiful and has a longer life ,The digital calendar mainly includes the assembly logic circuit and sequential circuits ,also can show the function such as automatic alarm, timing ,broadcast , information. The digital calendar adopts the model of software develop the modifications will finish on the software ,it makes the cost greatly reduced and the function has a strong flexibility .If you want to change its function as long as modifying on the software.Relative to the old clock precision is greatly precision and the maintenance is more convenient to change ,also need not every day turn over a calendar page ,making people’s life more convenient .So significance to research the digital calendar its application has a broad market prospect.KEYWORDS FPGA ,C alendar ,VerilogHDL ,QuartusII目录中文摘要 (Ⅰ)英文摘要 (II)1 FPGA及数字电子万年历简介 (3)1.1 FPGA简介 (3)1.2 数字电子万年历的未来发展 (4)2 数字电子万年历的工作原理 (5)3 数字电子万年历各功能模块的实现 (6)3.1 时钟类型 (6)3.2 数字电子万年历的主要系统 (8)3.3 数字电子万年历主控制模块 (8)3.4 时间及其数据设置模块 (9)3.4.1 时间模块 (9)3.4.2 时间设置模块 (11)3.4.3 时间数据与时间设置数据多路选择模块 (12)3.5 时间显示动态位选模块 (14)3.6 显示模块 (15)3.7 秒表模块 (16)3.8 日期显示设置模块 (17)3.8.1 日期自动工作模块 (17)3.8.2 日期设置模块 (18)3.9 闹钟模块 (19)3.10 分频模块 (20)致谢 (23)参考文献 (24)附录 (25)1 FPGA及数字电子万年历简介1.1FPGA简介FPGA是现场可编程门列阵(Field programmable gates array)的简单缩写,是CPLD、PAL等数字元器件原有上的进步,是由可编程模块组成的专用进制式线路,属于半定制的电路。
基于FPGA的数字日历设计
基于FPGA的数字日历设计
基于FPGA设计数字日历可以实现以软件方式设计硬件的目的,无需购买专用数字芯片,从而克服了传统利用多片数字集成电路设计数字日历存在
焊接麻烦、调试繁琐、成本较高等问题。
而且,基于FPGA的数字日历与传统系统相比,在设计灵活、开发速度、降低成本、计时精度、功能实现上都得到
大幅度提升,能够更好地满足人们日常生活的需要。
本文介绍如何利用VHDL硬件描述语言设计一个具有年、月、日、星期、时、分、秒计时显示功能,时间调整功能和整点报时功能的数字日历。
在QuartusⅡ开发环境下,采用自顶向下的设计方法,建立各个基本模块,再构建成一个完整的基于FPGA设计的数字日历的顶层模块,然后对其进行编译、仿真、引脚锁定,最终下载到可编程逻辑器件上进行结果验证。
1数字日历整体设计方案
基于FPGA的数字日历设计分为硬件设计和软件设计两大部分。
其原理框
2数字日历的工作原理
首先由外部振荡器产生稳定的高频脉冲信号,作为数字日历的时间基准,然后经过分频器输出标准秒脉冲,输入到FPGA的CLOCK端,实现计数。
当秒计数器满60后向分计数器进位,分计数器满60后向小时计数器进位,小时计数器按照24进1规律计数。
计满后各计数器清零,重新计数。
日部分由于
日有28天、29天、30天、31天4种情况,故日由年和月共同判断其天数,日计满后向月进位,月满后向年进位。
计数器的输出分别经译码器送数码管显示。
计时出现误差时,可以用校时电路校时、校分、校秒和校年、校月、校日。
基于fpga的LCD显示万年历
接着我的上一篇博文,终于完善好了,前几天太忙了,没有及时上传,呵呵,今天晚上刚比较早刚好凌晨,及时上传一下,实现了从0000---9999年的时钟,其实万年历和十万年历,都是差不多,等到地球能转到9999年再改代码也不迟,哈哈!!我这里有顶层和底层文件,顶层主要是调用模块和做按键处理,具体按键防抖动原理,参见偶的以前的博文,我写完这个万年历的代码,还没来得及优化,占用了太多了逻辑门,可以进一步优化。
大致思路是:第一次按下KEY1 的时候,所有计时停止,再按KEY1,年就闪烁,按下KEY2和KEY3 进行加减。
再按KEY1,月就闪烁,按下KEY2和KEY3 进行加减........依次为调年-月-日-星期-时分秒,再次按一下KEY1,进入正常运行模式。
好了先上顶层模块module LCD(rst,clk,rw,rs,en,data,key1,key2,key3);input clk,rst;input key1,key2,key3;output rs,en,rw;output [7:0] data;reg key1_out,key2_out,key3_out;wire clk,rst;wire rs,en,rw;wire [7:0] data;disp U1(.clk(clk),.rst(rst),.rs(rs),.en(en),.rw(rw),.data(data),.key1(key1_out),.key2(key2_out),.key3(key3_out));//=============key1,key2,key3 按键防抖动================// reg key1_reg1,key1_reg2;reg key2_reg1,key2_reg2;reg key3_reg1,key3_reg2;reg [31:0] count;always @(posedge clk)begincount<=count+1;if(count==500000)begincount<=0;key1_reg1<=key1;key2_reg1<=key2;key3_reg1<=key3;endkey1_reg2<=key1_reg1;key2_reg2<=key2_reg1;key3_reg2<=key3_reg1;key1_out <= key1_reg2 & (!key1_reg1);key2_out <= key2_reg2 & (!key2_reg1);key3_out <= key3_reg2 & (!key3_reg1);endendmodule底层模块:module disp(rst,clk,rw,rs,en,data,key1,key2,key3);input clk,rst;input key1,key2,key3;output rs,en,rw;output [7:0] data;reg rs,en_sel;reg [7:0] data;reg [14:0] year;reg [7:0] shi,fen,miao,month,dat;reg [31:0]count,count1; //LCD CLK 分频计数器reg lcd_clk;//2行32个数据寄存器reg [7:0]one_1,one_2,one_3,one_4,one_5,one_6,one_7,one_8,one_9,one_10,one_11,one_12,on e_13,one_14,one_15,one_16;reg [7:0]two_1,two_2,two_3,two_4,two_5,two_6,two_7,two_8,two_9,two_10,two_11,two_12,two_ 13,two_14,two_15,two_16;reg [7:0] next;parameter state0 =8'h00, //设置8位格式,2行,5*7 8'h38;state1 =8'h01, //整体显示,关光标,不闪烁8'h0C 闪烁8'h0estate2 =8'h02, //设定输入方式,增量不移位8'h06state3 =8'h03, //清除显示8'h01state4 =8'h04, //显示第一行的指令80Hstate5 =8'h05, //显示第二行的指令80H+40Hscan =8'h06,nul =8'h07;parameter data0 =8'h10, //2行32个数据状态data1 =8'h11,data2 =8'h12,data3 =8'h13,data4 =8'h14,data5 =8'h15,data6 =8'h16,data7 =8'h17,data8 =8'h18,data9 =8'h19,data10 =8'h20,data11 =8'h21,data12 =8'h22,data13 =8'h23,data14 =8'h24,data15 =8'h25,data16 =8'h26,data17 =8'h27,data18 =8'h28,data19 =8'h29,data20 =8'h30,data21 =8'h31,data22 =8'h32,data23 =8'h33,data24 =8'h34,data25 =8'h35,data26 =8'h36,data27 =8'h37,data28 =8'h38,data29 =8'h39,data30 =8'h40,data31 =8'h41;initialbegin//第一行显示年-月-日星期//Mon Tue Wed Thur Fri Sat Sunone_1<=" "; one_2<=" "; one_3<=" "; one_4<=" "; one_5<="-"; one_6<=" "; one_7<=" "; one_8<="-";one_9<=" ";one_10<=" ";one_11<=" ";one_12<=" ";one_13<=" ";one_14<="";one_15<=" ";one_16<=" ";//第二行显示Clock:00-00-00two_1<="C"; two_2<="l"; two_3<="o"; two_4<="c"; two_5<="k"; two_6<=":"; two_7<=" "; two_8<=" ";two_9<="-";two_10<=" ";two_11<=" ";two_12<="-";two_13<=" ";two_14<="";two_15<=" ";two_16<=" ";shi<=8'd0;fen<=8'd0;miao<=8'd0;end//======================产生LCD 时序脉冲=========================== always @ (posedge clk ) //获得LCD时钟begincount<=count+1;if(count==32'd50000)begincount<=32'b0;lcd_clk<=~lcd_clk;endend//=====================产生闪烁扫描时钟===========================reg [31:0] count2;reg scan_flag;always @ (posedge clk or negedge rst) //获得校准时间选中闪烁状态beginif(!rst)beginscan_flag<=1'b0;endelsebegincount2<=count2+1;if(count2==32'd1*******)begincount2<=32'b0;scan_flag<=~scan_flag;endendend//====================产生按键标志位================================= reg [3:0] flag;always @ (posedge clk or negedge rst )beginif(!rst)beginflag<=4'b0;endelseif(key1)beginflag<=flag+1'b1;if(flag==4'b1000)flag<=4'b0000;endend//===================计时以及校准=======================================reg[3:0] week;reg[7:0] dat_flag;always @ (posedge clk or negedge rst ) //时钟计数器beginif(!rst)begin //初始化显示第一行2012-05-19 Sat 第二行:Clock:00-00-00 shi<=8'b0;fen<=8'b0;miao<=8'b0;month<=8'd5;dat<=8'd19;year<=16'd2012;week<=4'd5;count1<=1'b0;two_7<= (shi/8'd10)+8'b00110000;two_8<= (shi%8'd10)+8'b00110000;two_10<=(fen/8'd10)+8'b00110000;two_11<=(fen%8'd10)+8'b00110000;two_13<=(miao/8'd10)+8'b00110000;two_14<=(miao%8'd10)+8'b00110000;one_1<=(year/16'd1000)+8'b00110000;one_2<=((year%16'd1000)/16'd100)+8'b00110000;one_3<=((year%16'd100)/8'd10)+8'b00110000;one_4<=(year%8'd10)+8'b00110000;one_6<=(month/8'd10)+8'b00110000;one_7<=(month%8'd10)+8'b00110000;one_9<=(dat/8'd10)+8'b00110000;one_10<=(dat%8'd10)+8'b00110000;endelsebegintwo_7<= (shi/8'd10)+8'b00110000;two_8<= (shi%8'd10)+8'b00110000;two_10<=(fen/8'd10)+8'b00110000;two_11<=(fen%8'd10)+8'b00110000;two_13<=(miao/8'd10)+8'b00110000;two_14<=(miao%8'd10)+8'b00110000;one_1<=(year/16'd1000)+8'b00110000;one_2<=((year%16'd1000)/16'd100)+8'b00110000;one_3<=((year%16'd100)/8'd10)+8'b00110000;one_4<=(year%8'd10)+8'b00110000;one_6<=(month/8'd10)+8'b00110000;one_7<=(month%8'd10)+8'b00110000;one_9<=(dat/8'd10)+8'b00110000;one_10<=(dat%8'd10)+8'b00110000;// 判断是否为31天的月份if(month==8'd1||month==8'd3||month==8'd5||month==8'd7||month==8'd8||month==8'd10|| month==8'd12)dat_flag<=8'd31;// 判断是否为30天的月份else if(month==8'd4||month==8'd6||month==8'd9||month==8'd11)dat_flag<=8'd30;// 判断是否为闰年和平年else if(month==8'd2)beginif(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)dat_flag<=28;else dat_flag<=27;endcase (week)//星期//Mon Tue Wed Thu Fri Sat Sun4'b0000 : //1beginone_13<="M";one_14<="o";one_15<="n";end4'b0001 : //2beginone_13<="T";one_14<="u";one_15<="e";end4'b0010 : //3beginone_13<="W";one_14<="e";one_15<="d"; end4'b0011 : //4beginone_13<="T";one_14<="h";one_15<="u"; end4'b0100 : //5beginone_13<="F";one_14<="r";one_15<="i"; end4'b0101 : //6beginone_13<="S";one_14<="a";one_15<="t"; end4'b0110 : //7beginone_13<="S";one_14<="u";one_15<="n"; endendcasecase(flag)4'b0000 :beginen_sel<=1'b1;count1<=count1+1'b1;if(count1==32'd4*******)begincount1<=1'b0;miao<=miao+1'b1;if(miao==8'd59)beginmiao<=1'b0;fen<=fen+1'b1;if(fen==8'd59)beginfen<=1'b0;shi<=shi+1'b1;if(shi==8'd23)beginshi<=1'b0;dat<=dat+1'b1;week<=week+1'b1;if(week==4'b0110)week<=1'b1;if(dat==dat_flag)begindat<=8'd1;month<=month+1'b1;if(month==8'd12)beginmonth<=8'd1;year<=year+1'b1;if(year==16'd9999)year<=16'd0; //可以计1万年endendendendendendend4'b0001 :begincount1<=32'b0;//shi<=shi;fen<=fen;miao<=miao;year<=year;month<=month;dat<=dat;week<=week;end4'b0010 : //调年begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;one_1<=8'd20;one_2<=8'd20;one_3<=8'd20;one_4<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数beginyear<=year+1'b1;if(year==16'd9999)year<=16'd0;endif(key3) //减数beginyear<=year-1'b1;if(year==16'd0)year<=16'd9999;endend4'b0011 : //调月begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;one_6<=8'd20;one_7<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endcaseif(key2) //加数beginmonth<=month+1'b1;if(month==8'd12)month<=8'd0;endif(key3) //减数beginmonth<=month-1'b1;if(month==8'd0)month<=8'd12;endend4'b0100 : //调日begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;one_9<=8'd20;one_10<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数begindat<=dat+1'b1;if(dat==dat_flag)dat<=8'd0;endif(key3) //减数dat<=dat-1'b1;if(dat==8'd0)dat<=dat_flag;endend4'b0101 : //调星期begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;one_13<=8'd20;one_14<=8'd20;one_15<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数beginweek<=week+1'b1;if(week==4'd6)week<=4'd0;endif(key3) //减数beginweek<=week-1'b1;if(week==4'd0)week<=4'd7;endend4'b0110 : //调时begincase(scan_flag)begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;two_7<= 8'd20;two_8<= 8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数beginshi<=shi+8'b00000001;if(shi==8'd23)shi<=8'b0;endif(key3) //减数beginshi<=shi-8'b00000001;if(shi==8'b0)shi<=23;endend4'b0111 : //调分begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;two_10<=8'd20;two_11<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数beginfen<=fen+8'b00000001;if(fen==8'd59)fen<=8'b0;endif(key3) //减数beginfen<=fen-8'b00000001;if(fen==8'b0)fen<=59;endend4'b1000 : //调秒begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;two_13<=8'd20;two_14<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数beginmiao<=miao+8'b00000001;if(miao==8'd59)miao<=8'b0;endif(key3) //减数beginmiao<=miao-8'b00000001;if(miao==8'b0)miao<=59;endendendcaseendendalways @(posedge lcd_clk )begincase(next)state0 :begin rs<=1'b0; data<=8'h38; next<=state1; endstate1 :begin rs<=1'b0; data<=8'h0e; next<=state2; endstate2 :begin rs<=1'b0; data<=8'h06; next<=state3; endstate3 :begin rs<=1'b0; data<=8'h01; next<=state4; endstate4 :begin rs<=1'b0; data<=8'h80; next<=data0; end //显示第一行data0 :begin rs<=1'b1; data<=one_1; next<=data1 ; enddata1 :begin rs<=1'b1; data<=one_2; next<=data2 ; enddata2 :begin rs<=1'b1; data<=one_3; next<=data3 ; enddata3 :begin rs<=1'b1; data<=one_4; next<=data4 ; enddata4 :data5 :begin rs<=1'b1; data<=one_6; next<=data6 ; enddata6 :begin rs<=1'b1; data<=one_7; next<=data7 ; enddata7 :begin rs<=1'b1; data<=one_8; next<=data8 ; enddata8 :begin rs<=1'b1; data<=one_9; next<=data9 ; enddata9 :begin rs<=1'b1; data<=one_10; next<=data10 ; enddata10 :begin rs<=1'b1; data<=one_11; next<=data11 ; enddata11 :begin rs<=1'b1; data<=one_12; next<=data12 ; enddata12 :begin rs<=1'b1; data<=one_13; next<=data13 ; enddata13 :begin rs<=1'b1; data<=one_14; next<=data14 ; enddata14 :begin rs<=1'b1; data<=one_15; next<=data15 ; enddata15 :begin rs<=1'b1; data<=one_16; next<=state5 ; endstate5:begin rs<=1'b0;data<=8'hC0; next<=data16; end //显示第二行data16 :begin rs<=1'b1; data<=two_1; next<=data17 ; enddata17 :begin rs<=1'b1; data<=two_2; next<=data18 ; enddata18 :begin rs<=1'b1; data<=two_3; next<=data19 ; enddata19 :begin rs<=1'b1; data<=two_4; next<=data20 ; enddata20 :data21 :begin rs<=1'b1; data<=two_6; next<=data22 ; enddata22 :begin rs<=1'b1; data<=two_7; next<=data23 ; enddata23 :begin rs<=1'b1; data<=two_8; next<=data24 ; enddata24 :begin rs<=1'b1; data<=two_9; next<=data25 ; enddata25 :begin rs<=1'b1; data<=two_10; next<=data26 ; end data26 :begin rs<=1'b1; data<=two_11; next<=data27 ; end data27 :begin rs<=1'b1; data<=two_12; next<=data28 ; end data28 :begin rs<=1'b1; data<=two_13; next<=data29 ; end data29 :begin rs<=1'b1; data<=two_14; next<=data30 ; end data30 :begin rs<=1'b1; data<=two_15; next<=data31 ; end data31 :begin rs<=1'b1; data<=two_16; next<=scan ; endscan : //交替更新第一行和第二行数据beginnext<=state4;enddefault: next<=state0;endcaseendassign en=lcd_clk && en_sel;assign rw=1'b0;endmodule。
基于FPGA的万年历程序设计
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity clock isport(rst:in std_logic;clk:in std_logic;clr:in std_logic;display_mode: in std_logic;inc:in std_logic;mode:in std_logic;seg8:out std_logic_vector(7 downto 0);scan:out std_logic_vector(7 downto 0);led:out std_logic_vector(3 downto 0) );end;architecture one of clock is--signal state:std_logic_vector(2 downto 0);--signal dis_mode:std_logic_vector(1 downto 0);signal state:integer range 0 to 7;signal dis_mode:integer range 0 to 3;--signal qhh,qhl,qmh,qml,qsh,qsl,qy1,qy2,qy3,qy4,qm1,qm2,qd1,qd2:std_logic_vector(3 downto 0);signal qhh,qhl,qmh,qml,qsh,qsl,qy1,qy2,qy3,qy4,qmonl,qmonh,qdl,qdh:integer range 0 to 15; signal data:integer range 0 to 15 ;signal cnt:integer range 0 to 7;signal clk1khz,clk1hz,clk2hz,clk5ms:std_logic;--signal blink:std_logic_vector(2 downto 0);--signal inc_reg:std_logic;signal sec,min:integer range 0 to 59;signal hour:integer range 0 to 23;signal year:integer range 1 to 9999;signal month:integer range 1 to 12;signal day,day_limit:integer range 1 to 31;beginprocess(clk)variable count:integer range 0 to 30000;beginif clk'event and clk='1' thenif count=25000 then clk1khz<=not clk1khz;count:=0;else count:=count+1;end if;end if;end process;-------------------------------------------------------process (clk)variable cnte:integer range 0 to 30000000;beginif clk'event and clk ='1' thenif cnte=25000000 then clk1hz<=not clk1hz; cnte:=0;else cnte:=cnte+1;end if ;end if ;end process ;-----------------------------------------------------process (clk)variable cnt2:integer range 0 to 25000000;beginif clk'event and clk='1' thenif cnt2=12500000 then clk2hz<=clk2hz;cnt2:=0;else cnt2:=cnt2+1;end if ;end if ;end process;-----------------------------------------------------process(clk)variable cnnt:integer range 0 to 600000;beginif clk'event and clk='1' thenif cnnt=500000 then clk5ms<=clk5ms;cnnt:=0;else cnnt:=cnnt+1;end if ;end if ;end process;-----------------------------------------------------------------------------------------process(display_mode , clk1hz)beginif display_mode'event and display_mode='0' then dis_mode<=dis_mode+1;if dis_mode=1 thendis_mode<=0;end if;end if;end process;-------------------------------------------process(clk)beginyear<=year;month<= month;day<=day;hour<=hour;min<=min;sec<=sec;end process;-----------------------------------------process(mode , clr,clk1hz)beginif clr='0' thenstate<=0;elsif mode'event and mode='0' thenstate<=state+1;if state=6 thenstate<=0;end if;end if ;end process;----------------------------------------------------------------------------------- process(clk1hz,state,dis_mode,inc,clr,hour,sec,min,rst,year,month,day) beginif rst='0' thenyear<=2000;month<=2;day<=25;hour<=0;min<=0;sec<=0;--state<=0;--dis_mode<=0;elsif clr='0' thenhour<=23;min<=59;sec<=55;year<=4164;month<=1;day<=25;elsif clk1hz'event and clk1hz='1' thencase state iswhen 0 => led<="0000";if((month=1)or(month=3)or(month=5)or(month=7)or(month=8)or(month=10)or(month=12)) thenday_limit<=31;end if;if month=2 then----if((year%4==0&&year%100!=0)||(year%400==0))if ((((year rem 4)=0) and ((year rem 100)/=0)) or ((year rem 400=0))) thenday_limit<=29;elseday_limit<=28;end if;end if;if((month=4)or(month=6)or(month=9)or(month=11)) thenday_limit<=30;end if;sec<=sec+1;if sec=59 thensec<=0;min<=min+1;if min=59 thenmin<=0;hour<=hour+1;if hour =23 thenhour<=0;day<=day+1;if day=day_limit thenday<=1;month<=month+1;if month=12 thenmonth<=1;year<=year+1;if year=9999 thenyear<=1;end if;end if;end if;end if;end if;end if;--if sec=59 then sec<=0;--if min=59 then min<=0;--if hour=23 then hour<=0;--else--hour<=hour+1;--end if;--else--min<=min+1;--end if;--else--sec<=sec+1;--end if;when 1=> led<="0001";if inc='0' thenif hour=23 thenhour<=0;else hour<=hour+1;end if;end if;when 2=>led<="0010" ;if inc='0' thenif min=59 thenmin<=0;elsemin<=min+1;end if;end if;when 3=>led<="0011" ;if inc='0' thenif sec=59 thensec<=0;elsesec<=sec+1;end if;end if;when 4 =>led<="0100";if inc='0' thenif year=9999 thenyear<=1;elseyear<=year+1;end if;end if;when 5=> led <="0101";if inc='0' thenif month=12 thenmonth<=1;elsemonth<=month+1;end if;end if;when 6 =>led <="0110";if inc='0' thenif day=day_limit thenday<=1;elseday<=day+1;end if;end if;when others =>null;end case;end if;--end if;end process;---------------------------------------------------------------------- process(sec)begincase sec iswhen 0|10|20|30|40|50 => qsl<=0;when 1|11|21|31|41|51 => qsl<=1;when 2|12|22|32|42|52 => qsl<=2;when 3|13|23|33|43|53 => qsl<=3;when 4|14|24|34|44|54 => qsl<=4;when 5|15|25|35|45|55 => qsl<=5;when 6|16|26|36|46|56 => qsl<=6;when 7|17|27|37|47|57 => qsl<=7;when 8|18|28|38|48|58 => qsl<=8;when 9|19|29|39|49|59 => qsl<=9;when others =>null;end case;case sec iswhen 0|1|2|3|4|5|6|7|8|9 => qsh<=0;when 10|11|12|13|14|15|16|17|18|19 => qsh<=1;when 20|21|22|23|24|25|26|27|28|29 => qsh<=2;when 30|31|32|33|34|35|36|37|38|39 => qsh<=3;when 40|41|42|43|44|45|46|47|48|49 => qsh<=4;when 50|51|52|53|54|55|56|57|58|59 => qsh<=5;when others =>null;end case;end process;-------------------------------------------------------------------- process(min)begincase min iswhen 0|10|20|30|40|50 => qml<=0;when 1|11|21|31|41|51 => qml<=1;when 2|12|22|32|42|52 => qml<=2;when 3|13|23|33|43|53 => qml<=3;when 4|14|24|34|44|54 => qml<=4;when 5|15|25|35|45|55 => qml<=5;when 6|16|26|36|46|56 => qml<=6;when 7|17|27|37|47|57 => qml<=7;when 8|18|28|38|48|58 => qml<=8;when 9|19|29|39|49|59 => qml<=9;when others =>null;end case;case min iswhen 0|1|2|3|4|5|6|7|8|9 => qmh<=0;when 10|11|12|13|14|15|16|17|18|19 => qmh<=1;when 20|21|22|23|24|25|26|27|28|29 => qmh<=2;when 30|31|32|33|34|35|36|37|38|39 => qmh<=3;when 40|41|42|43|44|45|46|47|48|49 => qmh<=4;when 50|51|52|53|54|55|56|57|58|59 => qmh<=5;when others =>null;end case;end process;----------------------------------------------------------------------- process(hour)begincase hour iswhen 0|10|20 => qhl<=0;when 1|11|21 => qhl<=1;when 2|12|22 => qhl<=2;when 3|13|23 => qhl<=3;when 4|14 => qhl<=4;when 5|15 => qhl<=5;when 6|16 => qhl<=6;when 7|17 => qhl<=7;when 8|18 => qhl<=8;when 9|19 => qhl<=9;when others =>null;end case;case hour iswhen 0|1|2|3|4|5|6|7|8|9 => qhh<=0;when 10|11|12|13|14|15|16|17|18|19 => qhh<=1;when 20|21|22|23 => qhh<=2;when others => null;end case;end process;---------------------------------------------------------------process(year)beginqy1<=year/1000;qy2<=(year rem 1000)/100;qy3<=((year rem 1000)rem 100)/10;qy4<=((year rem 1000)rem 100) rem 10;--qy1<=year/1000;--qy2<=(year rem 1000)/100;--qy3<=((year-(year/1000)*1000)-((year-(year/1000)*1000)/100)*100)/10; --qy4<=((year rem 1000)rem 100)rem 10;end process;----------------------------------------------------------------process(month)beginqmonh<=month/10;qmonl<=month rem 10;end process;-----------------------------------------------------------------process(day)beginqdh<=day/10;qdl<=day rem 10;end process;----------------------------------------------------------------process(clk1khz)beginif clk1khz'event and clk1khz='1' thenif cnt=7 thencnt<=0;else cnt<=cnt+1;end if;end if;end process;----------------------------------------------------------process (cnt,qhh,qhl,qmh,qml,qsh,qsl,dis_mode)begincase dis_mode iswhen 0 => case cnt iswhen 0 => data<=qsl; scan<="11111110";when 1 => data<=qsh; scan<="11111101";when 2 => data<=15 ; scan<="11111111";when 3 => data<=qml; scan<="11110111";when 4 => data<=qmh; scan<="11101111";when 5 => data<=15; scan<="11111111";when 6 => data<=qhl; scan<="10111111";when 7 => data<=qhh; scan<="01111111";when others => null;end case;when 1=> case cnt iswhen 0 => data<=qdl; scan<="11111110";when 1 => data<=qdh; scan<="11111101";when 2 => data<=qmonl ; scan<="11111011";when 3 => data<=qmonh; scan<="11110111";when 4 => data<=qy4; scan<="11101111";when 5 => data<=qy3; scan<="11011111";when 6 => data<=qy2; scan<="10111111";when 7 => data<=qy1; scan<="01111111";when others =>null;end case;when others => null;end case;end process;----------------------------------------------------------------------------------process(data)begincase data iswhen 0 =>seg8<="11000000";when 1 =>seg8<="11111001";when 2 =>seg8<="10100100";when 3 =>seg8<="10110000";when 4 =>seg8<="10011001";when 5 =>seg8<="10010010";when 6 =>seg8<="10000010";when 7 =>seg8<="11111000";when 8 =>seg8<="10000000";when 9 =>seg8<="10010000";when others =>seg8<="11111111";end case ;end process;end;。
基于FPGA的数字日历设计
基于FPGA的数字日历设计作者:刘娟花厉谨来源:《现代电子技术》2014年第03期摘要:介绍了一种基于FPGA的数字日历设计方案,采用VHDL语言编程设计了一个具有年、月、日、星期、时、分、秒计时显示功能,时间调整功能和整点报时功能的数字日历。
采用VHDL和原理图相结合的设计输入方式,在Quartus Ⅱ开发环境下完成设计、编译和仿真,并下载到FPGA芯片EP1C3T144⁃3上进行结果验证。
结果表明:该设计方案切实可行,对FPGA的应用和数字日历的设计具有一定参考价值。
关键词:数字日历; VHDL; FPGA; Quartus Ⅱ中图分类号: TN710⁃34; TP391 文献标识码: A 文章编号: 1004⁃373X(2014)03⁃0137⁃04Design of digital calendar based on FPGALIU Juan⁃hua, LI Jin(Faculty of Electronic Information,Xi’an Polytechnic Univer sity,Xi’an 710048, China)Abstract: A design scheme of digital calendar based on FPGA is introduced. VHDL programming language is used to design the digital calendar, which has functions of displaying the year, month, day, week, hour, minute, second, time adjustment and the Hourly chime. The input method of the scheme is in combination VHDL and block diagram. The design, compiling and simulation are completed under Quartus Ⅱ development environment. The designed file is accomplished and downloaded into FPGA chip EP1C3T144⁃3 to verify the results. The experiment results verify that the design scheme is workable, and can provide references for the application of FPGA and the design of digital calendar.Keywords: digital calendar; VHDL; FPGA; Quartus Ⅱ0 引言电子技术的发展日新月异,其应用无处不在,它正在不断地改变着我们的生活,改变着我们的世界。
基于fpga的多功能万年历
基于FPGA的多功能万年历1. 绪论现代科技在不断进步电子技术在不断发展,电子产品设计复杂程度也在不断增加。
而且电子产品的更新换代也越来越快,现在只靠传统的纯硬件的设计方法已经不能满足现代人们的要求。
EDA就是典型的硬件设计软件化的设计平台。
EDA是一项非常先进的技术,它有许多别的技术没有的优点:像单片机需要先画出硬件图再编写相对应的程序,而EDA是先编好程序再画图的,而且模块化的编程还会在软件中生成相应的封装元件,使最后画原理图变的更加简单;可以编好程序就直接仿真,程序出现错误可以在源文件内部直接改;并且设计好的总系统可以集成在一个体积小、功耗低、可靠性高的芯片上。
本设计采用VHDL语言,VHDL语言是一种全方位的数字系统设计和测试的硬件描述。
它支持原理图输入方法以及传统的文件输入方。
对于前者适用于小规模的数字集成电路,并进行模拟仿真。
而对于大规模的、复杂的系统,如果用纯原理图设计方法的话的,由于种种条件和环境制约,会导致工作效率底而且容易出错的等缺点。
在信息技术的今天,集成电路逐渐的趋向于系统化、微尺寸化、低功耗高集成化,因此,高密度可编程逻辑器件和VHDL越来越得到设计者的青睐。
它具有极强的描述能力,支持结构、数据流、行为三种描述形式的混合的设计方式,描覆盖面广、抽象能力强。
它能支持系统行为级、逻辑门级和寄存器传输级三个不同层次的设计。
在本设计中用到的FPGA是特殊的ASIC芯片,ASIC是一种带有逻辑处理的加速处理器的专用的系统集成电路。
它具有功耗低、速度快、集成度、设计制造成本低等优点。
本设计是研究基于FPGA的多功能万年历的设计,主要实现以下功能:能够显示年、月、日、时、分、秒,时间采用24小时制。
当时间不准确时还可以手动校准。
本系统还能实时的显示当前的温度,扩展了万年历的功能。
我采用的是数字温度传感器DS18B20和FPGA组成的温度采集系统,此系统具有硬件电路简单,抗干扰能力强等优点。
FPGA万年历报告
FPGA-CPLD原理及应用课程设计报告题目:基于SOPC设计万年历一、摘要设计从系统硬件出发,由CPU、总线、RAM、外接设备等构成SOPC Builder 的硬件系统,通过Nios II DE2开发的嵌入式软件编写并嵌入SOPC Builder的硬件中实现万年历的整体开发。
通过应用SoPC Builder开发工具,设计者可以摆脱传统的、易于出错的软硬件设计细节,从而达到加快项目开发、缩短开发周期、节约开发成本的目的并具有高集成度、设计灵活和可移植性较好。
关键词:万年历SOPC SOPC Builder Nios II DE2二、设计要求用Nios II DE2 开发板的LCD显示电子钟的日期和时间。
LCD分两行显示,第1行显示年、月、日;第2行显示时、分、秒。
用输入BUTTON[0]来控制LCD 行的修改,同时让Nios II DE2开发板上的绿色发光二极管亮灭来表示这个选择。
当BUTTON[0]按一下后,LEDG3亮,可以修改年、月和日的数字;再按一下BUTTON[0]后,LEDG3灭,可以修改时、分和秒的数字。
另外用输入按钮BUTTON[3]来控制日期和时间的修改,当处于日期修改方式时,每次按动一次BUTTON[3],依次更换“年”、“月”和“日”的修改。
当处于时间修改方式时,每次按动一次BUTTON[3],依次更换“时”、“分”和“秒”的修改。
修改对象被选中后,按动BUTTON[2]输入按钮可以增加显示的数字;按动BUTTON[1]输入按钮可以减少显示的数字。
三、设计内容1、按键信息BUTTON[3]:“年”、“月”、“日”或“时”、“分”、“秒”切换键BUTTON[2]:+键BUTTON[1]:-键BUTTON[0]:“年”、“月”、“日”与“时”、“分”、“秒”切换键显示信息LCD_Line1:显示“年”、“月”、“日”LCD_Line1:显示“时”、“分”、“秒”2、SOPC Builder 硬件建立SOPC Builder是在Quartus II里的SOPC Builder进行的,先建立工程,在SOPC Builder里添加硬件,包括CPU ,jtag_uart ,RAM,LCD,PIO,按键,LED,以及LCD_ON。
VHDL设计FPGA数字系统:电子万年历.
大连海事大学毕业论文Array二○一四年六月VHDL设计FPGA数字系统:电子万年历专业班级: 电子信息工程10-2班姓名: 牛舒雅指导老师: 严飞信息科学技术学院摘要随着EDA(电子设计自动化)技术的发展和应用领域的扩大,EDA技术在电子信息、通信、自动化控制及计算机应用领域的重要性日益突出。
钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能,诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、定时启闭路灯等。
所有这些,都是以钟表数字化为基础的。
因此,研究基于FPGA的电子万年历及扩大其应用,有非常现实的意义。
EDA的关键技术之一是用形式化方法来描述数字系统的硬件电路、即用所谓的硬件描述语言来描述硬件电路。
本设计是用VHDL语言编程实现基于FPGA的电子万年历。
在设计中,首先介绍了万年历的设计思路,确定各功能模块,而后在Quartus II开发环境中用VHDL语言对各模块进行编程,编译成功后完成仿真,并逐一调试程序使各模块达到设计目的。
然后,将各模块生成的元器件连接起来,形成顶层原理图文件,进行系统仿真。
最后,对顶层原理图进行引脚设定,并下载到试验箱验证,证明系统的可行性。
关键字:EDA;VHDL ;万年历;Quartus IIABSTRACTWith the development of EDA (electronic design automation) technology and expansion of application fields ,the importance of EDA technology in electronic information, communication, auto control, and computer applications is becoming increasingly prominent. EDA technology is the core of the modern electronic design techniques, which rely on powerful computers . In EDA tools software platform, computer automatically completes logic simplification,logical partitions, logic synthesis , logic optimization ,logical simulation and other functions until the electronic circuit system achieves the stated performance. However, the realization of these function bases on the description of the system using the hardware description language HDL (Hardware Description language) . One of the key technologies of the EDA is to use formal methods to describe digital systems hardware circuit, which uses the so-called hardware description language to describe the hardware circuit.The design is the calendar based on VHDL language. Firstly, in which ,I introduce ideas about designing the calendar. In addition, I compile and simulate the program of different modules in the Quartus II development environment and debug one by one to make different modules meet objectives of the design. Secondly, I take advantage of all components,which is created according to program to generate top-level file . Finally, I make pin settings and download to the test chamber to prove the feasibility of the system.Key words: EDA;VHDL ;calendar;Quartus II目录第1章绪论 (1)1.1钟的起源 (1)1.2钟的现状以及发展 (1)1.3电子万年历的简介 (1)1.4VHDL设计FPGA数字系统:电子万年历的设计要求 (2)1.5 本章小结 (2)第2章开发技术基础 (3)2.1 EDA技术简介 (3)2.1.1 EDA技术基本概述 (3)2.1.2EDA技术发展与发展方向 (3)2.2FPGA基本介绍 (4)2.2.1FPGA简介 (4)2.2.1FPGA组成 (5)2.3VHDL语言概述 (5)2.3.1VHDL语言特点 (6)2.3.2VHDL语言结构 (7)2.4Quartus II软件介绍 (7)2.5ZY11EDA13BE实验系统介绍 (8)2.5.1 ZY11EDA13BE实验系统的特点 (8)2.5.2ZY11EDA13BE实验系统主板组成 (8)2.6本章小结 (9)第3章电子万年历的设计 (10)3.1设计思想 (10)3.2 设计框图 (11)3.3 设计流程图 (12)3.4 本章小结 (15)第4章电子万年历的设计、仿真与展示 (16)4.1 模块分析 (16)4.1.1 秒与分的计数器模块 (16)4.1.3 日计数器模块 (18)4.1.4月计数器模块 (21)4.1.5年低位计数器模块 (22)4.1.6年高位计数器模块 (23)4.1.7校准模块 (24)4.1.8 显示以及显示内容切换模块 (26)4.2顶层原理图 (27)4.3 管脚锁定 (29)4.4电子万年历的展示 (29)4.5本章小结 (30)第5章总结 (31)参考文献 (32)致谢 (33)第1章绪论1.1钟的起源中国古代很早就用日晷计时。
基于fpga的LCD显示万年历..
接着我的上一篇博文,终于完善好了,前几天太忙了,没有及时上传,呵呵,今天晚上刚比较早刚好凌晨,及时上传一下,实现了从0000---9999年的时钟,其实万年历和十万年历,都是差不多,等到地球能转到9999年再改代码也不迟,哈哈!!我这里有顶层和底层文件,顶层主要是调用模块和做按键处理,具体按键防抖动原理,参见偶的以前的博文,我写完这个万年历的代码,还没来得及优化,占用了太多了逻辑门,可以进一步优化。
大致思路是:第一次按下KEY1 的时候,所有计时停止,再按KEY1,年就闪烁,按下KEY2和KEY3 进行加减。
再按KEY1,月就闪烁,按下KEY2和KEY3 进行加减........依次为调年-月-日-星期-时分秒,再次按一下KEY1,进入正常运行模式。
好了先上顶层模块module LCD(rst,clk,rw,rs,en,data,key1,key2,key3);input clk,rst;input key1,key2,key3;output rs,en,rw;output [7:0] data;reg key1_out,key2_out,key3_out;wire clk,rst;wire rs,en,rw;wire [7:0] data;disp U1(.clk(clk),.rst(rst),.rs(rs),.en(en),.rw(rw),.data(data),.key1(key1_out),.key2(key2_out),.key3(key3_out));//=============key1,key2,key3 按键防抖动================// reg key1_reg1,key1_reg2;reg key2_reg1,key2_reg2;reg key3_reg1,key3_reg2;reg [31:0] count;always @(posedge clk)begincount<=count+1;if(count==500000)begincount<=0;key1_reg1<=key1;key2_reg1<=key2;key3_reg1<=key3;endkey1_reg2<=key1_reg1;key2_reg2<=key2_reg1;key3_reg2<=key3_reg1;key1_out <= key1_reg2 & (!key1_reg1);key2_out <= key2_reg2 & (!key2_reg1);key3_out <= key3_reg2 & (!key3_reg1);endendmodule底层模块:module disp(rst,clk,rw,rs,en,data,key1,key2,key3);input clk,rst;input key1,key2,key3;output rs,en,rw;output [7:0] data;reg rs,en_sel;reg [7:0] data;reg [14:0] year;reg [7:0] shi,fen,miao,month,dat;reg [31:0]count,count1; //LCD CLK 分频计数器reg lcd_clk;//2行32个数据寄存器reg [7:0]one_1,one_2,one_3,one_4,one_5,one_6,one_7,one_8,one_9,one_10,one_11,one_12,on e_13,one_14,one_15,one_16;reg [7:0]two_1,two_2,two_3,two_4,two_5,two_6,two_7,two_8,two_9,two_10,two_11,two_12,two_ 13,two_14,two_15,two_16;reg [7:0] next;parameter state0 =8'h00, //设置8位格式,2行,5*7 8'h38;state1 =8'h01, //整体显示,关光标,不闪烁8'h0C 闪烁8'h0estate2 =8'h02, //设定输入方式,增量不移位8'h06state3 =8'h03, //清除显示8'h01state4 =8'h04, //显示第一行的指令80Hstate5 =8'h05, //显示第二行的指令80H+40Hscan =8'h06,nul =8'h07;parameter data0 =8'h10, //2行32个数据状态data1 =8'h11,data2 =8'h12,data3 =8'h13,data4 =8'h14,data5 =8'h15,data6 =8'h16,data7 =8'h17,data8 =8'h18,data9 =8'h19,data10 =8'h20,data11 =8'h21,data12 =8'h22,data13 =8'h23,data14 =8'h24,data15 =8'h25,data16 =8'h26,data17 =8'h27,data18 =8'h28,data19 =8'h29,data20 =8'h30,data21 =8'h31,data22 =8'h32,data23 =8'h33,data24 =8'h34,data25 =8'h35,data26 =8'h36,data27 =8'h37,data28 =8'h38,data29 =8'h39,data30 =8'h40,data31 =8'h41;initialbegin//第一行显示年-月-日星期//Mon Tue Wed Thur Fri Sat Sunone_1<=" "; one_2<=" "; one_3<=" "; one_4<=" "; one_5<="-"; one_6<=" "; one_7<=" "; one_8<="-";one_9<=" ";one_10<=" ";one_11<=" ";one_12<=" ";one_13<=" ";one_14<="";one_15<=" ";one_16<=" ";//第二行显示Clock:00-00-00two_1<="C"; two_2<="l"; two_3<="o"; two_4<="c"; two_5<="k"; two_6<=":"; two_7<=" "; two_8<=" ";two_9<="-";two_10<=" ";two_11<=" ";two_12<="-";two_13<=" ";two_14<="";two_15<=" ";two_16<=" ";shi<=8'd0;fen<=8'd0;miao<=8'd0;end//======================产生LCD 时序脉冲=========================== always @ (posedge clk ) //获得LCD时钟begincount<=count+1;if(count==32'd50000)begincount<=32'b0;lcd_clk<=~lcd_clk;endend//=====================产生闪烁扫描时钟===========================reg [31:0] count2;reg scan_flag;always @ (posedge clk or negedge rst) //获得校准时间选中闪烁状态beginif(!rst)beginscan_flag<=1'b0;endelsebegincount2<=count2+1;if(count2==32'd1*******)begincount2<=32'b0;scan_flag<=~scan_flag;endendend//====================产生按键标志位================================= reg [3:0] flag;always @ (posedge clk or negedge rst )beginif(!rst)beginflag<=4'b0;endelseif(key1)beginflag<=flag+1'b1;if(flag==4'b1000)flag<=4'b0000;endend//===================计时以及校准=======================================reg[3:0] week;reg[7:0] dat_flag;always @ (posedge clk or negedge rst ) //时钟计数器beginif(!rst)begin //初始化显示第一行2012-05-19 Sat 第二行:Clock:00-00-00 shi<=8'b0;fen<=8'b0;miao<=8'b0;month<=8'd5;dat<=8'd19;year<=16'd2012;week<=4'd5;count1<=1'b0;two_7<= (shi/8'd10)+8'b00110000;two_8<= (shi%8'd10)+8'b00110000;two_10<=(fen/8'd10)+8'b00110000;two_11<=(fen%8'd10)+8'b00110000;two_13<=(miao/8'd10)+8'b00110000;two_14<=(miao%8'd10)+8'b00110000;one_1<=(year/16'd1000)+8'b00110000;one_2<=((year%16'd1000)/16'd100)+8'b00110000;one_3<=((year%16'd100)/8'd10)+8'b00110000;one_4<=(year%8'd10)+8'b00110000;one_6<=(month/8'd10)+8'b00110000;one_7<=(month%8'd10)+8'b00110000;one_9<=(dat/8'd10)+8'b00110000;one_10<=(dat%8'd10)+8'b00110000;endelsebegintwo_7<= (shi/8'd10)+8'b00110000;two_8<= (shi%8'd10)+8'b00110000;two_10<=(fen/8'd10)+8'b00110000;two_11<=(fen%8'd10)+8'b00110000;two_13<=(miao/8'd10)+8'b00110000;two_14<=(miao%8'd10)+8'b00110000;one_1<=(year/16'd1000)+8'b00110000;one_2<=((year%16'd1000)/16'd100)+8'b00110000;one_3<=((year%16'd100)/8'd10)+8'b00110000;one_4<=(year%8'd10)+8'b00110000;one_6<=(month/8'd10)+8'b00110000;one_7<=(month%8'd10)+8'b00110000;one_9<=(dat/8'd10)+8'b00110000;one_10<=(dat%8'd10)+8'b00110000;// 判断是否为31天的月份if(month==8'd1||month==8'd3||month==8'd5||month==8'd7||month==8'd8||month==8'd10|| month==8'd12)dat_flag<=8'd31;// 判断是否为30天的月份else if(month==8'd4||month==8'd6||month==8'd9||month==8'd11)dat_flag<=8'd30;// 判断是否为闰年和平年else if(month==8'd2)beginif(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)dat_flag<=28;else dat_flag<=27;endcase (week)//星期//Mon Tue Wed Thu Fri Sat Sun4'b0000 : //1beginone_13<="M";one_14<="o";one_15<="n";end4'b0001 : //2beginone_13<="T";one_14<="u";one_15<="e";end4'b0010 : //3beginone_13<="W";one_14<="e";one_15<="d"; end4'b0011 : //4beginone_13<="T";one_14<="h";one_15<="u"; end4'b0100 : //5beginone_13<="F";one_14<="r";one_15<="i"; end4'b0101 : //6beginone_13<="S";one_14<="a";one_15<="t"; end4'b0110 : //7beginone_13<="S";one_14<="u";one_15<="n"; endendcasecase(flag)4'b0000 :beginen_sel<=1'b1;count1<=count1+1'b1;if(count1==32'd4*******)begincount1<=1'b0;miao<=miao+1'b1;if(miao==8'd59)beginmiao<=1'b0;fen<=fen+1'b1;if(fen==8'd59)beginfen<=1'b0;shi<=shi+1'b1;if(shi==8'd23)beginshi<=1'b0;dat<=dat+1'b1;week<=week+1'b1;if(week==4'b0110)week<=1'b1;if(dat==dat_flag)begindat<=8'd1;month<=month+1'b1;if(month==8'd12)beginmonth<=8'd1;year<=year+1'b1;if(year==16'd9999)year<=16'd0; //可以计1万年endendendendendendend4'b0001 :begincount1<=32'b0;//shi<=shi;fen<=fen;miao<=miao;year<=year;month<=month;dat<=dat;week<=week;end4'b0010 : //调年begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;one_1<=8'd20;one_2<=8'd20;one_3<=8'd20;one_4<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数beginyear<=year+1'b1;if(year==16'd9999)year<=16'd0;endif(key3) //减数beginyear<=year-1'b1;if(year==16'd0)year<=16'd9999;endend4'b0011 : //调月begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;one_6<=8'd20;one_7<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endcaseif(key2) //加数beginmonth<=month+1'b1;if(month==8'd12)month<=8'd0;endif(key3) //减数beginmonth<=month-1'b1;if(month==8'd0)month<=8'd12;endend4'b0100 : //调日begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;one_9<=8'd20;one_10<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数begindat<=dat+1'b1;if(dat==dat_flag)dat<=8'd0;endif(key3) //减数dat<=dat-1'b1;if(dat==8'd0)dat<=dat_flag;endend4'b0101 : //调星期begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;one_13<=8'd20;one_14<=8'd20;one_15<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数beginweek<=week+1'b1;if(week==4'd6)week<=4'd0;endif(key3) //减数beginweek<=week-1'b1;if(week==4'd0)week<=4'd7;endend4'b0110 : //调时begincase(scan_flag)begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;two_7<= 8'd20;two_8<= 8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数beginshi<=shi+8'b00000001;if(shi==8'd23)shi<=8'b0;endif(key3) //减数beginshi<=shi-8'b00000001;if(shi==8'b0)shi<=23;endend4'b0111 : //调分begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;two_10<=8'd20;two_11<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数beginfen<=fen+8'b00000001;if(fen==8'd59)fen<=8'b0;endif(key3) //减数beginfen<=fen-8'b00000001;if(fen==8'b0)fen<=59;endend4'b1000 : //调秒begincase(scan_flag)1'b0:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;two_13<=8'd20;two_14<=8'd20;end1'b1:begincount1<=32'b0; //shi<=shi;fen<=fen;miao<=miao;endendcaseif(key2) //加数beginmiao<=miao+8'b00000001;if(miao==8'd59)miao<=8'b0;endif(key3) //减数beginmiao<=miao-8'b00000001;if(miao==8'b0)miao<=59;endendendcaseendendalways @(posedge lcd_clk )begincase(next)state0 :begin rs<=1'b0; data<=8'h38; next<=state1; endstate1 :begin rs<=1'b0; data<=8'h0e; next<=state2; endstate2 :begin rs<=1'b0; data<=8'h06; next<=state3; endstate3 :begin rs<=1'b0; data<=8'h01; next<=state4; endstate4 :begin rs<=1'b0; data<=8'h80; next<=data0; end //显示第一行data0 :begin rs<=1'b1; data<=one_1; next<=data1 ; enddata1 :begin rs<=1'b1; data<=one_2; next<=data2 ; enddata2 :begin rs<=1'b1; data<=one_3; next<=data3 ; enddata3 :begin rs<=1'b1; data<=one_4; next<=data4 ; enddata4 :data5 :begin rs<=1'b1; data<=one_6; next<=data6 ; enddata6 :begin rs<=1'b1; data<=one_7; next<=data7 ; enddata7 :begin rs<=1'b1; data<=one_8; next<=data8 ; enddata8 :begin rs<=1'b1; data<=one_9; next<=data9 ; enddata9 :begin rs<=1'b1; data<=one_10; next<=data10 ; enddata10 :begin rs<=1'b1; data<=one_11; next<=data11 ; enddata11 :begin rs<=1'b1; data<=one_12; next<=data12 ; enddata12 :begin rs<=1'b1; data<=one_13; next<=data13 ; enddata13 :begin rs<=1'b1; data<=one_14; next<=data14 ; enddata14 :begin rs<=1'b1; data<=one_15; next<=data15 ; enddata15 :begin rs<=1'b1; data<=one_16; next<=state5 ; endstate5:begin rs<=1'b0;data<=8'hC0; next<=data16; end //显示第二行data16 :begin rs<=1'b1; data<=two_1; next<=data17 ; enddata17 :begin rs<=1'b1; data<=two_2; next<=data18 ; enddata18 :begin rs<=1'b1; data<=two_3; next<=data19 ; enddata19 :begin rs<=1'b1; data<=two_4; next<=data20 ; enddata20 :data21 :begin rs<=1'b1; data<=two_6; next<=data22 ; enddata22 :begin rs<=1'b1; data<=two_7; next<=data23 ; enddata23 :begin rs<=1'b1; data<=two_8; next<=data24 ; enddata24 :begin rs<=1'b1; data<=two_9; next<=data25 ; enddata25 :begin rs<=1'b1; data<=two_10; next<=data26 ; end data26 :begin rs<=1'b1; data<=two_11; next<=data27 ; end data27 :begin rs<=1'b1; data<=two_12; next<=data28 ; end data28 :begin rs<=1'b1; data<=two_13; next<=data29 ; end data29 :begin rs<=1'b1; data<=two_14; next<=data30 ; end data30 :begin rs<=1'b1; data<=two_15; next<=data31 ; end data31 :begin rs<=1'b1; data<=two_16; next<=scan ; endscan : //交替更新第一行和第二行数据beginnext<=state4;enddefault: next<=state0;endcaseendassign en=lcd_clk && en_sel;assign rw=1'b0;endmodule。
基于FPGA的多功能电子万年历
基于FPGA的多功能电子万年历电子万年历可以显示日期、星期、时间以及其他的一些信息。
近几年,随着FPGA技术的发展,基于FPGA的电子万年历已经被广泛使用。
基于FPGA的电子万年历除了具备传统电子万年历的基本功能外,还具有诸多的优点。
采用FPGA做万年历,集成度高、抗电磁干扰性能好、可编程性强,且易于扩展。
本文将主要讲述基于FPGA的多功能电子万年历的设计原理、实现细节以及相关应用。
设计原理基于FPGA的多功能电子万年历主要由FPGA芯片、时钟模块、数码管显示模块以及按键扫描模块组成。
1.FPGA芯片:大体上分为输入、输出、内存和运算4个部分。
通过采用FPGA芯片可以实现逻辑门的优化布局和资源分配,从而实现万年历的多种功能。
2.时钟模块:利用时钟模块产生震荡脉冲,驱动万年历的各种操作。
时钟模块还可以产生各种频率的时钟信号,如秒钟、分频、时钟、日历等,从而实现多种功能。
3.显示模块:显示模块主要通过数码管来显示日期、星期、时间等信息。
具体实现方法是将数码管的数码码表和时序参数存储在内存中,通过编程控制数码管的显示方式,实现数据的输出。
4.按键扫描模块:按键扫描模块主要通过扫描键盘来接受用户的输入,并根据用户的操作控制万年历的功能。
实现细节基于FPGA的多功能电子万年历的实现细节主要包括万年历的功能实现、按键扫描和电路部署。
1.万年历的功能实现多功能电子万年历主要支持年、月、日的日期显示、星期显示、时间显示、时钟多种功能。
具体实现方法是每秒读取系统时间,并将时间转换成5V逻辑电平数据,然后通过编程控制数码管的显示方式,实现数据的输出。
2.按键扫描按键扫描模块主要通过接收按下按键后输出电平并进行数值编码,与计算机进行数值比对,然后根据用户的操作控制万年历的功能。
比如,按下设置键后,进入设置模式,按一次将秒数置零,按2次进行月日年设置,按3次进行时间设置,按4次重新返回当前时间界面。
3.电路部署电路部署主要包括FPGA芯片与其他模块、模块与模块之间的连接。
基于FPGA的多功能电子万年历毕业设计说明
毕业设计中期报告题目名称:基于FPGA的万年历设计院系名称:电气学院班级:应电学号:0832100589学生:梁启超指导教师:金凤2011年06月目录一、多功能电子万年历及FPGA简介 (1)1.1电子万年历的发展 (1)1.2 FPGA简介 (1)1.3 电子万年历的工作原理 (2)二、多功能电子万年历各功能模块实现 (4)2.1 时钟问题 (4)2.1.1 全局时钟 (4)2.1.2 门控时钟 (4)2.1.3 多级逻辑时钟 (5)2.1.4 波动式时钟 (5)2.2 电子万年历的控制系统 (6)2.3 主控制模块 maincontrol (7)2.4 时间及其设置模块 time_auto_and_set (8)2.2.1 时间模块 timepiece_main (8)2.2.2 时间设置模块 timeset (9)2.2.3 时间数据与时间设置数据多路选择模块 time_mux (11)2.3 时间显示动态位选模块 time_disp_select (13)2.4 显示模块 disp_data_mux (14)2.5 秒表模块 stopwatch (15)2.6 日期显示与设置模块 date_main (16)2.6.1 日期自动工作模块 autodate (17)2.6.2 日期设置模块 setdate (17)2.7 闹钟模块alarmclock (18)2.8 分频模块 fdiv (19)2.9 顶层模块图 (21)三、附录 (23)电子万年历系统的Verilog HDL语言程序设计部分代码 (23)3.1主控制模块 (23)3.2秒自动计时子模块 (25)3.3时间自动工作控制 (25)3.4时间数据与时间设置数据多路选择模块 (26)3.5时间及其设置模块 (27)3.6时间显示动态位选模块 (28)3.7秒表模块 (29)3.8分频模块 (29)参考文献 (31)1 引言1.1 选题意义钟表的数字化给人们生产生活带来了极大的方便,而且大扩展了钟表原先的报时功能,诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、定时启闭路灯等。
26_毕业设计基于fpga的万年历设计[管理资料]
基于FPGA的万年历电路的设计目录摘要 ........................................................................................................................................... Abstract (I)前言 0第1章万年历的发展及FPGA简介 (1)万年历的发展 (1)FPGA简介 (1)第2章设计原理 (2)组成模块 (2)系统设计图 (2)第3章各功能模块介绍 (4)分频模块(fenpin) (4)控制模块(countr) (4)时间显示调整模块(mux_4) (4)时分秒模块(timeve) (5)年月日模块(nyr2009) (5)显示控制模块(mux_16) (6)译码器(yimaqi) (6)第4章模拟仿真 (8)年月日模块仿真 (8)时分秒模块仿真 (8)结论 (9)总结与体会 (10)谢辞 (11)参考文献 (12)附录一 (13)附录二 (24)附录三 (30)基于FPGA的万年历电路的设计摘要基于FPGA的万年历设计,主要完成的任务是使用Verilog语言,在Quartis2上完成电路设计,程序开发模拟,基本功能是能够显示/修改年月日时分秒。
电路设计模块中分为几个模块:分频、控制、时间显示调整、时分秒、年月日、显示控制、译码器。
各个模块完成不同的任务,合在一起就构成了万年历的系统电路设计。
至于程序编写,使用Verilog语言,根据各个模块的不用功能和它们之间的控制关系进行编写。
软件模拟直接在Quartis2上进行。
进入信息时代,时间观念越来越重,但是老式的钟表以及日历等时间显示工具已经不太适合。
如钟表易坏,需要经常维修,日历需要每天翻页等。
对此,数字万年的设计就有了用武之地。
基于FPGA的万年历设计,采用软件开发模拟,开发成本低,而且再功能设计上有很大的灵活度,只要在软件上进行简单的修改就能实现不同的功能要求,能够满足不同环境要求。
基于FPGA的电子万年历的设计与实现
基于FPGA的电子万年历的设计与实现
李承铭;王佳欣;柯骏;李丝天;李翔;陈初侠
【期刊名称】《电脑知识与技术》
【年(卷),期】2024(20)4
【摘要】文章基于FPGA芯片EP4CE6E22C8设计了一款电子万年历。
首先根据设计要求,将电子万年历分成多个底层电路并用VerilogHDL语言对其进行设计和仿真,然后调用已设计好的各底层电路采用原理图方式设计顶层电路,最后对设计好的顶层电路进行管脚锁定并下载到FPGA芯片中进行硬件验证。
结果表明,所设计的电子万年历能实现秒、分、时、星期、日、月、年的显示、时间的设置和整点报时功能,集多功能于一体,具有较好的实用性。
【总页数】4页(P106-109)
【作者】李承铭;王佳欣;柯骏;李丝天;李翔;陈初侠
【作者单位】巢湖学院电子工程学院
【正文语种】中文
【中图分类】TP29
【相关文献】
1.基于AT89S52单片机的电子万年历设计与实现
2.基于LED点阵显示的电子万年历的设计与实现
3.基于I2C总线电子万年历的设计与实现
4.基于FPGA的电子万年历设计
5.一种电子万年历的设计与实现
因版权原因,仅展示原文概要,查看原文内容请购买。
开题报告
年月日
注:此表由学生填写。开题报告会结束后,由指导教师和小组签署意见。论文答辩前,学生将此表交指导教师。此表按要求装订在论文文本内。
[9]王开军,姜宇柏.面向CPLD/FPGA的VHDL设计[J].机械工业出版社2006,12(1):28-65.
[10]刘君,常明,秦娟.基于硬件描述语言(VHDL)的数字时钟设计[J].天津理工大学学报,2007,23(4):40-41
六、指导教师意见:
指导教师签名:
年月日
七、指导小组意见:
组长签名:
主要内容:以FPGA芯片为核心器件,设计一个万年历。
预期目标:设计并实现一个万年历,其具有如下功能:①显示年、月、日、时、分、秒;②可调整日期和时间。
四、拟采用的研究方法和主要措施:
研究方法:1.文献资料法;2.计算机设计法。
主要措施:1.通过我院图书馆查阅相关文献资料并对资料归纳总结;2.通过在实验箱上进行软件设计;3.制作电路板。
五、主要参考文献:
[1]沈明山编著.EDA技术及可编程器件应用实训[M].北京:科学出版社,2004:12-15.
[2]潘松,黄继业编著.EDA技术与VHDL(第2版)[M].北京:清华大学出版社,2007:23-24.
[3]张毅刚.单片机原理及应用[M].北京:高等教育出版社,2003:34-37.
二、本课题的研究现状:
【2019年整理】基于FPGA的日历、时间、闹铃系统
基于FPGA的日历、时间、闹铃系统前言:由于本人刚刚入门,只用了最基本的设计思维,所以可能浪费了许多芯片资源,要是哪位高手能帮忙把系统优本人定然感激不尽。
系统功能:显示当前日期,时间,到点报时。
可通过按键来调整日期时间,并且设置闹铃时间,闹铃响后,必须手动模块说明:系统的顶层模块如下图所示,该系统由六个模块组成,分别为分频模块,按键模块,计数模块,LCD液晶除法器模块,以及铃声模块。
皆为可综合模块,可综合为门级网表,并在FPG必片上验证了其正确性。
由于涉及版严禁用于商业目的,违者必究!按键示意图:l|hhpljM—■;~~L H—*gMdJL I M■dqK- i Ji;I .At1,、分频器: module div_1hz(clk,clock);output reg clock;input clk;// 外部50MHZ寸钟输入reg[24:0] i;always@(posedge clk)begini=i+1;if(i==25'h17d7840)begin i=0;clock=~clock; // 产生1HZ频率信号。
endendendmodule 2、按键模块: modulekey(num,keyout,targe,keyout_en,keyin,rst,clk);output reg [3:0] keyout;output [3:0] num;output targe;output reg keyout_en; input rst,clk; input [3:0]keyin; reg [7:0] i; reg [3:0] num; reg [23:0] count; reg [5:0] state,next_state; reg [3:0] keyout_reg,keyin_reg; parameter s0=6'b000001,s1=6'b000010, s2=6'b000100, s3=6'b001000, s4=6'b010000, s5=6'b100000; wire clock; always@(posedge clk or negedge 设置时间阉钟“设计早关闭*确定rst) beginif(!rst)i<=0; else i<=i+1; endassign clock=i[7];always@(posedge clock or negedge rst) begin if(!rst) begin count<=0; keyout_en<=0; end else begin if(keyin!=4'hf) begin if(count<'h4bb3)// 去抖动count<=count+1; else keyout_en<=1; end else if(state[5]||state[0]) begin count<=0;keyout_en<=0; end end endassign targe=(!(state==s0||state==s5))&&(keyin!=4'hf);always@(posedge clock) beginif(targe)beginkeyout_reg<=keyout; keyin_reg<=keyin; endelsebeginkeyout_reg<=keyout_reg;keyin_reg<=keyin_reg; endendalways@(keyout reg or keyin_reg or clock) begincase({keyin_reg,keyout_reg}) 8'b1110_1110: num <= 1 ; 8'b1110_1101: num <= 2 ;8'b1110_1011: num <= 3 ; 8'b1110_0111: num <= 10 ;8'b1101_1110: num <= 4 ;8'b1101_1101: num <= 5 ; 8'b1101_1011: num <= 6 ; 8'b1101_0111: num <= 11 ;8'b1011_1110: num <= 7 ; 8'b1011_1101: num <= 8 ; 8'b1011_1011: num <= 9;8'b1011_0111: num <= 12;8'b0111_1110: num <= 0;8'b0111_1101: num <= 15; 8'b0111_1011: num <= 14; 8'b0111_0111: num <= 13;endcaseendalways@(posedge clock or negedge rst) beginif(!rst)state<=s0;elsestate<=next_state;endalways@(keyin or state or keyout_en) beginkeyout=4'b0000;case(state)s0: beginkeyout=4'b0000;if(keyout_en)next_state=s1;elsenext_state=s0;ends1: beginkeyout=4'b1110;if(keyin!=4'hf)next_state=s5;elsenext_state=s2;ends2: beginkeyout=4'b1101;if(keyin!=4'hf)next_state=s5;elsenext_state=s3;ends3: beginkeyout=4'b1011;if(keyin!=4'hf)next_state=s5;elsenext_state=s4;ends4: beginkeyout=4'b0111;if(keyin!=4'hf)next_state=s5;elsenext_state=s0;ends5: beginkeyout=4'b0000;if(keyin==4'hf)next_state=s0;elsenext_state=s5;enddefault next_state=s0;endcaseendendmodule计数器模块:module jishuqi(out_4,out_400,nian,yue,ri,shi,fen,miao,n,speaker,ns,nf,clk_1hz,yushu1,yushu2,num,keyout_en);//shuzimiaobiao output reg[15:0]nian; output reg[7:0]yue,ri,shi,fen,miao,ns,nf;output [11:0] out_4,out_400;output reg [1:0]n;output reg speaker;input clk_1hz;input [15:0]yushu1,yushu2;input [3:0] num;input keyout_en;reg [3:0]cunt;reg[2:0] cnt;reg [15:0] ni;reg [7:0] y,r,s,f,m;assign out_4='d4;assign out_400='d400;wire [15:0]yushu;assign yushu=!((yushu1==0)||(yushu2==0))?0:1;initial begin ns<=8;speaker<=1;endalways@(posedge clk_1hz)beginif(n==3)begin speaker<=1;endelse if((shi==ns)&&(fen==nf))elsespeaker<=speaker;endalways@(negedge keyout_en)beginif(num=='ha)begin n<=1;cunt<=0;endelse if(num=='hd)beginn<=0;cunt<=0;cnt<=0;endelse if(num=='hb)n<=2;else if(num=='hc)n<=3;elsen<=n;if(n==2)beginif((num==1)||(num==2)||(num==3)||(num==4)||(num==5)||(num==6)||(num==7)||(num==8)||(num==9||num==0))begin cnt<=cnt+1;endelsecnt<=cnt;endif(n==1)beginif((num==1)||(num==2)||(num==3)||(num==4)||(num==5)||(num==6)||(num==7)||(num==8)||(num==9||num==0))begin cunt<=cunt+1;endelsecunt<=cunt;endcase(cnt)0:ns[7:4]<=num;1:ns[3:0]<=num;2:nf[7:4]<=num;3:nf[3:0]<=num;4:cnt<=0;endcasecase(cunt)0:begin ni[15:12]<=num;end1:begin ni[11:8]<=num;end2:begin ni[7:4]<=num;end3:begin ni[3:0]<=num;end5:begin y[3:0]<=num;end6:begin r[7:4]<=num;end7:begin r[3:0]<=num;end8:begin s[7:4]<=num;end9:begin s[3:0]<=num;end10:begin f[7:4]<=num;end11:begin f[3:0]<=num;end12:begin m[7:4]<=num;end13:begin m[3:0]<=num;end14:cunt<=0;endcaseendalways@(posedge clk_1hz)//suan fa shi xian beginif(n!=1)beginmiao<=miao+1;if(yue=='h13)begin yue<=0;nian[3:0]<=nian[3:0]+1;if(nian[3:0]=='d9) begin nian[3:0]<=0;nian[7:4]<=nian[7:4]+1;if(nian[7:4]=='d9)begin nian[7:4]<=0;nian[11:8]<=nian[11:8]+1;if(nian[11:8]=='d9)beginnian[11:8]<=0;nian[15:12]<=nian[15:12]+1;if(nian[15:12]=='d9) nian[15:12]<=0;endendendendif(miao[3:0]==4'd9)beginmiao[3:0]<=0;miao[7:4]<=miao[7:4]+1;if(miao[7:4]==4'd5)beginmiao[7:4]<=0;fen[3:0]<=fen[3:0]+1;if(fen[3:0]==9)beginfen[3:0]<=0;fen[7:4]<=fen[7:4]+1;if(fen[7:4]==4'd5)beginfen[7:4]<=0;shi[3:0]<=shi[3:0]+1;if(shi[3:0]=='d9)beginshi[3:0]<=0;shi[7:4]<=shi[7:4]+1;endif((shi[7:4]==2)&&(shi[3:0]==3)) begin shi[7:4]<=0;shi[3:0]<=0; ri[3:0]<=ri[3:0]+1; if(ri[3:0]=='d9)begin ri[3:0]<=0; ri[7:4]<=ri[7:4]+1;endif(((yue[3:0]==1)&&(yue[7:4]==0) )|| ((yue[3:0]==3)&&(yue[7:4]==0) )|| (yue[3:0]==5)||(yue[3:0]==7)||(=8)11((yue[3:0]==0)&&(yue[7:4]==1))||((yue[3:0]==2)&&(yue[7:4]==1))||((yue[3:0]==3)&&(yue[7:4]==1)) begin if(!((yue[3:0]==3)&&(yue[7:4]==1)))beginif((ri[7:4]==3)&&(ri[3:0]==1))beginri[7:4]<=0;ri[3:0]<=1;yue[3:0]<=yue[3:0]+1;endendif((yue[3:0]==4)||(yue[3:0]==6)||(yue[3:0]==9)||((yue[3:0]==1)&&(yue[7:4]==1))) beginif((ri[7:4]==3)&&(ri[3:0]==0))beginri[7:4]<=0;ri[3:0]<=1;yue[3:0]<=yue[3:0]+1;endendif((yue[3:0]==2)&&(yue[7:4]==0))beginif(yushu==0)beginif((ri[7:4]==2)&&(ri[3:0]==9))beginri[7:4]<=0;ri[3:0]<=1;yue[3:0]<=yue[3:0]+1;endendelsebeginif(ri[7:4]==2&&ri[3:0]==9)beginri[7:4]<=0;ri[3:0]<=1;yue[3:0]<=yue[3:0]+1;endendendif(yue[3:0]=='d10)beginyue[3:0]<=0;yue[7:4]<=yue[7:4]+1;endendendendendendendendif(n==1)beginnian<=ni;yue<=y;ri<=r;shi<=s;fen<=f;miao<=m;endendendmodule4、LCD液晶显示模块:module lcd1602(nian,yue,ri,shi,fen,miao,clk,n,ns,nf,rs,rw,en,dat); function [7:0]data;input [3:0] num;begincase(num)0:begin data=8'h30;end1:data=8'h31;2:data=8'h32;3:data=8'h33;4:data=8'h34;5:data=8'h35;6:data="6";7:data=8'h37;8:data=8'h38;9:data=8'h39;endcaseendendfunctioninput [15:0] nian;input [7:0] yue,ri,shi,fen,miao;input [7:0]ns,nf;input clk;input [1:0] n;output rs,rw,en;output[7:0] dat;reg rs,rw;wire en;reg[7:0] dat;reg[5:0] counter;reg[1:0] state;reg [15:0] count;reg clkr;parameter init=0,write_data=1; assign en=clkr;always @(posedge clk)begincount=count+1;if(count==16'h000f)clkr=~clkr;endalways@(posedge clkr)begincase(state)init:beginrs=0;rw=0;counter=counter+1;case(counter)1:dat='h38;2:dat='h08;3:dat='h01;4:dat='h06;5:dat='h0c;6:begindat='h80;state=write_data;counter=0;enddefault: counter=0;endcaseendwrite_data:beginif(n!=2)begincase(counter)0:begin rs<=0;dat=0+8'h80;end1:begin rs<=1;dat=data(nian[15:12]);end2:begin rs<=0;dat=1+8'h80;end3:begin rs<=1;dat=data(nian[11:8]);end4:begin rs<=0;dat=2+8'h80;end5:begin rs<=1;dat=data(nian[7:4]);end6:begin rs<=0;dat=3+8'h80;end7:begin rs<=1;dat=data(nian[3:0]);end8:begin rs<=0;dat=4+8'h80;end9:begin rs<=1;dat="-";end10:begin rs<=0;dat=5+8'h80;end11:begin rs<=1;dat=data(yue[7:4]);end12:begin rs<=0;dat=6+8'h80;end13:begin rs<=1;dat=data(yue[3:0]);end14:begin rs<=0;dat=7+8'h80;end15:begin rs<=1;dat="-";end16:begin rs<=0;dat=8+8'h80;end17:begin rs<=1;dat=data(ri[7:4]);end18:begin rs<=0;dat=9+8'h80;end19:begin rs<=1;dat=data(ri[3:0]);end20:begin rs<=0;dat=0+8'hc0;end21:begin rs<=1;dat=data(shi[7:4]);end22:begin rs<=0;dat=1+8'hc0;end23:begin rs<=1;dat=data(shi[3:0]);end24:begin rs<=0;dat=2+8'hc0;end25:begin rs<=1;dat=":";end26:begin rs<=0;dat=3+8'hc0;end27:begin rs<=1;dat=data(fen[7:4]);end28:begin rs<=0;dat=4+8'hc0;end29:begin rs<=1;dat=data(fen[3:0]);end30:begin rs<=0;dat=5+8'hc0;end31:begin rs<=1;dat=":";end32:begin rs<=0;dat=6+8'hc0;end33:begin rs<=1;dat=data(miao[7:4]);end34:begin rs<=0;dat=7+8'hc0;end35:begin rs<=1;dat=data(miao[3:0]);end36:beginrs=0; dat='h80;enddefault: counter=0;endcaseif(counter==37) counter=0;else counter=counter+1;endelsebegincase(counter)0:begin rs<=0;dat=0+8'h80;end1:begin rs<=1;dat=data(ns[7:4]);end2:begin rs<=0;dat=1+8'h80;end3:begin rs<=1;dat=data(ns[3:0]);end4:begin rs<=0;dat=2+8'h80;end5:begin rs<=1;dat=":";end6:begin rs<=0;dat=3+8'h80;end7:begin rs<=1;dat=data(nf[7:4]);end 8:begin rs<=0;dat=4+8'h80;end9:begin rs<=1;dat=data(nf[3:0]);end10:begin rs<=0;dat=5+8'h80;end11:begin rs<=1;dat=" ";end12:begin rs<=0;dat=6+8'h80;end13:begin rs<=1;dat=" ";end14:begin rs<=0;dat=7+8'h80;end15:begin rs<=1;dat=" ";end16:begin rs<=0;dat=8+8'h80;end17:begin rs<=1;dat=" ";end18:begin rs<=0;dat=9+8'h80;end19:begin rs<=1;dat=" ";end20:begin rs<=0;dat=0+8'hc0;end21:begin rs<=1;dat=" ";end22:begin rs<=0;dat=1+8'hc0;end23:begin rs<=1;dat=" ";end24:begin rs<=0;dat=2+8'hc0;end25:begin rs<=1;dat=" ";end26:begin rs<=0;dat=3+8'hc0;end27:begin rs<=1;dat=" ";end28:begin rs<=0;dat=4+8'hc0;end29:begin rs<=1;dat=" ";end30:begin rs<=0;dat=5+8'hc0;end31:begin rs<=1;dat=" ";end32:begin rs<=0;dat=6+8'hc0;end33:begin rs<=1;dat=" ";end34:begin rs<=0;dat=7+8'hc0;end35:begin rs<=1;dat=" ";end36: beginrs=0; dat='h80;enddefault:counter<=0;endcaseif(counter==37) counter<=0;else counter<=counter+1;endenddefault: state=init;endcaseendendmodule5、除法器模块,module divider(quotient,remainder,ready,error,word1,word2,start,clock,reset);parameter L_divn=16,L_divr=12,S_idle=0,S_adivr=1,S_adivn=2,S_div=3,S_err=4, L_state=3,L_cnt=4,Max_cnt=L_divn-L_divr; output [L_divn-1:0] quotient,remainder;output ready,error;input [L_divn-1:0] word1;//dividendstart,clock,reset;//0,start,1,resetstate,next_state;Load_words,Subtract,Shif_dividend,Shift_divisor;reg [L_divn-1:0] quotient; reg [L_divn:0] dividend; reg [L_divr-1:0]divisor;num_Shift_dividend,num_Shift_divisor;comparison; wire MSB_divr=divisor[L_divr-1]; wire ready=((state==S_idle)&&reset); wire error=(state==S_err);wire Max=(num_Shift_dividend==Max_cnt+num_Shift_divisor); wiresign_bit=comparison[L_divr];assign remainder=(dividend[L_divn-1:L_divn-L_divr])>num_Shift_divisor;/////////always @(state or dividend or divisor or MSB_divr) case(state) S_adivr: if(MSB_divr==0)comparison=dividend[L_divn:L_divn-L_divr]+{Tb1,~(divisor<<1)}+1'b1; elsecomparison=dividend[L_divn:L_divn-L_divr]+{1'b1,~divisor[L_divr-1:0]} default:comparison=dividend[L_divn:L_divn-L_divr]+{1'b1,~divisor[L_divr-1:0]}+1'b1;endcasealways @(posedge clock or negedge reset) if(!reset) state<=S_idle; else state<=next_state; always @(state or word1 or word2 or start or comparison or sign_bit or Max) beginLoad_words=0;Subtract=0;Shift_dividend=0;Shift_divisor=0;case(state)S_idle:case(!start)0: next_state=S_idle;1:if(word2==0) next_state=S_err;else if(word1) begin next_state=S_adivr;Load_words=1; else next_state=S_idle;endcaseS_adivr:case(MSB_divr)0: if(sign_bit==0) begin next_state=S_adivr;Shift_divisor=1else if(sign_bit==1) next_state=S_adivn; 1: next_state=S_div;endcaseS_adivn:case({Max,sign_bit})2'b00: next_state=S_div;2'b01: begin next_state=S_adivn;Shift_dividend=1; end 2'b10: begin next_state=S_idle;Subtract=1; end 2'b11:next_state=S_idle; endcase S_div:case((Max,sign_bit})input [L_divr-1:0] word2;//divisorinput reg [L_state-1:0]regreg [L_cnt-1:0] reg [L_divr:0]2'b00: begin next_state=S_div;Subtract=1;end2'b01: next_state=S_adivn;2'b10: begin next_state=S_div;Subtract=1;end2'b11: begin next_state=S_div;Shift_dividend=1; endendcasedefault: next_state=S_err;endcaseendalways @(posedge clock or negedge reset)beginif(!reset)begindivisor<=0;dividend<=0;quotient<=0;num_Shift_dividend<=0;num_Shift_divisor<=0;endelse if(Load_words==1)begindividend<=word1;divisor<=word2;quotient<=0;num_Shift_dividend<=0;num_Shift_divisor<=0;endelse if(Shift_divisor)begindivisor<=divisor<<1;num_Shift_divisor<=num_Shift_divisor+1;endelse if(Shift_dividend)begindividend<=dividend<<1;quotient<=quotient<<1;num_Shift_dividend<=num_Shift_dividend+1;endelse if(Subtract)begindividend[L_divn:L_divn-L_divr]<=comparison;quotient[0]<=1;endend endmodule6、铃声模块:module liangzhu(sys_clk,rst_n,sp);input sys_clk,rst_n;output sp;reg sp;reg[3 :0] high,med,low;reg[13:0] divider,origin;reg[7 :0] counter;reg[23:0] clk_cnt;always @ (posedge sys_clk or posedge rst_n) if (rst_n)clk_cnt <= 24'd0;elseclk_cnt <= clk_cnt + 1'b1;wire clk_6mhz = clk_cnt[2];wire clk_4hz = clk_cnt[23];wire carry=(divider==16383);always @(posedge clk_6mhz)beginif(carry)divider=origin;elsedivider=divider+1'b1;endalways@(posedge carry)beginsp =~sp;endalways@(posedge clk_4hz) begincase({high ,med ,low}) 12'b000000000011 12'b000000000101 12'b000000000110 12'b00000000011112'b00000001000012'b00000010000012'b00000011000012'b00000101000012'b00000110000012'b00010000000012'b000000000000default:origin=14'd0;endcaseendalways@(posedge clk_4hz) origin=14'd7281; origin=14'd8730; origin=14'd9565; origin=14'd10310; origin=14'd10647; origin=14'd11272; origin=14'd11831; origin=14'd12556; origin=14'd12974; origin=14'd13516; origin=14'd16383;beginif(counter==8'd50)counter=8'd0;elsecounter=counter+1'b1;case(counter)8'd 0:{high,med,low}=12'b0000_0000_0011;8'd 1:{high,med,low}=12'b0000_0000_0011;8'd 2:{high,med,low}=12'b0000_0000_0011;8'd 3:{high,med,low}=12'b0000_0000_0011;8'd 4:{high,med,low}=12'b0000_0000_0101;8'd 5:{high,med,low}=12'b0000_0000_0101;8'd 6:{high,med,low}=12'b0000_0000_0101;8'd 7:{high,med,low}=12'b0000_0000_0110;8'd 8:{high,med,low}=12'b0000_0001_0000;8'd 9:{high,med,low}=12'b0000_0001_0000;8'd10:{high,med,low}=12'b0000_0001_0000;8'd11:{high,med,low}=12'b0000_0010_0000;8'd12:{high,med,low}=12'b0000_0000_0110;8'd13:{high,med,low}=12'b0000_0001_0000;8'd14:{high,med,low}=12'b0000_0000_0101;8'd15:{high,med,low}=12'b0000_0000_0101;8'd16:{high,med,low}=12'b0000_0101_0000;8'd17:{high,med,low}=12'b0000_0101_0000;8'd18:{high,med,low}=12'b0000_0101_0000;8'd19:{high,med,low}=12'b0001_0000_0000;8'd20:{high,med,low}=12'b0000_0110_0000;8'd21:{high,med,low}=12'b0000_0101_0000;8'd22:{high,med,low}=12'b0000_0011_0000;8'd23:{high,med,low}=12'b0000_0101_0000;8'd24:{high,med,low}=12'b0000_0010_0000;8'd25:{high,med,low}=12'b0000_0010_0000;8'd26:{high,med,low}=12'b0000_0010_0000;8'd27:{high,med,low}=12'b0000_0010_0000;8'd28:{high,med,low}=12'b0000_0010_0000;8'd29:{high,med,low}=12'b0000_0010_0000;8'd30:{high,med,low}=12'b0000_0010_0000;8'd31:{high,med,low}=12'b0000_0010_0000;8'd32:{high,med,low}=12'b0000_0010_0000;8'd33:{high,med,low}=12'b0000_0010_0000;8'd34:{high,med,low}=12'b0000_0010_0000;8'd35:{high,med,low}=12'b0000_0011_0000;8'd36:{high,med,low}=12'b0000_0000_0111;8'd37:{high,med,low}=12'b0000_0000_0111;8'd38:{high,med,low}=12'b0000_0000_0110;8'd39:{high,med,low}=12'b0000_0000_0110;8'd40:{high,med,low}=12'b0000_0000_0101;8'd41:{high,med,low}=12'b0000_0000_0101;8'd42:{high,med,low}=12'b0000_0000_0101;8'd43:{high,med,low}=12'b0000_0000_0110;8'd44:{high,med,low}=12'b0000_0001_0000;8'd45:{high,med,low}=12'b0000_0001_0000;8'd46:{high,med,low}=12'b0000_0010_0000;8'd47:{high,med,low}=12'b0000_0010_0000;default:{high,med,low}=12'd0;endcase//后边乐曲片断此处省略endendmodule后记:本人深深的体会到语法的重要性,一个小小的语法问题有时候可以折磨人几天甚至几个月。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于FPGA的多功能万年历1. 绪论现代科技在不断进步电子技术在不断发展,电子产品设计复杂程度也在不断增加。
而且电子产品的更新换代也越来越快,现在只靠传统的纯硬件的设计方法已经不能满足现代人们的要求。
EDA就是典型的硬件设计软件化的设计平台。
EDA是一项非常先进的技术,它有许多别的技术没有的优点:像单片机需要先画出硬件图再编写相对应的程序,而EDA是先编好程序再画图的,而且模块化的编程还会在软件中生成相应的封装元件,使最后画原理图变的更加简单;可以编好程序就直接仿真,程序出现错误可以在源文件内部直接改;并且设计好的总系统可以集成在一个体积小、功耗低、可靠性高的芯片上。
本设计采用VHDL语言,VHDL语言是一种全方位的数字系统设计和测试的硬件描述。
它支持原理图输入方法以及传统的文件输入方。
对于前者适用于小规模的数字集成电路,并进行模拟仿真。
而对于大规模的、复杂的系统,如果用纯原理图设计方法的话的,由于种种条件和环境制约,会导致工作效率底而且容易出错的等缺点。
在信息技术的今天,集成电路逐渐的趋向于系统化、微尺寸化、低功耗高集成化,因此,高密度可编程逻辑器件和VHDL越来越得到设计者的青睐。
它具有极强的描述能力,支持结构、数据流、行为三种描述形式的混合的设计方式,描覆盖面广、抽象能力强。
它能支持系统行为级、逻辑门级和寄存器传输级三个不同层次的设计。
在本设计中用到的FPGA是特殊的ASIC芯片,ASIC是一种带有逻辑处理的加速处理器的专用的系统集成电路。
它具有功耗低、速度快、集成度、设计制造成本低等优点。
本设计是研究基于FPGA的多功能万年历的设计,主要实现以下功能:能够显示年、月、日、时、分、秒,时间采用24小时制。
当时间不准确时还可以手动校准。
本系统还能实时的显示当前的温度,扩展了万年历的功能。
我采用的是数字温度传感器DS18B20和FPGA组成的温度采集系统,此系统具有硬件电路简单,抗干扰能力强等优点。
1.1 项目研究的背景和意义现在是一个科技迅速发展的时代。
新的电子产品、电子技术日异更新。
生在21世纪的我们应该都深深的体会到电子产品给我们带来的变化,而且电子产品更是随处可见。
随着科技的发展人们的生活节奏也越来越快,时间对人们来说也是越来越宝贵。
在这样快节奏的生活里,人们常常会忘记了时间,一旦遇到重要的会议或重要的事情而忘记了时间,这将会带来很大的损失。
而传统的钟表已经不能满足这些人的要求。
随着科技的发展和社会的进步,人们对数化日历的要求也越来越高。
数字化的日历具有功耗低、多功能化、一劳永逸等优点,因此数字化的日历必将取代传统的日历走入寻常百姓家。
本设计采用的是数字温度传感器DS18B20和FPGA组成的温度采集系统。
数字温度传感器DS18B20,可以直接与FPGA相连,构成简单的测量电路,这样就方便实现远距离传输和多点温度测量;而且FPGA相对于单片机来说速度快,修改方便,可以减少开发成本和时间,并增加了系统的灵活性。
EDA是一项非常先进的技术,它有许多别的技术没有的优点:像单片机需要先画出硬件图再编写相对应的程序,而EDA是先编好程序再画图的,而且模块化的编程还会在软件中生成相应的封装元件,使最后画原理图变的更加简单;可以编好程序就直接仿真,程序出现错误可以在源文件内部直接改;并且设计好的总系统可以集成在一个体积小、功耗低、可靠性高的芯片上。
1.1 课题相关技术的发展现代电子产品基本上都是大量使用大规模的可编程的逻辑器件,这样就降低了产品的功耗、缩小了电子产品的体积、功能也越来越多样化、产品的性能也得到提高。
现代计算机技术在电子产品开发中得到了广泛的应用,以前需要一两个月才能开发出来的,现在只要几个星期甚至更短的时间,不仅仅缩短了电子产品的研发周期还提高了自动化程度,降低了生产的成本,增加了产品的竞争力。
EDA(电子设计自动化)是最近几年才迅速发展起来的,它是将计算机软件、硬件、微电子技术交叉运用的现代电子技术。
现在电子产品都在趋于数字化,基于EDA的数字系统的设计具有很大的应用市场。
可编程逻辑器件自EDA诞生以来,经历了PLA、PAL、GAL、CPLD、FPGA几个阶段。
现在比较流行的可编程逻辑器件就是美国ALTERA公司的FPGA和CPLD。
可编程逻辑器件采用全新的结构和先进的技术可以根据用户的要求来构造逻辑功能的数字集成电路,加上MaxplusII(或最新的QUARTUS)开发环境,不仅简化了电路的设计,降低了成本,提高了系统的可靠性,也给数字化设计带了了重大变革。
电子设计的核心就是EDA技术,EDA技术是指以计算机为开发平台,融合应用电子技术,计算机技术而研制成的通用软包。
EDA技术经历了70年代的计算机辅助设计CAD、80年代的计算机辅助工程CAE和电子系统设计自动化ESDA三个发展阶段。
它的基本特征是:“自顶向下”的设计方法,对整个系统进行方案设计和功能划分,提高了设计的效率,比单片机或C语言要简单易懂。
本设计利用硬件描述语言结合可编程逻辑器件进行的,VHDL语言具有一下优点:(1)VHDL的描述范围宽使它成为高层次的设计的核心,将工作人员的重心提高到了系统功能的实现与调试。
(2)VHDL可以用简洁的代码来描述复杂的控制逻辑设计,灵活且方便。
(3)VHDL不依赖与特定的器件,方便了工艺的转换。
(4)VHDL是一个标准的语言,众多的EDA厂商都支持,因此移植性强。
1.2 课题研究的内容本设计主要研究基于FPGA的多功能万年历,要求如下:(1)显示年、月、日、时、分、秒,时间以24小时为一个周期。
(2)具有校准以及报时功能,可以对年、月、日、时、分及秒进行单独校对,使其校正到标准时间。
(3)能够实时的显示当前温度。
1.3 设计方案论证与选择方案一:运用单片机C语言实现多功能万年历的设计按照设计要求,系统软件编程应包含三个部分:输入部分,选择导出部分,输出显示部分。
相应的系统硬件部分除了核心模块单片机之外,主要的外围部件还有按键、传感器等。
其中单片机系统作为中央处理单元,根据逻辑开关输入的信号转换为显示部分能识别的方式传递给显示部分,显示部分接到传来的指示信号做出相应的显示。
此方法运用了当前最常见的C语言,方案较简洁,不过C语言难以掌握,因此本设计不采用此方法。
方案二:运用数字逻辑电路实现多功能万年历的设计采用74138、74161和其它器件构成实现对万年历控制功能的硬件电路。
由设计要求可知,可以把电路分为按键控制电路,译码、显示、驱动等各部分电路。
开关控制电路,译码与显示驱动电路,显示电路。
这种方案是由纯硬件电路实现的设计,优点是省略了软件部分的设计,但是这种方案因为是纯硬件实现的,成本较高,误差较大,不灵活,因此在本次设计中也不予以采用。
方案三:运用EDA技术实现多功能万年历的设计根据设计要求,系统设计依靠EDA的MAX+PLUS Ⅱ设计软件、VHDL硬件描述语言及FPGA芯片实现多功能万年历的设计。
即在MAX+PLUS Ⅱ软件中用VHDL语言编写各模块程序,通过编译后分别封装成元器件,这些元器件生成顶层文件,再画出硬件电路图,这是EDA硬件软件化的一大特点。
最后借助EDA实验箱实现硬件仿真的功能。
软硬件相结合,层次分明,结构清晰。
且VHDL语言简单易懂,FPGA芯片也是当今的流行趋势。
综合以上三种设计方案,方案三是最为经济合理的,也是我们最能理解的。
2. FPGA简介2.1 FPGA概述FPGA(Field Programmable Gate Array)即现场可编程门阵列,它是在PLA、GLA、CPLD等可编程器件的基础上进一步发展的产物。
它是专用集成电路中的一种半定制电路,具有门电路数多的优点。
2.2 FPGA基本结构FPGA器件在结构上,由逻辑功能块排列为阵列,它的结构可以分为三个部分:可编程逻辑块CLB(Configurable Logic Block)可编程I/O模块(Input/Output Block)和可编程内部连线PI(Programmable Interconnect)。
(1).CLB是FPGA的主要组成部分,图2-1是CLB基本结构框图。
图2-1 CLB 基本结构(2).可编程输入/输出模块IOB ,编程灵活根据系统功能的需要可被配置为输入、输出或双向传输三种功能,实现不同的逻辑功能,满足不同的的逻辑接口的需要。
(3).可编程内部连线PI 。
XC4000系列芯片的连线资源由水平和垂直的布线通道构成,较短的线段分布于单个CLB 中,较长的线段跨接与两个CLB 之间,而最长的线段跨越怎个芯片。
可编程开关用来把CLB 的输入输出接到其周围的线段上,并且可以将两个不同的线段连接在一起。
3. 多功能万年历总体设计方案3.1 多功能万年历的构成日历实际上是一个对标准频率(1HZ )进行计数的计数电路。
因此标准的1HZ 时间信号必须做到准确稳定。
通常使用石英晶体振荡器电路构成数字钟。
同时为了保证与标准时间的一致,需要在电路上加上一个校准电路。
同时图3-1所示为日历的一般构成框图。
主要包括时间基准电路、计数器电路、控制电路、译码和显示电路。
其核心的部分就是控制逻辑电路,不断完善它可以增加系统的功能。
可编程开关矩输入输出模块互连资源图3-1 日历时钟部分组成框图本设计还具有显示年、月、日的功能,其显示范围为其总体框架如图3-2。
图3-2 总体框架3.2 多功能万年历工作原理日历的核心部分就是时钟部分,实际就是对标准的时钟信号进行计数,秒计数器对秒脉冲信号进行计数,记满60秒后就分计数器进位同时又从0开始计数;分计数器对秒的进位信号进行计数,记满60后向时计数器进位同时又从0开始计数;同理时计数器为24进制计数器,记满24向日计数器进位同时计数器清零,重新开始计数。
由于日数根据年、月的不同天数也不同,必须由年、月共同决定,日记满后12个月后向年计数器进位。
各个计数器的输出分别经过译码器送数码管显示。
当计时出现错误时,可以用校准电路对年、月、日、时、分、秒进行校准。
在系统中除了需要校准的控制信号外,还需要有时钟的使能信号、清零信号。
这些控制信号由一个4×4矩形键盘输入。
七段译码器构成译码显示电路,数码管完成显示功能。
在此的系统中利用数字温度传感器DS18B20和FPGA组成的温度采集系统经处理后送至数码管显示即可。
4 单元电路4.1 分频模块电路设计与实现在此系统中晶体振荡器的信号的稳定性与精准度直接影响到整个日历时钟的准确度。
为了保证基准时钟的准确性,所以我决定选用特性非常好的石英晶体,它只让某一特定频率点的信号通过,其他频率段的信号全部会被它衰减,而且它震荡信号的频率与震荡电路中的元器件完全无关。
所以这种震荡电路输出的是准确度极高的信号,再利用分频电路的话就会得到标准的秒信号,其组成框图如图4-1。