一、使用的MCU為STC89C52RC
二、DS1302驅動
1 #include <REGX52.H> 2 #include "DS1302.h" 3 #include "LCD1602.h" 4 #include "Delay.h" 5 #include "Timer0.h" 6 #include "SKey.h" 7 8 9 void setMode1(); 10 void setMode2(); 11 void Show_Time(); 12 void case0(); 13 void case1(); 14 void case2(); 15 void case3(); 16 void case4(); 17 void flashChoose(); 18 //啟動設定時間的入口 19 char times[] = {0x24, 0x11, 0x24 , 0x19,0x56,0x32, 0x07}; 20 //秒前面的冒號的顯隱開關 21 unsigned char SecondFlashFlag = 0x01; 22 //修改時間時控制選擇的位置的閃爍開關 23 unsigned char chooseFlashFlag = 0x01; 24 //模式: 0預設,1,顯示模式 2,修改模式 25 unsigned int MODE = 0; 26 //透過獨立鍵盤來控制時鐘:1顯示; 2修改 3加,4減。 27 unsigned char KeyN = 0; 28 //選擇要修改的位置: 年月日時分秒(1-6) 29 char selectLoc = 0; 30 //要修改時存放時間的臨時陣列。 31 unsigned char tempArr[7] ; 32 //標記是否修改的標誌 0 未修改 1 修改了 33 unsigned char modifyFlag = 0; 34 void main() 35 { 36 37 LCD_Init(); 38 39 LCD_ShowString(1,1," - - "); 40 LCD_ShowString(2,1," : : "); 41 42 Timer0Init(); 43 //初始化DS1302 44 DS1302_Init(); 45 //DS1302_SetTime2(times); 46 DS1302_ReadTime(); 47 48 while(1){ 49 50 KeyN = getSKey(); 51 if(KeyN!=0){ 52 if(KeyN == 1){ setMode1();} 53 if(KeyN == 2){ setMode2();} 54 //LCD_ShowNum(2,12,KeyN,2); 55 56 } 57 58 switch(MODE){ 59 case 0: 60 case 1: case1(); break; 61 case 2: case2(); break; 62 63 } 64 65 switch(KeyN){ 66 67 case 3: case3(); break; 68 case 4: case4(); break; 69 70 } 71 72 73 Delay(400); 74 75 } 76 77 } 78 79 80 void case0(){ 81 Show_Time(); 82 } 83 84 void case1(){ 85 selectLoc = 0; 86 Show_Time(); 87 88 } 89 90 void case2(){ 91 92 SecondFlashFlag = 1; 93 chooseFlashFlag = !chooseFlashFlag; 94 flashChoose(); 95 } 96 97 98 /** 99 * @bref 對要修改的區域進行閃爍操作 100 * @param 無 101 * @retval 無 102 */ 103 void flashChoose(){ 104 LCD_ShowString(1,1," - - "); 105 LCD_ShowString(2,1," : : "); 106 LCD_ShowNum(1,1,tempArr[0]/16*10 + tempArr[0]%16, 2); 107 LCD_ShowNum(1,4,tempArr[1]/16*10 + tempArr[1]%16, 2); 108 LCD_ShowNum(1,7,tempArr[2]/16*10 + tempArr[2]%16, 2); 109 LCD_ShowNum(2,1,tempArr[3]/16*10 + tempArr[3]%16, 2); 110 LCD_ShowNum(2,4,tempArr[4]/16*10 + tempArr[4]%16, 2); 111 LCD_ShowNum(2,7,tempArr[5]/16*10 + tempArr[5]%16, 2); 112 113 114 switch(selectLoc){ 115 case 1: { 116 if(chooseFlashFlag){ 117 LCD_ShowString(1,1," "); 118 } 119 break; 120 } 121 case 2: { 122 if(chooseFlashFlag){ 123 LCD_ShowString(1,4," "); 124 } 125 break; 126 } 127 case 3: { 128 if(chooseFlashFlag){ 129 LCD_ShowString(1,7," "); 130 } 131 break; 132 } 133 case 4: { 134 if(chooseFlashFlag){ 135 LCD_ShowString(2,1," "); 136 } 137 break; 138 } 139 case 5: { 140 if(chooseFlashFlag){ 141 LCD_ShowString(2,4," "); 142 } 143 break; 144 } 145 case 6: { 146 if(chooseFlashFlag){ 147 LCD_ShowString(2,7," "); 148 } 149 break; 150 } 151 152 } 153 154 } 155 156 157 158 void case3(){ 159 if(MODE == 2){ 160 unsigned int temp = 0; 161 162 switch(selectLoc){ 163 case 1:{ 164 //年 165 temp = tempArr[0]/16*10 + tempArr[0]%16; 166 temp++; 167 if(temp>99){ 168 temp=1; 169 } 170 tempArr[0] = (temp/10)<<4 | (temp%10); 171 172 break; 173 } 174 case 2:{ 175 //月 176 temp = tempArr[1]/16*10 + tempArr[1]%16; 177 temp++; 178 if(temp>12){ 179 temp=1; 180 } 181 tempArr[1] = (temp/10)<<4 | (temp%10); 182 183 break; 184 } 185 case 3:{ 186 //日 187 temp = tempArr[2]/16*10 + tempArr[2]%16; 188 temp++; 189 if( tempArr[1]==0x01||tempArr[1]==0x03 190 ||tempArr[1]==0x05||tempArr[1]==0x07 191 ||tempArr[1]==0x08||tempArr[1]==0x10 192 ||tempArr[1]==0x12){ 193 if(temp>31){ 194 temp=1; 195 } 196 }else if(tempArr[1]==0x04 197 ||tempArr[1]==0x06||tempArr[1]==0x09||tempArr[1]==0x11){ 198 199 if(temp>30){ 200 temp=1; 201 } 202 }else if(tempArr[1]==0x02){ 203 204 if((tempArr[0]/16*10 + tempArr[0]%16)%4==0){ 205 if(temp>29){ 206 temp=1; 207 } 208 }else{ 209 if(temp>28){ 210 temp=1; 211 } 212 } 213 214 } 215 tempArr[2] = (temp/10)<<4 | (temp%10); 216 217 218 break; 219 } 220 case 4:{ 221 //時 222 temp = tempArr[3]/16*10 + tempArr[3]%16; 223 temp++; 224 if(temp>23){ 225 temp=0; 226 } 227 228 tempArr[3] = (temp/10)<<4 | (temp%10); 229 break; 230 } 231 case 5:{ 232 //分 233 temp = tempArr[4]/16*10 + tempArr[4]%16; 234 temp++; 235 if(temp>59){ 236 temp=0; 237 } 238 239 tempArr[4] = (temp/10)<<4 | (temp%10); 240 break; 241 } 242 case 6:{ 243 //秒 244 temp = tempArr[5]/16*10 + tempArr[5]%16; 245 temp++; 246 if(temp>59){ 247 temp=0; 248 } 249 tempArr[5] = (temp/10)<<4 | (temp%10); 250 break; 251 } 252 253 254 } 255 //修改時間了 256 modifyFlag = 0x01; 257 258 } 259 260 261 Delay(5); 262 } 263 264 void case4(){ 265 if(MODE == 2){ 266 267 unsigned int temp = 0; 268 269 switch(selectLoc){ 270 case 1:{ 271 //年 272 temp = tempArr[0]/16*10 + tempArr[0]%16; 273 temp--; 274 if(temp<0){ 275 temp=99; 276 } 277 tempArr[0] = (temp/10)<<4 | (temp%10); 278 279 break; 280 } 281 case 2:{ 282 //月 283 temp = tempArr[1]/16*10 + tempArr[1]%16; 284 temp--; 285 if(temp<1){ 286 temp=12; 287 } 288 tempArr[1] = (temp/10)<<4 | (temp%10); 289 290 break; 291 } 292 case 3:{ 293 //日 294 temp = tempArr[2]/16*10 + tempArr[2]%16; 295 temp--; 296 if( tempArr[1]==0x01||tempArr[1]==0x03 297 ||tempArr[1]==0x05||tempArr[1]==0x07 298 ||tempArr[1]==0x08||tempArr[1]==0x10 299 ||tempArr[1]==0x12){ 300 if(temp<1){ 301 temp=31; 302 } 303 }else if(tempArr[1]==0x04 304 ||tempArr[1]==0x06||tempArr[1]==0x09||tempArr[1]==0x11){ 305 306 if(temp<1){ 307 temp=30; 308 } 309 }else if(tempArr[1]==0x02){ 310 311 if((tempArr[0]/16*10 + tempArr[0]%16)%4==0){ 312 if(temp<1){ 313 temp=29; 314 } 315 }else{ 316 if(temp<1){ 317 temp=28; 318 } 319 } 320 321 } 322 tempArr[2] = (temp/10)<<4 | (temp%10); 323 324 325 break; 326 } 327 case 4:{ 328 //時 329 temp = tempArr[3]/16*10 + tempArr[3]%16; 330 temp--; 331 if(temp<0){ 332 temp=23; 333 } 334 335 tempArr[3] = (temp/10)<<4 | (temp%10); 336 break; 337 } 338 case 5:{ 339 //分 340 temp = tempArr[4]/16*10 + tempArr[4]%16; 341 temp--; 342 if(temp<0){ 343 temp=59; 344 } 345 346 tempArr[4] = (temp/10)<<4 | (temp%10); 347 break; 348 } 349 case 6:{ 350 //秒 351 temp = tempArr[5]/16*10 + tempArr[5]%16; 352 temp--; 353 if(temp<0){ 354 temp=59; 355 } 356 tempArr[5] = (temp/10)<<4 | (temp%10); 357 break; 358 } 359 360 361 } 362 363 //修改時間了 364 modifyFlag = 0x01; 365 } 366 Delay(5); 367 } 368 369 370 371 372 373 /** 374 * @bref 顯示時間 375 * @param 無 376 * @retval 無 377 */ 378 void Show_Time(){ 379 380 DS1302_ReadTime(); 381 382 LCD_ShowNum(1,1,DS1302_TIME[0]/16*10 + DS1302_TIME[0]%16, 2); 383 LCD_ShowNum(1,4,DS1302_TIME[1]/16*10 + DS1302_TIME[1]%16, 2); 384 LCD_ShowNum(1,7,DS1302_TIME[2]/16*10 + DS1302_TIME[2]%16, 2); 385 LCD_ShowNum(2,1,DS1302_TIME[3]/16*10 + DS1302_TIME[3]%16, 2); 386 LCD_ShowNum(2,4,DS1302_TIME[4]/16*10 + DS1302_TIME[4]%16, 2); 387 LCD_ShowNum(2,7,DS1302_TIME[5]/16*10 + DS1302_TIME[5]%16, 2); 388 //LCD_ShowString(1,11,Cvt_Day(DS1302_TIME[6])); 389 if(SecondFlashFlag){ 390 391 LCD_ShowString(2,6,":"); 392 }else{ 393 394 LCD_ShowString(2,6," "); 395 } 396 397 if(MODE == 2){ 398 //選擇年 399 if(selectLoc == 1){ 400 LCD_ShowString(1,1," "); 401 402 } 403 //選擇月 404 if(selectLoc == 2){ 405 LCD_ShowString(1,4," "); 406 407 } 408 //選擇日 409 if(selectLoc == 3){ 410 LCD_ShowString(1,7," "); 411 412 } 413 //選擇時 414 if(selectLoc == 4){ 415 LCD_ShowString(2,1," "); 416 417 } 418 //選擇分 419 if(selectLoc == 5){ 420 LCD_ShowString(2,4," "); 421 422 } 423 //選擇秒 424 if(selectLoc == 6){ 425 426 LCD_ShowString(2,7," "); 427 } 428 429 430 } 431 432 433 434 435 } 436 437 /** 438 * @bref 設定模式1 439 * @param 無 440 * @retval 無 441 */ 442 void setMode1(){ 443 if(MODE ==2){ 444 // 先讓MODE不等於2,不然chooseFlashFlag又變回1了 445 MODE = 0; 446 chooseFlashFlag = 0; 447 //修改時間了就設定,沒有修改,就不設定。 448 if(modifyFlag){ 449 DS1302_SetTime2(tempArr); 450 } 451 DS1302_ReadTime(); 452 modifyFlag = 0; 453 454 } 455 MODE ==1; 456 457 } 458 459 void setMode2(){ 460 unsigned char i=0; 461 if(MODE!=2){ 462 DS1302_ReadTime(); 463 for(i=0;i<7;i++){ 464 tempArr[i] = DS1302_TIME[i]; 465 } 466 } 467 MODE = 2; 468 selectLoc++; 469 if(selectLoc>6 || selectLoc<=0){ 470 selectLoc=1; 471 472 } 473 474 } 475 476 477 /** 478 * @bref timer0 中斷函式,用於將秒前面的冒號做跳動。 479 * @param 無 480 * @retval 無 481 */ 482 483 void Timer0_Routine() interrupt 1 484 { 485 static unsigned int Count; 486 TL0 = 0x18; //設定定時初值 487 TH0 = 0xFC; //設定定時初值 488 Count++; 489 if(Count == 1000) 490 { 491 SecondFlashFlag = !SecondFlashFlag; 492 Count=0; 493 494 } 495 496 497 }
1. 使用LCD1602顯示時鐘。
2. 使用Timer0來做時鐘跳動的重新整理。
3. 透過K1~K4四個獨立鍵位來操作時鐘的顯示和修改。