??? 09/15/04 07:56 Read: times |
#77421 - Priority interrupt problem with DS5240 |
I have written an application that runs on a DS5250/DS5240 based board, a 8052 derivative from Dallas-Maxim, this application has to manage a keybord and a simple protocol to dialogue with an host
I enable two interrupts: interrupt from Timer 0 and interrupt from Serial 0, the first one has a low priority, the second one an high priority. Interrupt from timer 0 manages a set of virtual timers, interrupt from Serial 0 manages the reception and trasmission using circular buffer. Sometimes (let’s say after two-three hours that the program runs) happens that interrupt from Timer 0 seems to “freeze” (virtual timer does not work anymore), the rest of the program continue to work well. I was able to break the program in this condition ( I use a Developer’s Kit to debug) and it appears the LIP bits in the STATUS register is always set. This means that a low priority interrupt is active at this point in time. This will prevent any more low priority interrupts from being acknowledged. The only thing that I can do at this point is to turn off and then to turn on the device. The only cause I can guess is that Timer 0 interrupt sometimes is terminated by a RET instead of a RETI, but I cant understand how. The “freeze” disappears if I program the two interrupt with the same priority level (level 0). The interrupt routines are: //Timer 0 Interrupt manages a virtual timer table void timer0 (void) interrupt 1 using 3 { data unsigned char data *ptabella; data unsigned char i; TR0 = 0; ptabella = (unsigned char data*) &timer10ms; for( i = 0; i < LENTIMER10MS; i++ ) { if( (*ptabella) !=0 ) (*ptabella)--; ptabella++; } if( --prescaler_50ms == 0 ) { prescaler_50ms = VALUE_50MS; ptabella = (unsigned char data*)&timer50ms; for( i = 0; i < LENTIMER50MS; i++ ) { if( (*ptabella) !=0 ) (*ptabella)--; ptabella++; } if( --prescaler_1sec == 0 ) { prescaler_1sec = VALUE_1SEC; ptabella =(unsigned char data*)&timer1sec; for( i = 0; i < LENTIMER1SEC; i++ ) { if( (*ptabella) !=0 ) { (*ptabella) --; } ptabella++; } } } TL0 = (unsigned char)LO_T0; TH0 = (unsigned char)HI_T0; TR0 = 1; } void com_isr (void) interrupt 4 using 2 { if (RI != 0) /* Received data interrupt */ { RI = 0; //inserte a character in a circular buffer if( r_count < RBUF_SIZE ) { ACC = SBUF0; //check the parity if( RB8 == P ) { r_count++; rbuf[ r_in++ ] = SBUF0; if( r_in > RBUF_SIZE-1 ) r_in = 0; } } } if (TI != 0) // Transmitted data interrupt { TI = 0; //get a character from circular buffer and trasmit it if( t_count != 0 ) { ACC = tbuf[ t_out ]; //set the parity TB8 = P; SBUF0 = tbuf[ t_out++ ]; t_count--; if( t_out > TBUF_SIZE-1 ) t_out = 0; } else t_disabled = 1; } } |