/* xtimer1.c sdcc version 4-channel timer Timer4 Timer3 Timer2 Timer1 __ __ __ __ __ __ __ __ |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| 0-99min 0-99hr 0-99min 0-99min key4 Key3 Key2 Key1 The xtimer1.c is firmware for xtimer board. The hardware schematic and details can get from http://www.kmitl.ac.th/~kswichit/xtimer/xtimer1.html Copyright(c) 2003 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include char cputick; char command; char timer1,timer2,timer3,timer4,timer5,load_timer5,load_timer6,index5,timer6,index6; unsigned int timer1_clk,timer2_clk,timer3_clk,timer4_clk; unsigned char timer7; unsigned char blink1,blink2,blink3,blink4,one_sec; unsigned char index1,index2,index3,index4; unsigned char flag1,flag2,key,ACCU,temp,buzzer1,buzzer2; unsigned char i,column,buffer[7],t[5]; char delay,count1; unsigned int count; unsigned char code busy_pattern[4]= {1,20,0,100}; unsigned char code busy_pattern2[4]= {1,20,0,20}; char code 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 int Time,temp16; //int PGM; /* signed PGM 0-499 */ char code preset_timer1[] = {-1,0,3,5,10,15,20,25,30,0}; char code preset_timer2[] = {-1,0,3,5,10,15,20,25,30,0}; char code preset_timer3[] = {-1,0,1,2,3,5,8,9,10,11,12,13,14,0}; char code preset_timer4[] = {-1,0,3,5,10,15,20,25,30,0}; #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 key1 P3_2 #define key2 P3_3 #define key3 P3_4 #define key4 P3_5 #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 */ // prototype declaration void blink_timer1(); void blink_timer2(); void blink_timer3(); void blink_timer4(); // shift 16-bit data to 7219 serially shift(int n) { char j; CLK = LOAD = 0; for(j=0; j<16; j++) { DIN = n&0x8000; // send data to 7219 CLK =1; // pulse CLK CLK =0; n<<=1; // shift left one bit } LOAD =1; // pulse LOAD LOAD =0; } 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 */ } 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); } void blink() { if(flag1&0x02) blink_timer1(); if(flag1&0x08) blink_timer2(); if(flag1&0x10) blink_timer3(); if(flag1&0x20) blink_timer4(); } 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; } void 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 } updatedisplay() { moveTimetoBuffer(); blink(); update7219(); } shutdown() { if((timer1&timer2&timer3&timer4)== -1) { timer7++; if(timer7 >= 10) // 10 seconds timeout { shift(0x0c00); // enable shutdown mode EA = 0; // disable interrupt PCON = 2; // enter power down mode now } } } // timer functions run every one second void run_timer1(void) { if(timer1 != -1) { if(timer1 != 0) { timer7 = 0; // reset timeout buzzer1 = off; flag1 |= 0x02; output1=1; if(++timer1_clk >= 60) // timer1 is one min based! { timer1_clk = 0; timer1--; } } else // timer1 == 0 then fire output { output1=0; // fire output1 buzzer1 = on; flag1 &= ~0x02; flag2 &= ~0x01; } } else { flag1 &= ~0x02; // no blink when timer1 == -1 flag2 &= ~0x01; buzzer1 = off; } } void run_timer2() { if(timer2 != -1) { if(timer2 != 0) { timer7 = 0; buzzer2 = off; flag1 |= 0x08; output2=1; if(++timer2_clk >= 60) //timer2 is one min based! { timer2_clk = 0; timer2--; } } else // timer2 == 0 then fire output { output2=0; // fire output1 // putch('2'); buzzer2 = on; flag1 &= ~0x08; flag2 &= ~0x02; } } else { flag1 &= ~0x08; // no blink when timer1 == -1 flag2 &= ~0x02; buzzer2 = off; } } void run_timer3() { if(timer3 != -1) { if(timer3 != 0) { timer7 = 0; flag1 |= 0x10; output3=1; if(++timer3_clk >= 3600) // timer3 is one hour based! { timer3_clk = 0; timer3--; } } else // timer1 == 0 then fire output { output3=0; // fire output1 // putch('3'); flag1 &= ~0x10; flag2 &= ~0x04; } } else { flag1 &= ~0x10; // no blink when timer1 == -1 flag2 &= ~0x04; } } // I modified timer4 for sdcc testing and for my wife mixer delay off function! void run_timer4() { if(timer4 != -1) { if(timer4 != 0) { timer7 = 0; flag1 |= 0x20; output4=0; // turn on when run! if(++timer4_clk >= 60) // timer4 is one min based! { timer4_clk = 0; timer4--; } } else // timer4 == 0 then fire output { output4=1; // turn off when timeover! flag1 &= ~0x20; flag2 &= ~0x08; } } else { flag1 &= ~0x20; // no blink when timer1 == -1 flag2 &= ~0x08; output4= 1; // turn output off } } run_timer() { if(++one_sec>=100) { one_sec = 0; run_timer1(); run_timer2(); run_timer3(); run_timer4(); shutdown(); // run shutdown checking every second } } // reload preset time value from preset array for each key pressed void set_timer() { if((flag1&1) == 0) // enter only when keys have been released { if(!key1) // if key 1 has been pressed { flag1 |= 1; if(index1>=10) index1 =0; timer1= preset_timer1[index1++]; } if(!key2) { flag1 |= 1; if(index2>=10) index2 =0; timer2= preset_timer2[index2++]; } if(!key3) { flag1 |= 1; if(index3>=14) index3 =0; timer3= preset_timer3[index3++]; } if(!key4) { flag1 |= 1; if(index4>=10) index4 =0; timer4= preset_timer4[index4++]; } } } void key_release() { if((P3&0x3c) == 0x3c) flag1 &= ~1; } void blink_timer1() { ++blink1; if(blink1 >= 20) flag2 &= ~0x01; if( blink1 >= 100) { flag2 |= 0x01; blink1 = 0; } } void blink_timer2() { ++blink2; if(blink2 >= 20) flag2 &= ~0x02; if( blink2 >= 100) { flag2 |= 0x02; blink2 = 0; } } void blink_timer3() { ++blink3; if(blink3 >= 20) flag2 &= ~0x04; if( blink3 >= 200) { flag2 |= 0x04; blink3 = 0; } } void blink_timer4() { ++blink4; if(blink4 >= 20) flag2 &= ~0x08; if( blink4 >= 100) // <-- change for minute based blinking! { flag2 |= 0x08; blink4 = 0; } } void enable_buzzer(char i){ if (i) buzzer=0; else buzzer=1; } void enable_buzzer2(char i){ if (i) xbuzzer=0; else xbuzzer=1; } void counting_down2(char j){ timer5--; if (timer5 == 0){ index5+=2; if (index5 == j) index5 = 0; load_timer5 = 0; } } void counting_down3(char j){ timer6--; if (timer6 == 0){ index6+=2; if (index6 == j) index6 = 0; load_timer6 = 0; } } void ring1() { if (buzzer1){ if(load_timer5 == 0){ enable_buzzer(busy_pattern[index5]); timer5 = busy_pattern[index5+1]; load_timer5 = 1; } counting_down2(4); } else buzzer=1; } void ring2() { if (buzzer2){ if(load_timer6 == 0){ enable_buzzer2(busy_pattern2[index6]); timer6 = busy_pattern2[index6+1]; load_timer6 = 1; } counting_down3(4); } else xbuzzer=1; } void timer_isr(void) interrupt 1 using 1 { TH0 |= 0xdc; cputick++; } main() { flag1 = flag2 = 0; P1 = P3 = 0xFF; TMOD = 0x01; // timer0 mode 1 EA = ET0 = TR0 = 1; // enable timer0 interrupt, start 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();; } }