Al usar un PIC16F886, estoy tratando de generar interrupciones cada 100 milisegundos usando TMR0 sincronizado desde el oscilador interno, pero tengo un comportamiento realmente extraño.
Este es un circuito alimentado por batería, así que estoy usando el oscilador interno de 125KHz, seleccionado a través de:
OSCCON = 0b00010000; // select 125 KHz Int. Osc. = IRCF<2:0>=001
Luego asigno el prescaler a TMR0 y establezco un valor de precaler de 1: 2:
T0CS = 0; // TMR0 Clock Source: Internal instruction cycle clock (FOSC/4)
PSA = 0; // Prescaler is assigned to TMR0
PS2 = 0;
PS1 = 0; // > TMR0 Rate: 1:2;
PS0 = 0;
Así que ahora, de acuerdo con mis cálculos, cada 'tic' debería tomar ((1/125 000) / 4) / 2 = 1.0 × 10^-6
segundos. Si precargo el temporizador con 155, se necesitarán 100 'tics' para desbordar, generando una interrupción cada 100uS.
Mi rutina de servicio de interrupción consiste en:
if(T0IE)
{
ticks++;
if (ticks >= 999){
ticks = 0;
PORTB = ~PORTB;
}
TMR0 = 155;
return;
}
Y funciona, pero el momento no es exactamente el correcto.
Cuando lo simulo usando la SIM MPLAB, toma alrededor de 85 ms y en el hardware real parece que toma más de 100 ms.
El listado completo de códigos se puede encontrar aquí: enlace
Es muy posible que esté calculando mal algo, por lo que cualquier puntero / corrección sería muy apreciado.