7 votos

Arduino: delaymicroseconds ()

¿Cómo funciona la función delayMicrosseconds (). Por lo que entendí el prescaler de timer0 se establece en 64. Para un reloj de 16MHz da 4.0uS por cuenta. Estoy un poco confundido en las matemáticas para llegar a 1uS intervalo?

6voto

jason Puntos 147

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 los sistemas Linux. Los sistemas Windows tienen una trayectoria similar a la de cableado.c archivo. Tome el esfuerzo de encontrar el archivo y la navegación a través de él. Por ahora sólo se centran en esta única función, que no depende de ningún otro fucntions.

Inspeccionando el código verás que no se trata de temporizadores, es todo acerca de la instrucción de los ciclos. El código se basa fundamentalmente en la optimización del compilador ser exactamente el mismo para usted como para el desarrollador de la biblioteca. De que la suposición de que el autor! El número de ciclos de la CPU se "queman" por cada instrucción está bien documentada en el Atmel AVR conjunto de instrucciones del documento.

Primero, el valor de retardo está marcada por ser igual a 1, en este caso que acabamos de volver de la rutina ya pasó más de un microsegundo de tiempo de CPU.

A continuación, el valor de retardo se multiplica por cuatro (<<=2). El __asm__-bucle se compila en un 4 CPU ciclo del bucle. 4 ciclos × 4 = 16 ciclos. 16MHz/(4×4) = 1MHz, que tarda de 1 a nos de tiempo de ciclo, la resolución que estamos buscando.

La última -2 microsegundos (antes de que el bucle es pateada) es de nuevo una corrección en el compilador introduce sobrecarga. Llamando __asm__-código de C requiere algunas instrucciones adicionales para guardar los registros de la CPU.

Para un normal Arduino @16MHz sólo el código siguiente se compila:

/* Delay for the given number of microseconds.  Assumes a 8 or 16 MHz clock. */
void delayMicroseconds(unsigned int us)
{
        // calling avrlib's delay_us() function with low values (e.g. 1 or
        // 2 microseconds) gives delays longer than desired.
        //delay_us(us);
        // for the 16 MHz clock on most Arduino boards

        // for a one-microsecond delay, simply return.  the overhead
        // of the function call yields a delay of approximately 1 1/8 us.
        if (--us == 0)
                return;

        // the following loop takes a quarter of a microsecond (4 cycles)
        // per iteration, so execute it four times for each microsecond of
        // delay requested.
        us <<= 2;

        // account for the time taken in the preceeding commands.
        us -= 2;

        // busy wait
        __asm__ __volatile__ (
                "1: sbiw %0,1" "\n\t" // 2 cycles
                "brne 1b" : "=w" (us) : "0" (us) // 2 cycles
        );
}

BTW: El código compilado es bastante exacta, pero hay que ser conscientes de lo siguiente: En Arduino hay interrupciones temporizadas configurado que la mayoría no son conscientes de. Cuando una interrupción durante la ejecución de la delayMicroseconds(), el tiempo de delayMicroseconds() será malo. Usted puede, por supuesto, dejar de interrupciones antes de llamar a delayMicroseconds() y permitirles después, pero que de nuevo hace el impacto de precisión en el tiempo por la duración de código compilado para habilitar/deshabilitar.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X