Dos posibilidades:
- Como Dave indicó que podría tratarse de un problema de reinversión, su naturaleza regular significa que probablemente sea eso o alguna frecuencia de latido entre la tasa de interrupción y la tasa de bucle del código principal.
- El valor está cambiando cuando no esperas que lo haga.
Un problema de reinversión puede estar en el valor principal o en algún cálculo que esté realizando en él.
El segundo problema es si tienes algo como esto:
// if you haven't marked this as volatile then you're lucky it ever worked
volatile uint16_t period_u16;
onInterrupt () {
period_u16 = new_value;
}
main() {
while(true) {
uint16_t my_number = doSomeCalculation(period_u16);
// Invalid results if interrupt triggers here
result = my_number - period_u16;
... some other code ...
}
}
es decir, Realiza algunos cálculos basados en period_u16 y luego hace referencia a period_u16 por segunda vez, asumiendo que no ha cambiado entre ellos. Si la interrupción se dispara en el lugar equivocado, entonces period_u16 habrá cambiado entre esas líneas y los resultados serán incorrectos.
Para evitar esto, deshabilite las interrupciones durante la parte sensible o haga una copia local. Si la interrupción está configurando dos valores diferentes (o una sola variable que es más grande que el ancho del procesador), entonces tiene que hacer ambos, deshabilitar interrupciones, hacer una copia y luego volver a habilitarlos. Si no te arriesgas a obtener resultados inconsistentes.
Si el valor calculado es necesario dentro de la interrupción la próxima vez que se dispare, deberá mantener las interrupciones desactivadas hasta que se realicen los cálculos.