Cómo funciona la función delayMicroseconds (). Por lo que entendí, el preescalador del temporizador 0 está configurado en 64. Para un reloj de 16MHz da 4.0uS por conteo. ¿Estoy un poco confundido con las matemáticas para llegar al intervalo de 1uS?
8
micros()
dice "En placas Arduino de 16 MHz (por ejemplo, Duemilanove y Nano), esta función tiene una resolución de cuatro microsegundos (es decir, el valor devuelto es siempre un múltiplo de cuatro)".Respuestas:
El código fuente de esta función está bastante bien documentado y se puede encontrar en /usr/share/arduino/hardware/arduino/cores/arduino/wiring.c en sistemas Linux. Los sistemas Windows tendrán una ruta similar al archivo cableado.c. Haga el esfuerzo de encontrar el archivo y navegar por él. Por ahora solo concéntrese en esta única función, no depende de ninguna otra función.
Al inspeccionar el código, notará que no se trata de temporizadores, sino de ciclos de instrucción. El código depende en gran medida de que la optimización del compilador sea exactamente la misma para usted que para el desarrollador de la biblioteca. Que una suposición del autor! El número de ciclos de CPU 'quemados' por cada instrucción está bien documentado en el documento del conjunto de instrucciones Atmel AVR .
Primero se verifica que el valor de retraso sea igual a 1, en ese caso, solo regresando de la rutina que ya pasó más de un microsegundo de tiempo de CPU.
Luego, el valor del retraso se multiplica por cuatro (
<<=2
). El__asm__
bucle se compila en un bucle de ciclo de 4 CPU. 4 ciclos × 4 = 16 ciclos. 16MHz / (4 × 4) = 1MHz, lo que lleva 1 tiempo de ciclo, la resolución que buscamos.Los últimos -2 microsegundos (antes de que se inicie el bucle) es nuevamente una corrección en la sobrecarga introducida por el compilador. Llamar a
__asm__
-code desde C requiere algunas instrucciones adicionales para guardar los registros de la CPU.Para un Arduino @ 16MHz normal, solo se compilará el siguiente código:
Por cierto: el código compilado es bastante preciso, pero tenga en cuenta lo siguiente: en Arduino hay interrupciones programadas configuradas que la mayoría desconoce. Cuando se recibe una interrupción durante la ejecución del
delayMicroseconds()
, el momentodelayMicroseconds()
será incorrecto. Por supuesto, puede detener las interrupciones antes de llamardelayMicroseconds()
y habilitarlas después, pero eso nuevamente afecta la precisión del tiempo por la duración del código compilado para habilitar / deshabilitar.fuente