/* originally http://www.kmitl.ac.th:80/~kswichit/clock/clock.htm, via wayback cache CLOCK V1.0 89C2051 @11.0592MHz + 4-digit 7-SEG led + 4-key switch Simple Digital Clock demostrates scanning LED and key switch. The clock has 1-bit output port P3.7 for driving AC load through MOC3040+triac. The source program was modified for sdcc for 8051 January 27, 2004 * **** **** **** * * * * * * * * * * * * * * * * **** * * * * * * * * * * * * * * * * * * * * **** **** **** set set time manual HOUR MIN ON/OFF ON/OFF Copyright(C) 2004 WICHIT SIRICHOTE, kswichit@kmitl.ac.th This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ #include #include unsigned char sec100,sec,sec5,min,hour,flag1,command,temp,opto; unsigned char i,digit,buffer[4],onHour1,onMin1,offHour1,offMin1; char cputick,key,delay,count1; char code convert[10] = {0x3F,0x0c,0x76,0x5e,0x4d,0x5b,0x7b,0x0e,0x7f,0x5f}; void pause(int); void scanLED(); void manualOnOff(); void savetimeOnOff1(); void setmin(); void sethour(); void showOnce(); void savetimeOff1(); void time(); void timeToBuffer(); void blink(); void offmsd(); void keyexe(); void keydelay(); void comparetime(); void timer_isr (void) interrupt 1 using 1 { TH0 |= 0xdc; // reload timer 0 with 0DC00H cputick++; time(); // update realtime clock } void main() { EA = 1; ET0 = 1; // or IE |= 0x82; /* set bit EA and Timer0 enable */ TMOD |= 0x01; /* timer 0 run 16 bit counter */ TR0 = 1; //or TCON |= 0x10; /* run timer 0 */ opto = 0xff; cputick = 0; hour = 18; min = 0; sec = 0; key = -1; flag1 = 0; onHour1 = 18; /* 18:30 turn lamp on */ onMin1 = 01; offHour1 = 18; /* 21:30 turn off */ offMin1 = 02; count1 = 0; buffer[0] = 0x40; buffer[1] = 0x40; buffer[2] = 0x40; buffer[3] = 0x40; while(1) { while ( cputick < 1) scanLED(); cputick = 0; /*------------- the following tasks execute every 10ms ------*/ // time(); timeToBuffer(); blink(); offmsd(); keyexe(); keydelay(); comparetime(); /*-----------------------------------------------------------*/ } } /* ****************** change constant below for another X-tal ********/ void time () /* update real-time clock */ { sec100++; if (sec100 >= 100) /* 100 * 10 ms = 1 s */ {sec100 = 0; 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++; if (hour >= 24) {hour = 0; } } } } } void scanLED() /* scan 4-digit LED and 4-key switch, if key pressed key = 0-3 else key = -1 */ { int i; digit = 0x08; key = -1; for( i = 0; i < 4; i++) /* 4-DIGIT scanning */ { P3 = ~digit & opto; /* send complement[digit] */ P1 = ~buffer[i]; /* send complement[segment] */ pause(5); /* 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() { buffer[0] = convert[min%10]; buffer[1] = convert[min/10]; buffer[2] = convert[hour%10]; buffer[3] = convert[hour/10]; } void blink() { if((flag1 & 0x04) != 0) /* check bit 2 if set decrement temp until zero */ {temp--; if (temp != 0) { buffer[1] |= 0x80; buffer[2] |= 0x80; } else( flag1 &= ~0x04); } } 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 = 50; switch(key){ case (0): /* key position 0 */ manualOnOff(); /* service key 0 */ break; case (1): /* key position 1 */ savetimeOnOff1(); /* service key 1 */ break; case (2): /* key position 2 */ setmin(); /* service key 2 */ break; case (3): /* key position 3 */ sethour(); } } } } void sethour() { hour++; if ( hour== 24) hour = 0; } void setmin() { min++; sec = 0; if( min == 60 ) min = 0; } void savetimeOnOff1() { count1++; if (count1 == 1) { onHour1 = hour; onMin1 = min; buffer[0] = 0x00; buffer[1] = 0x68; buffer[2] = 0x78; buffer[3] = 0x71; showOnce(); } else { count1 = 0; savetimeOff1(); } } void savetimeOff1() { offHour1 = hour; offMin1 = min; buffer[0] = 0x63; buffer[1] = 0x63; buffer[2] = 0x78; buffer[3] = 0x71; showOnce(); } 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] = 0x68; buffer[3] = 0x78; showOnce(); } else { buffer[0] = 0; buffer[1] = 0x63; buffer[2] = 0x63; buffer[3] = 0x78; showOnce(); } } void showOnce() { int i; for(i=0;i<2000;i++) scanLED(); } void keydelay() { if ((flag1 & 0x80) !=0) { delay--; if(delay == 0) flag1 &= ~0x80; } } 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] == 0x3f) /* if msd = '0' then put blank unstead */ buffer[3] = 0x00; } void pause(int j) { int i; for (i = 0; i < j; i++) ; }