Millis versus centis en la plataforma AVR

6

Estoy construyendo un dispositivo en la plataforma AVR. El dispositivo necesitará cierta información de tiempo, así que estaba pensando en volver a implementar la funcionalidad similar a Arduino millis (aunque no exactamente como este ). Sin embargo, después de hacer algunos respaldos de los cálculos del sobre (en parte basados en esta publicación ), me empezó a parecer que millis consume al menos el 5% del tiempo de CPU en un procesador de 20Mhz, y proporcionalmente más que eso en un 16Mhz uno:

  • Cada milisegundo, el temporizador (timer0) se desborda, activa una interrupción, que se incrementa en millis
  • Un ISR debe tomar 26 relojes para la rutina pre / post ISR (5 PUSH + POP más CLR , IN y RETI
  • El propio ISR debería tomar aproximadamente 21 relojes (cargar el valor de 32 bits, incrementarlo y almacenarlo nuevamente en SRAM)
  • Esto produce casi 50 relojes, o 50 microsegundos cada milisegundo.
  • De hecho, la función ISR de Arduino es más lenta que eso (como lo revela esta publicación ) porque es realmente cuidadoso en mantener los milis lo más precisos posible, lo que requiere más ciclos de CPU

No necesito millis de precisión, por lo que estoy considerando implementar centis o incluso decis para guardar los ciclos del procesador para otras cosas. ¿Es esto irrazonable? ¿Están mal mis cálculos? Parecería una elección de diseño extraña, ¿o me estoy perdiendo algo?

    
pregunta angelatlarge

1 respuesta

1

50 relojes no son 50 us cuando se ejecuta a 16 MHz, son aproximadamente 3 us. Así que 0,3% de gastos generales, no 5%. Ciertamente puede hacer eso, pero nunca antes había tenido problemas con la ejecución de un ISR pequeño a 1 kHz. Podría ser una buena idea volver a implementarlo solo para que pueda agregar más elementos para ejecutar en cada marca del temporizador, o programar cosas para ejecutar en futuras marcas. Un método que uso con frecuencia es programar algo para que se ejecute en, por ejemplo, Intervalos de 1 segundo almacenando la hora actual + el intervalo en una variable y luego, cuando la hora excede la marca de tiempo futura, incremento la marca de tiempo por el intervalo de entrada y luego ejecuto el código. Si se omite una marca, la llamada actual solo se retrasa una vez. Sería muy fácil usar este método para ejecutar cosas en intervalos de 10 ms o 100 ms.

    
respondido por el alex.forencich

Lea otras preguntas en las etiquetas