??? 02/04/09 14:25 Read: times |
#162049 - Software Clock is 3 Sec Slow per minute |
Hi,
This is my first hardware + software project with AT89C51 24PC. This is a simple timer project. Entire thing works very well, but the timing is a bit slow. I have observed that for every minute, it turns on the relay 3 sec later. e.g. For 5 min, it turns relay after 5 min 15 sec. I have tried every aspect of debugging but no luck. I am using 12Mhz crystal printed on it and now I doubt it not really 12Mhz Any help is appreciated. ---------- Here is the source code ----------- #include <AT89X51.h> // variables that keep track of the time. Note the "volatile" keyword // should be used by all variables that are written by the interrupt // service routines and may be read by the main program. volatile int total_sec; volatile int total_sec_fraction; volatile int toggle_flag ; int input_value ; void timer0_isr(void) interrupt 1; void delay_time(void); void call_buzzer(int); void find_input(void); void main() { int i = 0 ; total_sec = total_sec_fraction = toggle_flag = 0 ; IE = 0; // turn off all interrupts total_sec = total_sec_fraction = 0 ; // zero total seconds TR0 = 0; // make sure timer 0 is stopped TF0 = 0; // clear the overflow flag TMOD =0x01 ; // set Timer 0 mode 1 TL0 = 0xAF ; TH0 = 0x3C ; // Set the time to count for 50 milli seconds. // Load counter to count for 50,000 counts // Thus 0xFFFF - ( 50,000 decimal) = 0x3CAF ; TR0 = 1; // start the timing IP = 0; // set interrupt priorities (all low) IE = 0x82; // enable timer0 interrupt ET0 = 1 ; // Activate timer0 P2 = 0x01 ; // Turn off buzzer, turn off relay, turn off LED P1 = 0xFF ; P2_0 = 0 ; // Turn on LED indicating that input reading will be done. while(P1_7); // Wait until the start button is pressed. call_buzzer(1); find_input(); TR0 = 0x0; // Stop timer to clear the count variables so that any sec used for buzzer dont get counted total_sec_fraction = total_sec = 0; // Reset the timing here. Error will be max 0.05seconds. TR0 = 0x1; // Start timer P2_7 = 1; // Turn on relay while(total_sec <= (input_value*60)) { P2_0 = 1 ; // Flash LED for ( i = 0 ; (total_sec <= (input_value*60)) && i < 15000 ; i++); P2_0 = 0 ; for ( i = 0 ; (total_sec <= (input_value*60)) && i < 15000 ; i++); } P2 = 0x0 ; // Turn off relay call_buzzer(2); P2 = 0x01 ; // Turn off entire port. while(1); } void timer0_isr(void) interrupt 1 { TR0 = 0x00 ; TL0 = 0xAF ; TH0 = 0x3C ; if( total_sec_fraction >= 20) { total_sec_fraction = 0 ; total_sec++ ; } else total_sec_fraction++ ; TR0 = 0x01 ; } void find_input(void) { if ( P1_0 == 0 ) input_value = 1 ; if ( P1_1 == 0 ) input_value = 2 ; if ( P1_2 == 0 ) input_value = 3 ; if ( P1_3 == 0 ) input_value = 4 ; if ( P1_4 == 0 ) input_value = 5 ; if ( P1_5 == 0 ) input_value = 6 ; if ( P1_6 == 0 ) input_value = 7 ; } void call_buzzer( int i) { int sec_count ; int temp ; sec_count = total_sec ; if( i == 1) { temp = 2 ; } if( i == 2) { temp = 4 ; } while( (total_sec - sec_count) <= temp) P2_1 = 1 ; P2_1 = 0; } |
Topic | Author | Date |
Software Clock is 3 Sec Slow per minute | 01/01/70 00:00 | |
How long does your ISR take? | 01/01/70 00:00 | |
Software clock is 3 sec slow | 01/01/70 00:00 | |
Don't assume - calculate! | 01/01/70 00:00 | |
You should use an auto-reload timer | 01/01/70 00:00 | |
Incorrect ISR - 21 ticks/second | 01/01/70 00:00 | |
Thank you ! Problem Solved | 01/01/70 00:00 | |
Solved? Check closely![]() | 01/01/70 00:00 |