/* xtimer.c 4-channel timer Timer4 Timer3 Timer2 Timer1 __ __ __ __ __ __ __ __ |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| 0-99hr 0-99hr 0-99min 0-99min key4 Key3 Key2 Key1 Copyright (C) 2003,2004 W.SIRICHOTE */ #include <8051io.h> #include <8051reg.h> #include <8051bit.h> extern unsigned register char cputick; register char command; register char timer1,timer2,timer3,timer4,timer5,load_timer5,load_timer6,index5,timer6,index6; register unsigned int timer1_clk,timer2_clk,timer3_clk,timer4_clk; register unsigned char timer7; register unsigned char blink1,blink2,blink3,blink4,one_sec; register unsigned char index1,index2,index3,index4; unsigned register char flag1,flag2,key,ACCU,temp,buzzer1,buzzer2; /* above must be defined as register for tiny model */ unsigned register char i,column,buffer[7],t[5]; register char delay,count1; register unsigned int count; unsigned char busy_pattern[4]= {1,20,0,100}; unsigned char busy_pattern2[4]= {1,20,0,20}; char convert[10] = {0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b}; /* 0 1 2 3 4 5 6 7 8 9 */ /* 7-segment pattern converting array a __ register data f |__| b D7 D6 D5 D4 D3 D2 D1 D0 e |__| c.DP DP a b c d e f g d */ unsigned register int Time,temp16,auto; register int PGM; /* signed PGM 0-499 */ char preset_timer1[] = {-1,0,3,5,10,15,20,25,30}; char preset_timer2[] = {-1,0,3,5,10,15,20,25,30}; char preset_timer3[] = {-1,0,1,2,3,5,8,9,10,11,12,13,14}; char preset_timer4[] = {-1,0,1,2,3,10,12,14}; #define CLK P1.7 #define DIN P1.6 #define LOAD P1.5 #define output1 P1.4 #define output2 P1.3 #define output3 P1.2 #define output4 P1.1 #define buzzer P3.0 #define xbuzzer P3.1 #define on 1 #define off 0 /* mask byte of flag1 for bit testing */ #define mode 0x40 /* swap number entry mode */ #define disabling_key 0x80 /* disable consecutive key pressing */ main() { // serinit(9600); flag1 = flag2 = 0; P1 = P3 = 0xFF; // printf("\n4-channel timer"); timer1= timer2=timer3=timer4 =-1; timer1_clk=timer2_clk=timer3_clk=timer4_clk=0; index1=index2=index3=index4=index5=index6=0; load_timer5 = load_timer6=0; buzzer1=buzzer2=0; timer7 = 0; while(1) { while(!cputick) // run following tasks every 10ms ; cputick = 0; set_timer(); run_timer(); key_release(); updatedisplay(); ring1(); ring2(); //command = chkchr(); // test set timer via terminal //set_timer2(); } } // timer functions run every one second run_timer() { if(++one_sec>=100) { one_sec = 0; run_timer1(); run_timer2(); run_timer3(); run_timer4(); shutdown(); // run shutdown checking every second } } run_timer1() { if(timer1 != -1) { if(timer1 != 0) { timer7 = 0; // reset timeout buzzer1 = off; flag1 |= 0x02; setbit(output1) if(++timer1_clk >= 60) // timer1 is one min based! { timer1_clk = 0; timer1--; } } else // timer1 == 0 then fire output { clrbit(output1) // fire output1 // putch('1'); buzzer1 = on; flag1 &= ~0x02; flag2 &= ~0x01; } } else { flag1 &= ~0x02; // no blink when timer1 == -1 flag2 &= ~0x01; buzzer1 = off; } } run_timer2() { if(timer2 != -1) { if(timer2 != 0) { timer7 = 0; buzzer2 = off; flag1 |= 0x08; setbit(output2) if(++timer2_clk >= 60) //timer2 is one min based! { timer2_clk = 0; timer2--; } } else // timer2 == 0 then fire output { clrbit(output2) // fire output1 // putch('2'); buzzer2 = on; flag1 &= ~0x08; flag2 &= ~0x02; } } else { flag1 &= ~0x08; // no blink when timer1 == -1 flag2 &= ~0x02; buzzer2 = off; } } run_timer3() { if(timer3 != -1) { if(timer3 != 0) { timer7 = 0; flag1 |= 0x10; setbit(output3) if(++timer3_clk >= 3600) // timer3 is one hour based! { timer3_clk = 0; timer3--; } } else // timer1 == 0 then fire output { clrbit(output3) // fire output1 // putch('3'); flag1 &= ~0x10; flag2 &= ~0x04; } } else { flag1 &= ~0x10; // no blink when timer1 == -1 flag2 &= ~0x04; } } run_timer4() { if(timer4 != -1) { if(timer4 != 0) { timer7 = 0; flag1 |= 0x20; setbit(output4) if(++timer4_clk >= 3600) // timer4 is one hour based! { timer4_clk = 0; timer4--; } } else // timer4 == 0 then fire output { clrbit(output4) // fire output1 // putch('4'); flag1 &= ~0x20; flag2 &= ~0x08; } } else { flag1 &= ~0x20; // no blink when timer1 == -1 flag2 &= ~0x08; } } // reload preset time value from preset array for each key pressed set_timer() { if((flag1&1) == 0) // enter only when keys have been released { if((P3&0x04) == 0) { flag1 |= 1; if(index1>=9) index1 =0; timer1= preset_timer1[index1++]; } if((P3&0x08) == 0) { flag1 |= 1; if(index2>=9) index2 =0; timer2= preset_timer2[index2++]; } if((P3&0x10) == 0) { flag1 |= 1; if(index3>=13) index3 =0; timer3= preset_timer3[index3++]; } if((P3&0x20) == 0) { flag1 |= 1; if(index4>=8) index4 =0; timer4= preset_timer4[index4++]; } } } key_release() { if((P3&0x3c) == 0x3c) flag1 &= ~1; } set_timer2() { if(command == '2') { // flag1 |= 1; if(index2>=8) index2 =0; timer2= preset_timer2[index2++]; } } blink_timer1() { ++blink1; if(blink1 >= 20) flag2 &= ~0x01; if( blink1 >= 100) { flag2 |= 0x01; blink1 = 0; } } blink_timer2() { ++blink2; if(blink2 >= 20) flag2 &= ~0x02; if( blink2 >= 100) { flag2 |= 0x02; blink2 = 0; } } blink_timer3() { ++blink3; if(blink3 >= 20) flag2 &= ~0x04; if( blink3 >= 200) { flag2 |= 0x04; blink3 = 0; } } blink_timer4() { ++blink4; if(blink4 >= 20) flag2 &= ~0x08; if( blink4 >= 200) { flag2 |= 0x08; blink4 = 0; } } blink() { if(flag1&0x02) blink_timer1(); if(flag1&0x08) blink_timer2(); if(flag1&0x10) blink_timer3(); if(flag1&0x20) blink_timer4(); } moveTimetoBuffer() /* convert 8-bit binary to 7-segment 8-digit */ { if(timer4 != -1) { buffer[7] = convert[timer4/10]; buffer[6] = convert[timer4%10]; if(flag2&0x08) buffer[6] |= 0x80; else buffer[6] &= ~0x80; } else { buffer[7]=buffer[6]= 0x01; } if(timer3 != -1) { buffer[5] = convert[timer3/10]; buffer[4] = convert[timer3%10]; if(flag2&0x04) buffer[4] |= 0x80; else buffer[4] &= ~0x80; } else { buffer[5]=buffer[4]= 0x01; } if(timer2 != -1) { buffer[3] = convert[timer2/10]; buffer[2] = convert[timer2%10]; if(flag2&0x02) buffer[2] |= 0x80; else buffer[2] &= ~0x80; } else { buffer[3] = 0x01; // -- buffer[2] = 0x01; } if(timer1 != -1) { buffer[1] = convert[timer1/10]; buffer[0] = convert[timer1%10]; if(flag2&0x01) buffer[0] |= 0x80; else buffer[0] &= ~0x80; } else { buffer[1] = 0x01; // -- buffer[0] = 0x01; } offmsd(); // turn off msd, e.g. 09 to 9, say } offmsd() // turn msd off { if (buffer[1] == 0x7e) buffer[1] = 0x00; if (buffer[3] == 0x7e) buffer[3] = 0x00; if (buffer[5] == 0x7e) buffer[5] = 0x00; if (buffer[7] == 0x7e) buffer[7] = 0x00; } enable_buzzer(char i){ if (i) clrbit(buzzer) else setbit(buzzer) } enable_buzzer2(char i){ if (i) clrbit(xbuzzer) else setbit(xbuzzer) } counting_down2(char j){ timer5--; if (timer5 == 0){ index5+=2; if (index5 == j) index5 = 0; load_timer5 = 0; } } counting_down3(char j){ timer6--; if (timer6 == 0){ index6+=2; if (index6 == j) index6 = 0; load_timer6 = 0; } } ring1() { if (buzzer1){ if(load_timer5 == 0){ enable_buzzer(busy_pattern[index5]); timer5 = busy_pattern[index5+1]; load_timer5 = 1; } counting_down2(4); } else setbit(buzzer) } ring2() { if (buzzer2){ if(load_timer6 == 0){ enable_buzzer2(busy_pattern2[index6]); timer6 = busy_pattern2[index6+1]; load_timer6 = 1; } counting_down3(4); } else setbit(xbuzzer) } shutdown() { if((timer1&timer2&timer3&timer4)== -1) { timer7++; if(timer7 >= 10) // 10 seconds timeout { shift(0x0c00); // enable shutdown mode asm" CLR IE.7"; asm" MOV PCON,#2"; // enter power down mode } } } updatedisplay() { moveTimetoBuffer(); blink(); update7219(); } update7219() { init7219(); /* reinitialize everytime entering to this function */ temp16 = buffer[0]; shift(0x0100|temp16); temp16 = buffer[1]; shift(0x0200|temp16); temp16 = buffer[2]; shift(0x0300|temp16); temp16 = buffer[3]; shift(0x0400|temp16); temp16 = buffer[4]; shift(0x0500|temp16); temp16 = buffer[5]; shift(0x0600|temp16); temp16 = buffer[6]; shift(0x0700|temp16); temp16 = buffer[7]; shift(0x0800|temp16); } shift(int i) /* shift 16-bit packet to MAX7219 */ { temp16 = i; /* transfer i to temp16 */ asm{ PUSH 2 PUSH A PUSH PSW CLR C CLR CLK // P1.7 is CLK CLR LOAD // P1.5 is LOAD MOV R2,#8 MOV A,temp16+1 SHIFT1 RLC A MOV DIN,C // P1.6 is DIN SETB CLK NOP CLR CLK DJNZ R2,SHIFT1 MOV R2,#8 MOV A,temp16 SHIFT2 RLC A MOV DIN,C SETB CLK NOP CLR CLK DJNZ R2,SHIFT2 SETB LOAD NOP CLR LOAD POP PSW POP A POP 2 } } init7219() { shift(0x0a05); /* intensity (middle) */ shift(0x0b07); /* scan limit 8 digits */ shift(0x0900); /* no decode mode */ shift(0x0c01); /* normal operation */ shift(0x0f00); /* disable test mode */ }