1、制氧机,鱼跃家庭制氧机实现了从 0000-9999 年的时钟,其实万年历和十万年历,都是差不多,等到地球能转到 9999 年再改代码也不迟,哈哈!我这里有顶层和底层文件,顶层主要是调用模块和做按键处理,具体按键防抖动原理,参见偶的以前的博文,我写完这个万年历的代码,还没来得及优化,占用了太多了逻辑门,可以进一步优化。大致思路是:第一次按下 KEY1 的时候,所有计时停止,再按 KEY1,年就闪烁,按下 KEY2 和 KEY3 进行加减。再按 KEY1,月就闪烁,按下 KEY2 和KEY3 进行加减 依次为调 年-月-日- 星期-时分秒, 再次按一下 KEY1,进入正常运行模式。好了先上顶层模块
2、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),.ke
3、y3(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;
4、key1_out = key1_reg2 key2_out = key2_reg2 制氧机,鱼跃家庭制氧机key3_out = key3_reg2 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:0count,count
5、1; /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,one_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 s
6、tate0 =8h00, /设置 8 位格式,2 行,5*7 8h38; state1 =8h01, /整体显示,关光标, 不闪烁 8h0C 闪烁 8h0estate2 =8h02, /设定输入方式,增量不移位 8h06state3 =8h03, /清除显示 8h01state4 =8h04, /显示第一行的指令 80Hstate5 =8h05, /显示第二行的指令 80H+40Hscan =8h06, nul =8h07; parameter data0 =8h10, /2 行 32 个数据状态data1 =8h11,data2 =8h12,data3 =8h13,data4 =8h14,d
7、ata5 =8h15,data6 =8h16,data7 =8h17,data8 =8h18,data9 =8h19,data10 =8h20,data11 =8h21,data12 =8h22,data13 =8h23,data14 =8h24,data15 =8h25,data16 =8h26,data17 =8h27,data18 =8h28,data19 =8h29,data20 =8h30,制氧机,鱼跃家庭制氧机data21 =8h31,data22 =8h32,data23 =8h33,data24 =8h34,data25 =8h35,data26 =8h36,data27 =8
8、h37,data28 =8h38,data29 =8h39,data30 =8h40,data31 =8h41;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:
9、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=8d0;fen=8d0;miao=8d0;end/=产生 LCD 时序脉冲= always (posedge clk ) /获得 LCD 时钟begincount=count+1;if(count=32d50000)begin
10、count=32b0;lcd_clk=lcd_clk;end制氧机,鱼跃家庭制氧机end/=产生闪烁扫描时钟= reg 31:0 count2;reg scan_flag;always (posedge clk or negedge rst) /获得校准时间选中闪烁状态beginif(!rst)beginscan_flag=1b0;endelsebegincount2=count2+1;if(count2=32d10000000)begincount2=32b0;scan_flag=scan_flag;endendend/=产生按键标志位= reg 3:0 flag;always (posed
11、ge clk or negedge rst )beginif(!rst)beginflag=4b0;endelseif(key1)beginflag=flag+1b1;if(flag=4b1000)flag=4b0000;制氧机,鱼跃家庭制氧机endend/=计时以及校准=reg3:0 week;reg7:0 dat_flag;always (posedge clk or negedge rst ) /时钟计数器beginif(!rst)begin /初始化显示 第一行 2012-05-19 Sat 第二行:Clock:00-00-00shi=8b0;fen=8b0;miao=8b0;mont
12、h=8d5;dat=8d19;year=16d2012;week=4d5;count1=1b0;two_7= (shi/8d10)+8b00110000;two_8= (shi%8d10)+8b00110000;two_10=(fen/8d10)+8b00110000;two_11=(fen%8d10)+8b00110000;two_13=(miao/8d10)+8b00110000;two_14=(miao%8d10)+8b00110000;one_1=(year/16d1000)+8b00110000;one_2=(year%16d1000)/16d100)+8b00110000;one_
13、3=(year%16d100)/8d10)+8b00110000;one_4=(year%8d10)+8b00110000;one_6=(month/8d10)+8b00110000;one_7=(month%8d10)+8b00110000;one_9=(dat/8d10)+8b00110000;one_10=(dat%8d10)+8b00110000;end elsebegintwo_7= (shi/8d10)+8b00110000;two_8= (shi%8d10)+8b00110000;two_10=(fen/8d10)+8b00110000;two_11=(fen%8d10)+8b0
14、0110000;two_13=(miao/8d10)+8b00110000;制氧机,鱼跃家庭制氧机two_14=(miao%8d10)+8b00110000;one_1=(year/16d1000)+8b00110000;one_2=(year%16d1000)/16d100)+8b00110000;one_3=(year%16d100)/8d10)+8b00110000;one_4=(year%8d10)+8b00110000;one_6=(month/8d10)+8b00110000;one_7=(month%8d10)+8b00110000;one_9=(dat/8d10)+8b0011
15、0000;one_10=(dat%8d10)+8b00110000;/ 判断是否为 31 天的月份if(month=8d1|month=8d3|month=8d5|month=8d7|month=8d8|month=8d10|month=8d12)dat_flag=8d31;/ 判断是否为 30 天的月份else if(month=8d4|month=8d6|month=8d9|month=8d11)dat_flag=8d30;/ 判断是否为闰年和平年else if(month=8d2)beginif(year % 4 = 0 else dat_flag=27;endcase (week)/星
16、期 /Mon Tue Wed Thu Fri Sat Sun4b0000 : /1beginone_13=“M“;one_14=“o“;one_15=“n“;end4b0001 : /2beginone_13=“T“;one_14=“u“;one_15=“e“;end4b0010 : /3begin制氧机,鱼跃家庭制氧机one_13=“W“;one_14=“e“;one_15=“d“;end 4b0011 : /4beginone_13=“T“;one_14=“h“;one_15=“u“;end 4b0100 : /5beginone_13=“F“;one_14=“r“;one_15=“i“;
17、end4b0101 : /6beginone_13=“S“;one_14=“a“;one_15=“t“;end4b0110 : /7beginone_13=“S“;one_14=“u“;one_15=“n“;endendcasecase(flag)4b0000 :beginen_sel=1b1; count1=count1+1b1;if(count1=32d49999999)begincount1=1b0;miao=miao+1b1;if(miao=8d59)beginmiao=1b0;fen=fen+1b1;if(fen=8d59)begin制氧机,鱼跃家庭制氧机fen=1b0;shi=sh
18、i+1b1;if(shi=8d23)beginshi=1b0;dat=dat+1b1;week=week+1b1;if(week=4b0110)week=1b1;if(dat=dat_flag)begindat=8d1;month=month+1b1;if(month=8d12)beginmonth=8d1;year=year+1b1;if(year=16d9999)year=16d0; /可以计 1 万年endend endendendendend4b0001 :begincount1=32b0; /shi=shi;fen=fen;miao=miao;year=year;month=mont
19、h;dat=dat;week=week;end4b0010 : /调年begincase(scan_flag)1b0:制氧机,鱼跃家庭制氧机begincount1=32b0; /shi=shi;fen=fen;miao=miao;one_1=8d20;one_2=8d20;one_3=8d20;one_4=8d20;end1b1:begincount1=32b0; /shi=shi;fen=fen;miao=miao;endendcaseif(key2) /加数begin year=year+1b1;if(year=16d9999)year=16d0;endif(key3) /减数begin
20、year=year-1b1;if(year=16d0)year=16d9999;endend4b0011 : /调月begincase(scan_flag)1b0:begincount1=32b0; /shi=shi;fen=fen;miao=miao;one_6=8d20;one_7=8d20;end1b1:begincount1=32b0; /shi=shi;fen=fen;miao=miao;endendcase制氧机,鱼跃家庭制氧机if(key2) /加数begin month=month+1b1;if(month=8d12)month=8d0;endif(key3) /减数begin
21、 month=month-1b1;if(month=8d0)month=8d12;endend 4b0100 : /调日begincase(scan_flag)1b0:begincount1=32b0; /shi=shi;fen=fen;miao=miao;one_9=8d20;one_10=8d20;end1b1:begincount1=32b0; /shi=shi;fen=fen;miao=miao;endendcaseif(key2) /加数begin dat=dat+1b1;if(dat=dat_flag)dat=8d0;endif(key3) /减数begin dat=dat-1b1
22、;制氧机,鱼跃家庭制氧机if(dat=8d0)dat=dat_flag;endend 4b0101 : /调星期begincase(scan_flag)1b0:begincount1=32b0; /shi=shi;fen=fen;miao=miao;one_13=8d20;one_14=8d20;one_15=8d20;end1b1:begincount1=32b0; /shi=shi;fen=fen;miao=miao;endendcaseif(key2) /加数begin week=week+1b1;if(week=4d6)week=4d0;endif(key3) /减数begin wee
23、k=week-1b1;if(week=4d0)week=4d7;endend 4b0110 : /调时begincase(scan_flag)1b0:begin制氧机,鱼跃家庭制氧机count1=32b0; /shi=shi;fen=fen;miao=miao;two_7= 8d20;two_8= 8d20;end1b1:begincount1=32b0; /shi=shi;fen=fen;miao=miao;endendcaseif(key2) /加数begin shi=shi+8b00000001;if(shi=8d23)shi=8b0;endif(key3) /减数begin shi=s
24、hi-8b00000001;if(shi=8b0)shi=23;endend4b0111 : /调分begincase(scan_flag)1b0:begincount1=32b0; /shi=shi;fen=fen;miao=miao;two_10=8d20;two_11=8d20;end1b1:begincount1=32b0; /shi=shi;fen=fen;miao=miao;end制氧机,鱼跃家庭制氧机endcaseif(key2) /加数begin fen=fen+8b00000001;if(fen=8d59)fen=8b0;endif(key3) /减数begin fen=fe
25、n-8b00000001;if(fen=8b0)fen=59;endend 4b1000 : /调秒begincase(scan_flag)1b0:begincount1=32b0; /shi=shi;fen=fen;miao=miao;two_13=8d20;two_14=8d20;end1b1:begincount1=32b0; /shi=shi;fen=fen;miao=miao;endendcaseif(key2) /加数begin miao=miao+8b00000001;if(miao=8d59)miao=8b0;endif(key3) /减数制氧机,鱼跃家庭制氧机begin mi
26、ao=miao-8b00000001;if(miao=8b0)miao=59;endendendcaseend endalways (posedge lcd_clk )begincase(next)state0 :begin rs=1b0; data=8h38; next=state1; endstate1 :begin rs=1b0; data=8h0e; next=state2; endstate2 :begin rs=1b0; data=8h06; next=state3; endstate3 :begin rs=1b0; data=8h01; next=state4; end stat
27、e4 :begin rs=1b0; data=8h80; next=data0; end /显示第一行data0 :begin rs=1b1; data=one_1; next=data1 ; enddata1 :begin rs=1b1; data=one_2; next=data2 ; enddata2 :begin rs=1b1; data=one_3; next=data3 ; enddata3 :begin rs=1b1; data=one_4; next=data4 ; enddata4 :begin rs=1b1; data=one_5; next=data5 ; enddata
28、5 :制氧机,鱼跃家庭制氧机begin rs=1b1; data=one_6; next=data6 ; enddata6 :begin rs=1b1; data=one_7; next=data7 ; enddata7 :begin rs=1b1; data=one_8; next=data8 ; enddata8 :begin rs=1b1; data=one_9; next=data9 ; enddata9 :begin rs=1b1; data=one_10; next=data10 ; enddata10 :begin rs=1b1; data=one_11; next=data11
29、 ; enddata11 :begin rs=1b1; data=one_12; next=data12 ; enddata12 :begin rs=1b1; data=one_13; next=data13 ; enddata13 :begin rs=1b1; data=one_14; next=data14 ; enddata14 :begin rs=1b1; data=one_15; next=data15 ; enddata15 :begin rs=1b1; data=one_16; next=state5 ; endstate5: begin rs=1b0;data=8hC0; ne
30、xt=data16; end /显示第二行data16 :begin rs=1b1; data=two_1; next=data17 ; enddata17 :begin rs=1b1; data=two_2; next=data18 ; enddata18 :begin rs=1b1; data=two_3; next=data19 ; enddata19 :begin rs=1b1; data=two_4; next=data20 ; enddata20 :begin rs=1b1; data=two_5; next=data21 ; enddata21 :制氧机,鱼跃家庭制氧机begin
31、 rs=1b1; data=two_6; next=data22 ; enddata22 :begin rs=1b1; data=two_7; next=data23 ; enddata23 :begin rs=1b1; data=two_8; next=data24 ; enddata24 :begin rs=1b1; data=two_9; next=data25 ; enddata25 :begin rs=1b1; data=two_10; next=data26 ; enddata26 :begin rs=1b1; data=two_11; next=data27 ; enddata2
32、7 :begin rs=1b1; data=two_12; next=data28 ; enddata28 :begin rs=1b1; data=two_13; next=data29 ; enddata29 :begin rs=1b1; data=two_14; next=data30 ; enddata30 :begin rs=1b1; data=two_15; next=data31 ; enddata31 :begin rs=1b1; data=two_16; next=scan ; endscan : /交替更新第一行和第二行数据 begin next=state4; enddefault: next=state0; endcaseendassign en=lcd_clk assign rw=1b0;endmodule