Estoy trabajando con un microcontrolador Atmel ATMEGA32U4 - hoja de datos aquí con un cristal de 16 MHz para el reloj del sistema.
A mi entender, este chip tiene un fusible 'Dividir reloj por 8' programado de fábrica, lo que hace que mi sistema sea de 2 MHz. (Página 348 de la hoja de datos. CKDIV8 (bit 7) el valor predeterminado es 0, programado).
Me gustaría confirmar la velocidad del reloj de mi sistema, así que escribí un código para generar un pin bajo, retrasar un ciclo de reloj y luego volver a colocar el pin alto. Medir el tiempo que el pin está bajo debería ser igual a un ciclo de reloj.
Aquí está el código que usé para lograr esto:
//Set PORT E as output
DDRE = 0xFF;
asm volatile("nop\n\t"::);
PORTE |= 1<<2;
asm volatile("nop\n\t"::);
PORTE &=~ (1<<2);
asm volatile("nop\n\t"::);
PORTE |= 1<<2;
asm volatile("nop\n\t"::);
PORTE &=~ (1<<2);
Un 'nop' es igual a un ciclo de reloj, según el manual del conjunto de instrucciones AVR , página 108 .
En base a esta información, asumiría una instrucción 'nop' para tomar 500 nanosegundos. ¿Es esta suposición correcta? (16 MHz / 8 = 2 MHz. \ $ \ Frac1 {2MHz} \ $ = 500ns)
Aquí hay un diagrama de alcance de mis hallazgos:
Parece que el tiempo de ejecución 'nop' es de solo 200 ns (5 MHz) Yo esperaría que hubiera una sobrecarga adicional usando C para establecer el puerto alto / bajo, por lo que 500 ns es en realidad el tiempo mínimo que esperaría que el pin sea bajo. Pero como se puede ver en mis cursores de medición 'a' y 'b', ni siquiera está cerca de 500 ns.
¿Puede alguien explicar qué está pasando?
¿Hay algún error en mi método?
¿Me estoy perdiendo algo estúpido? : p
Gracias por cualquier ayuda!