?? clock.c
字號:
/* 定時器,可以設置小時和分鐘; 可以設置開始時間,和結束時間,在P3.7口輸出變化情況(opto=0xFF P3.7=1, opto=0x7F P3.7=0)*/#include <reg52.h> #include <stdio.h> unsigned char sec100,sec,min,hour,day,month,flag1,temp,opto;unsigned char digit,buffer[4],onHour1,onMin1,offHour1,offMin1;char cputick,key,delay,count1;char keyflag, showdelay;unsigned char showsave;//char convert[10] = {0x3F,0x0c,0x76,0x5e,0x4d,0x5b,0x7b,0x0e,0x7f,0x5f};// 數碼管的編碼,需要取反輸出0-9char convert[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};// 各個月的天數char days[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};void pause(int); void scanLED();void manualOnOff();void savetimeOnOff1(); void setmin();void sethour();void setonHour();void setonMin();void setoffHour();void setoffMin();void setday();void setmonth();void showOnce();void savetimeOff1();void blinkset();void time();void timeToBuffer();void dateToBuffer();void blink();void offmsd();void keyexe();void keydelay();void comparetime();/*---------------------------------------------------------------------------*//* 定時器零的中斷服務程序 *//*---------------------------------------------------------------------------*/void timer0int (void) interrupt 1 using 1 { TL0 = 0; TH0 |= 0xB8; // reload timer 0 with 0B800H 22.1184MHZ cputick++; time(); // update realtime clock }/*---------------------------------------------------------------------------*//* 主函數 *//*---------------------------------------------------------------------------*/void main(){ EA = 1; // 允許所有中斷 ET0 = 1; // 允許定時器0中斷 TMOD |= 0x01; // timer 0 run 16 bit counter TR0 = 1; // run timer 0 opto = 0xff; // 控制P3.7的輸出 cputick = 0; // 每10ms加1 month = 1; // 月的初始值 day = 1; // 日的初始值 hour = 18; // 小時的初始值 min = 0; // 分鐘的初始值 sec = 0; // 秒的初始值 key = -1; // 首次按鍵 keyflag = 0; // 設置鍵沒有按下 flag1 = 0; showsave = 0; // 記錄閃爍多少次沒有按鍵自動恢復時間顯示 onHour1 = 18; // 18:01 turn lamp on onMin1 = 01; offHour1 = 18; // 18:02 turn lamp off offMin1 = 02; count1 = 0; buffer[0] = 0x00; buffer[1] = 0x00; buffer[2] = 0x00; buffer[3] = 0x00; while(1) { while ( cputick < 1) // 如果定時器中斷沒有執行,則顯一直 scanLED(); // 掃描顯示,否則獲取時間值,再顯示 cputick = 0; /*----------以下每10ms執行一次---------------------------------------*/ timeToBuffer(); // 將時間值的7段碼輸入buffer中 offmsd(); // 關閉最高位的零顯示 blink(); // 處理秒點的閃爍, 亮50*10ms blinkset(); // 處理設置時的閃爍 keyexe(); // 判斷鍵盤按鍵,執行相應動作 keydelay(); // 延時50*10ms后清除不可按鍵標志flag1 &= ~0x80 comparetime(); // 判斷是否到了開始或結束時間 /*-------------------------------------------------------------------*/ }}/*---------------------------------------------------------------------------*//* 由中斷服務程序調用,主要是設置秒分時的變量值 *//*---------------------------------------------------------------------------*/void time (){ sec100++; if (sec100 >= 30) opto |= 0x20; // set P3.5 to beep off if (sec100==50||sec100==100) // 設置時的閃爍間隔 { showdelay = 25; flag1 |= 0x08; } if (sec100 >= 100) // 100 * 10 ms = 1 s { flag1 |= 0x05; // set bit 0, bit 2 temp = 50; sec++; if (sec >= 60) { sec = 0; flag1 |= 0x02; // set bit 1 min++; if (min >= 60) { min = 0; hour++; opto &= 0xDF; // clear bit P3.5 to beep if (hour >= 24) { hour = 0; day++; if (day > days[month-1]) { day = 1; month++; if (month > 12) month = 1; } } } } }}/*----------------------------------------------------------------------------*//* 掃描4個數碼管和4個按鍵, if key pressed key = 0-3 else key = -1 *//*----------------------------------------------------------------------------*/void scanLED(){ int i; digit = 0x08; key = -1; for( i = 0; i < 4; i++) // 4-DIGIT scanning { P1 = ~buffer[i]; // send complement[segment] P3 = ~digit & opto; // send complement[digit] pause(160); // delay a while P1 = 0xff; // off LED if ((P3 & 0x10) == 0) // if key pressed P3.4 became low key = i; // save key position to key variable digit>>=1; // next digit }}/*----------------------------------------------------------------------------*//* 把時間值轉換為數碼管編碼 *//*----------------------------------------------------------------------------*/void timeToBuffer(){ if (keyflag < 3) // 如果設置鍵按下的次數小于3,則顯示時間 { buffer[0] = convert[min%10]; buffer[1] = convert[min/10]; buffer[2] = convert[hour%10]; buffer[3] = convert[hour/10]; } else if (keyflag < 5) // 否則顯示日期 { buffer[0] = convert[day%10]; buffer[1] = convert[day/10]; buffer[2] = convert[month%10]; buffer[3] = convert[month/10]; // 屏蔽0,不顯示 if (buffer[3] == convert[0]) buffer[3] = 0x00; if (buffer[1] == convert[0]) buffer[1] = 0x00; } else if (keyflag < 7) { buffer[0] = convert[onMin1%10]; buffer[1] = convert[onMin1/10]; buffer[2] = convert[onHour1%10]; buffer[3] = convert[onHour1/10]; } else { buffer[0] = convert[offMin1%10]; buffer[1] = convert[offMin1/10]; buffer[2] = convert[offHour1%10]; buffer[3] = convert[offHour1/10]; }}/*----------------------------------------------------------------------------*//* 點亮秒針 *//*----------------------------------------------------------------------------*/void blink(){ if((flag1 & 0x04) != 0) // check bit 2 if set decrement // temp until zero { temp--; if (temp != 0) { // 顯示日期時不顯示秒閃爍 if (keyflag < 3) { buffer[0] |= 0x80; buffer[1] |= 0x80; } } else flag1 &= ~0x04; }}/*----------------------------------------------------------------------------*//* 閃爍設置位*//*----------------------------------------------------------------------------*/void blinkset(){ if((flag1 & 0x08) != 0 && key!=3) // 如果閃爍間隔到且前后兩次按鍵不一樣,就閃爍 { showdelay--; if (showdelay != 0) { if (keyflag != 0) { // 如果是在小時和月份狀態 switch (keyflag) { case 1: case 3: case 5: case 7: buffer[3] = 0x00; // 關閉顯示,實現閃爍 buffer[2] = 0x00; break; case 2: buffer[0] = 0x80; // 關閉顯示,實現閃爍 buffer[1] = 0x80; break; case 4: case 6: case 8: buffer[0] = 0x00; // 關閉顯示,實現閃爍 buffer[1] = 0x00; break; } } } else { flag1 &= ~0x08; if (showsave++ > 20) // 如果閃爍20次都沒有按鍵,自動恢復時間顯示 { keyflag = 0; showsave = 0; } } }}/*----------------------------------------------------------------------------*//* 執行鍵盤命令 *//*----------------------------------------------------------------------------*/void keyexe(){ if (key != -1) { if ((flag1 & 0x80) == 0) // within 0.5 sec after 1st press // the following execution is not allowed { flag1 |= 0x80; delay = 25; switch(key) { case (0): // key position 0 manualOnOff(); // service key 0 keyflag=0; break; case (1): // key position 1 savetimeOnOff1(); // service key 1 keyflag=0; break; case (2): // key position 2 keyflag++; // keyflag 1: set hour if (keyflag>8) // 2: set min keyflag=0; // 3: set month // 4: set day break; case (3): // key position 3 showsave = 0; switch(keyflag) { case (0): dateToBuffer(); // show date break; case (1): sethour(); break; case (2): setmin(); break; case (3): setmonth(); break; case (4): setday(); break; case (5): setonHour(); break; case (6): setonMin(); break; case (7): setoffHour(); break; case (8): setoffMin(); break; } } } }}/*----------------------------------------------------------------------------*//* 顯示日期 *//*----------------------------------------------------------------------------*/void dateToBuffer(){ buffer[0] = convert[day%10]; buffer[1] = convert[day/10]; buffer[2] = convert[month%10]; buffer[3] = convert[month/10]; if (buffer[3] == convert[0]) buffer[3] = 0x00; if (buffer[1] == convert[0]) buffer[1] = 0x00; showOnce();}/*----------------------------------------------------------------------------*//* 設置小時 *//*----------------------------------------------------------------------------*/void sethour(){ hour++; if ( hour== 24) hour = 0;}void setonHour(){ onHour1++; if (onHour1 == 24) onHour1 = 0;}void setoffHour(){ offHour1++; if (offHour1 == 24) offHour1 = 0;}/*----------------------------------------------------------------------------*//* 設置分鐘 *//*----------------------------------------------------------------------------*/void setmin(){ min++; sec = 0; if( min == 60 ) min = 0;}void setonMin(){ onMin1++; if (onMin1 == 60) onMin1 = 0;}void setoffMin(){ offMin1++; if (offMin1 == 60) offMin1 = 0;}/*----------------------------------------------------------------------------*//* 設置日 *//*----------------------------------------------------------------------------*/void setday(){ day++; if (day > days[month-1]) day = 1;}/*----------------------------------------------------------------------------*//* 設置月 *//*----------------------------------------------------------------------------*/void setmonth(){ month++; if (month > 12) month = 1;}/*----------------------------------------------------------------------------*//* 設置開始和結束時間 *//*----------------------------------------------------------------------------*/void savetimeOnOff1(){ count1++; if (count1 == 1) { onHour1 = hour; onMin1 = min; buffer[0] = 0x00; buffer[1] = 0x54; buffer[2] = 0x5C; buffer[3] = 0x78; // show "on" at led showOnce(); } else { count1 = 0; savetimeOff1(); }}/*----------------------------------------------------------------------------*//* 保存結束時間 *//*----------------------------------------------------------------------------*/void savetimeOff1(){ offHour1 = hour; offMin1 = min; buffer[0] = 0x71; buffer[1] = 0x71; buffer[2] = 0x5C; buffer[3] = 0x78; // show "off" at led showOnce(); }/*----------------------------------------------------------------------------*//* 手工點亮 on 或者 off *//*----------------------------------------------------------------------------*/void manualOnOff(){ opto= ~opto | 0x7f; // complement bit 7 which in turn activates P3.7 if ((opto & 0x80) == 0) { buffer[0] = 0; buffer[1] = 0; buffer[2] = 0x54; buffer[3] = 0x5C; // show "on" showOnce(); } else { buffer[0] = 0; buffer[1] = 0x71; buffer[2] = 0x71; buffer[3] = 0x5C; // show "off" showOnce(); }}/*----------------------------------------------------------------------------*//* 顯示數碼值 *//*----------------------------------------------------------------------------*/void showOnce(){ int i; for(i=0;i<400;i++) scanLED();}/*----------------------------------------------------------------------------*//* 鍵盤延遲 *//*----------------------------------------------------------------------------*/void keydelay(){ if ((flag1 & 0x80) !=0) { delay--; if(delay == 0) flag1 &= ~0x80; }}/*----------------------------------------------------------------------------*//* 比較是否到了設定的開始或結束時間, 設定opto *//*----------------------------------------------------------------------------*/void comparetime(){ if((flag1 & 0x01) != 0 ) { flag1 &= ~0x01; if(hour == onHour1 && min == onMin1) opto = 0x7f; // clear P3.7 turning opto on if(hour == offHour1 && min == offMin1) opto = 0xff; // set bit P3.7 turning opto off }}/*----------------------------------------------------------------------------*//* 如果小時的最高位為零,則關閉顯示零 *//*----------------------------------------------------------------------------*/void offmsd(){ if (buffer[3] == convert[0]) // if msd = '0' then put blank instead buffer[3] = 0x00;}/*----------------------------------------------------------------------------*//* 延遲 *//*----------------------------------------------------------------------------*/void pause(int j){ int i; for (i = 0; i < j; i++);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -