【代码】verilog之:电子钟
功能:显示时分秒,能够设置时间。
实现:两个按键,一个进入设置,一个加数字。显示用LCD5110
用状态机实现,总共四种状态
idle(正常运行)——s_hour(时设置状态)——s_min(分设置状态)——s_sec(秒设置状态)
四种状态用set键循环切换,add键在后三种状态中可以对值进行加1操作。
代码如下,此处按键输入为消抖后的
需要注意的是时间运行时的判断阈值和按键设置时的判断阈值不同
1 /*-------------------------------------------------------------------------------------- 2 -- Filename ﹕ lcd5110.v 3 -- Author ﹕ZRtech 4 -- Description ﹕5110显示字符 5 -- Called by ﹕Top module 6 -- Revision History ﹕10-5-20 7 -- Revision 1.0 8 -- Company ﹕ ZRtech Technology .Inc 9 -- Copyright(c) 2010, ZRtech Technology Inc, All right reserved 10 ---------------------------------------------------------------------------------------*/ 11 module time_module 12 ( 13 CLK,RSTn,keyset,keyadd,hour1,hour2,min1,min2,sec1,sec2,kstate,CLK2HZ 14 ); 15 input CLK; 16 input RSTn; 17 input keyset; 18 input keyadd; 19 output reg[1:0]hour1; 20 output reg[3:0]hour2; 21 output reg[2:0]min1; 22 output reg[3:0]min2; 23 output reg[2:0]sec1; 24 output reg[3:0]sec2; 25 output [1:0]kstate; 26 output reg CLK2HZ; 27 28 //**************************************************** 29 reg [27:0]cnt;//分频计数器 30 reg CLK1HZ;//分频时钟 31 reg s_hour_cnt;//小时计数进位状态 32 33 reg[1:0] p; //状态机定义 34 //reg[2:0] p_back; //状态返回 35 36 parameter idle=2'd0;//状态值定义 37 parameter s_hour=2'd1; 38 parameter s_minute=2'd2; 39 parameter s_second=2'd3; 40 41 assign kstate=p; 42 43 always@(posedge CLK ) //时钟分频 44 begin 45 if(!RSTn) 46 cnt<=0; 47 else if(cnt==28'd24_999_999) //产生1Hz时钟脉冲 48 begin 49 cnt<=0; 50 CLK1HZ<=1; 51 CLK2HZ<=~CLK2HZ;//2hz时钟输出 52 //min1<=0; 53 end 54 else begin 55 cnt<=cnt+1; 56 CLK1HZ<=0; 57 //min1<=min1+1; 58 end 59 end 60 61 62 63 always@(posedge CLK )//状态机切换 64 begin 65 if(!RSTn) 66 p<=idle; 67 else 68 case (p) 69 idle: begin 70 if (keyset) 71 p<=s_hour; //next设置小时 72 else p<=idle; 73 /***************************************/ 74 case(s_hour_cnt)//小时计数 75 0: begin 76 if(hour1==2)//10进位情况 77 begin 78 s_hour_cnt<=1; 79 end 80 if(hour2 ==10) 81 begin 82 hour2<=0; 83 hour1<=hour1+1; 84 end 85 //else hour2<=hour2+1; 86 end 87 1: if(hour2==4) 88 begin 89 s_hour_cnt<=0;//4进位情况 90 hour1<=0; 91 hour2<=0; 92 end 93 endcase 94 /***************************************/ 95 if(min1==6) //分钟计数 96 begin 97 min1<=0; 98 hour2<=hour2+1; 99 end 100 else if(min2==10) 101 begin 102 min1<=min1+1; 103 min2<=0; 104 end 105 106 /***************************************/ 107 if(sec1==6) //秒计数 108 begin 109 sec1<=0; 110 min2<=min2+1; 111 end 112 else if(sec2==10) 113 begin 114 sec1<=sec1+1; 115 sec2<=0; 116 end 117 else if(CLK1HZ)//每秒加一 118 sec2<=sec2+1; 119 end 120 s_hour: 121 begin 122 if (keyset) 123 p<=s_minute; //next设置分钟 124 else p<=s_hour; 125 /***************************************/ 126 if(keyadd) //小时数值按键设定 127 begin 128 case(s_hour_cnt)//小时计数 129 0: begin 130 if(hour1==2)//10进位情况 131 begin 132 s_hour_cnt<=1; 133 end 134 if(hour2 ==9) 135 begin 136 hour2<=0; 137 hour1<=hour1+1; 138 end 139 else hour2<=hour2+1; 140 end 141 1: if(hour2==3) 142 begin 143 s_hour_cnt<=0;//4进位情况 144 hour1<=0; 145 hour2<=0; 146 end 147 else hour2<=hour2+1; 148 endcase 149 end 150 end 151 s_minute: 152 begin 153 if (keyset) 154 p<=s_second; //next设置秒 155 else p<=s_minute; 156 157 if(keyadd) //分钟数值按键设定 158 begin 159 if(min1==5 && min2==9) //分钟计数 160 begin 161 min1<=0; 162 min2<=0; 163 hour2<=hour2+1; 164 end 165 else if(min2==9) 166 begin 167 min1<=min1+1; 168 min2<=0; 169 end 170 else min2<=min2+1; 171 end 172 end 173 s_second:begin 174 if (keyset) 175 p<=idle; //next返回正常显示 176 else p<=s_second; 177 178 if(keyadd) //秒数值按键设定 179 begin 180 if(sec1==5 && sec2==9) //秒计数 181 begin 182 sec1<=0; 183 min2<=min2+1; 184 end 185 else if(sec2==9) 186 begin 187 sec1<=sec1+1; 188 sec2<=0; 189 end 190 else sec2<=sec2+1; 191 end 192 end 193 194 endcase 195 end 196 197 198 endmodule