/* CLOCK V1.0 89C2051 + 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 Proview32 C51 Compiler. 3 November 2542 * **** **** **** * * * * * * * * * * * * * * * * **** * * * * * * * * * * * * * * * * * * * * **** **** **** set set time manual HOUR MIN ON/OFF ON/OFF Copyright (c) 1999 W.SIRICHOTE */ #include #include unsigned char sec100,sec,min,hour,temp,opto,flag1,RunFlag; unsigned char i,digit,buffer[4],si,j,ii; int showi; unsigned char onHours,offHours; unsigned char onHour1,onMin1,offHour1,offMin1,onHour2,onMin2,offHour2,offMin2; unsigned char cputick,key,keyold,delay,count1; code unsigned char convert[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; void scanLED(); void manualOnOff(); void showOnce(); void timeToBuffer(); void blink(); void offmsd(); void keyexe(); void keydelay(); //防止键重入;在该程序中,若键长按每隔300ms执行一次keyexe() ; void comparetime(); void main() { opto = 0xff; cputick = 0; hour = 0; min = 0; sec = 0; RunFlag = 0; flag1 = 0; onHour1 = 6; /* 6:00 turn lamp on */ onMin1 = 0; offHour1 = 8; /* 8:00 turn off */ offMin1 = 0; onHour2 =0; //快捷定时时间变量 onMin2 =0; offHour2 =0; offMin2 =0; onHours = 0; //快捷开时间变量 offHours =0; //快捷关时间变量 count1 = 0; buffer[0] = ~0x40;//"- " buffer[1] = ~0x40;//"- " buffer[2] = ~0x40;//"- " buffer[3] = ~0x40;//"- " showOnce(); TH0 = 0xdc; TMOD |= 0x01; /* timer 0 run 16 bit counter */ ET0 = 1; // or IE |= 0x82; /* set bit EA and Timer0 enable */ EA = 1; TR0 = 1; //or TCON |= 0x10; /* run timer 0 */ keyold = key = 0; while(1) { while ( cputick < 1) // <10ms就一直执行scanLed(),直到10ms到执行下面的程序;这样才能保证每隔10ms执行一次下面的程序; scanLED(); cputick = 0; /*------------- the following tasks execute every 10ms ------*/ if(key) //为测新键 { keyold = key; for(i = 0;i < 10; i++) { scanLED(); //调显示延时,消键抖 } if(keyold != key) key = 0; } timeToBuffer(); blink(); offmsd(); keyexe(); keydelay(); comparetime(); RunFlag &= ~0x10; if((RunFlag & 0x0F) == 0) RunFlag &= ~0x40; /*-----------------------------------------------------------*/ } } void timer0int (void) interrupt 1 using 1 { TH0 |= 0xdc; // reload timer 0 with 0DC00H cputick++; { 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; min++; if (min >= 60) {min = 0; hour++; if (hour >= 24) {hour = 0; } } } } } } /* ****************** change constant below for other X-tal ********/ void scanLED() { ii = 1; digit = 0x08; if(key != 0) { key = 0; } else keyold = 0; for( si = 0; si < 4; si++) /* 4-DIGIT scanning */ { P3 = ~digit & opto; /* send complement[digit] */ if(P3_5 == 1 && keyold == 0 ) ; //电池供电,数码管不亮,省电 else P1 = buffer[si]; /* send complement[segment] */ for(j = 0; j <30;j++) {;} P1 = 0xff; /* off LED */ if (P3_4 == 0) /* if key pressed P3.4 became low */ { key |= ii; /* save key position to key variable */ } ii <<= 1; digit >>= 1; /* next digit */ } if(key == 3) RunFlag |= 0x80; } void timeToBuffer() { switch(key) { case 2: case 6: case 10: buffer[0] = convert[onMin1%10]; buffer[1] = convert[onMin1/10]; buffer[2] = convert[onHour1%10]; buffer[3] = convert[onHour1/10]; break; case 1: case 5: case 9: buffer[0] = convert[offMin1%10]; buffer[1] = convert[offMin1/10]; buffer[2] = convert[offHour1%10]; buffer[3] = convert[offHour1/10]; break; case 3: case 7: case 11: // buffer[0] = convert[offHours%10]; buffer[1] = convert[offHours/10]; buffer[2] = convert[onHours%10]; buffer[3] = convert[onHours/10]; break; default: buffer[0] = convert[min%10]; buffer[1] = convert[min/10]; buffer[2] = convert[hour%10]; buffer[3] = convert[hour/10]; break; } } void blink() { if((flag1 & 0x04) != 0) /* check bit 2 if set decrement temp until zero */ { temp--; if (temp != 0) // 每个隔500ms“:” { buffer[1] &= 0x7f; buffer[2] &= 0x7f; if((RunFlag & 0x40) != 0) buffer[0] &= 0x7f; } else( flag1 &= ~0x04); } } void keyexe() { if ((key != 0) || ((RunFlag & 0x80) != 0)) { if ((flag1 & 0x80) == 0) /* within 0.3 sec after 1st press the following execution is not allowed */ { flag1 |= 0x80; delay = 30; if((RunFlag & 0x80) != 0) { P3 &= 0xF0; if(P3_4 == 1) //test ,if key is free { RunFlag &= 0x7F; P3 |= 0x0F; manualOnOff(); /* service key 0 */ return; } P3 |= 0x0F; } switch(key) { case (3): /* key position 0 */ break; case (4): /* key position 2 */ min++; sec = 0; if( min == 60 ) min = 0; /* service key 2 */ break; case (8): /* key position 3 */ hour++; if ( hour== 24) hour = 0; break; case (10): /* key position 3 */ onHour1++; if(onHour1 == 24) onHour1 = 0; break; case (6): /* key position 3 */ onMin1++; if(onMin1 == 60) onMin1 = 0; break; case (9): /* key position 3 */ offHour1++; if(offHour1 == 24) offHour1 = 0; break; case (5): /* key position 3 */ offMin1++; if(offMin1 == 60) offMin1 = 0; break; case (7): /* key position 3 */ offHours++; if(offHours == 24) offHours = 0; break; case (11): /* key position 3 */ onHours++; if(onHours == 24) onHours = 0; break; } } } } void manualOnOff() { opto= ~opto | 0x7f; // complement bit 7 which in turn activates P3.7 if (((opto & 0x80) == 0) && ((RunFlag & 0x20) == 0 )) { if(offHours == 0) opto= ~opto | 0x7f; //立即关闭外设 RunFlag |=0x20; buffer[0] = 0xff; // buffer[1] = 0xc8; //n buffer[2] = 0xc1; //u buffer[3] = 0x88; //r RunFlag |= 0x40; // 第四个数码管“.”,监控标志 RunFlag |= 0x0f; if((onHour1 == offHour1) && (onMin1 == offMin1)) RunFlag &= ~0x0c; if(onHours == offHours) RunFlag &= ~0x03; if(onHours == 0) RunFlag &= ~0x02; if(offHours==0 ) RunFlag &= ~0x01; showOnce(); offHour2 = hour + offHours; offMin2 = min; if(offHour2 > 24) offHour2 = 0; onHour2 = hour + onHours; onMin2=min; if(onHour2 > 24) onHour2 = 0; } else { if ((opto & 0x80) == 0) opto= ~opto | 0x7f; buffer[0] = ~0xF3; //P buffer[1] = 0xC0; //O buffer[2] = ~0x87; //T buffer[3] = 0x92; //S showOnce(); RunFlag &= ~0x40; //取消监控 RunFlag &= ~0x20; } } void showOnce() { for(showi=0;showi<1000;showi++) { RunFlag &= ~0x10; scanLED(); } } void keydelay() { if ((flag1 & 0x80) !=0) { delay--; if(delay == 0) flag1 &= ~0x80; } } void comparetime() { if((flag1 & 0x01) != 0 ) // 1S到 { flag1 &= ~0x01; if((onHour1 == offHour1 )&&( onMin1 == offMin1)) ; //1路定时开时间==1路定时关时间,不执行任何动作,保持之前的状态; else { if((RunFlag & 0x08) != 0) { if((hour == onHour1) && (min == onMin1)) { opto = 0x7f; /* clear P3.7 turning opto on */ RunFlag &= ~0x08; buffer[0] = 0xff; buffer[1] = 0xff; buffer[2] = 0xc8; // n buffer[3] = 0xA3; // O buffer[3] &= 0x7f; // spk showOnce(); showOnce(); showOnce(); } } if((RunFlag & 0x04) != 0) { if((hour == offHour1) && (min == offMin1)) { opto = 0xff; /* set bit P3.7 turning opto off */ RunFlag &= ~0x04; buffer[0] = 0xff; buffer[1] = 0x8e; //f buffer[2] = 0x8e; //f buffer[3] = 0xA3; // o showOnce(); } } } if( onHours == offHours ) ; // 快捷定时开时间==快捷定时关时间,不执行任何动作,保持之前的状态; else { if(onHours == 0); else if((RunFlag & 0x02) != 0) { if((hour == onHour2) && (min == onMin2)) { opto = 0x7f; // clear P3.7 turning opto on RunFlag &= ~0x02; buffer[0] = 0xff; buffer[1] = 0xff; buffer[2] = 0xc8; //n buffer[3] = 0xA3; //o showOnce(); } } if(offHours == 0) ; else if((RunFlag & 0x01) != 0) { if((hour == offHour2) && (min == offMin2)) { opto = 0xff; // set bit P3.7 turning opto off RunFlag &= ~0x01; RunFlag &=~0x40; //熄第四个数码管“.” 取消监控 buffer[0] = 0xff; buffer[1] = 0x8e; //f buffer[2] = 0x8e; //f buffer[3] = 0xA3; //o showOnce(); } } } } } void offmsd() { if (buffer[3] == 0xc0) /* if msd = '0' then put blank instead */ buffer[3] = 0xff; }