assembly pic

assembly - ¿Cómo funciona Delay en PIC ASM? Estoy realmente desconcertado



(3)

Realmente no lo entiendo en absoluto. Todo el código que veo en línea de alguna manera en los comentarios tiene números aleatorios de por qué está haciendo tantos ciclos, pero literalmente no hay ninguna explicación sobre por qué qué o qué hace quién. Realmente no tengo ni idea.

Por ejemplo:

cblock Delay1 Delay2 Delay3 endc Start: . . . Delay movlw .2 movwf Delay1 ;&&&& movlw .3 movwf Delay2 movlw .4 <------ Important note here. For some reason it loops back to the movwf Delay3 <------ "&&&&" mark when it reads this piece of code. NO IDEA why DelayLoop decfsz Delay1,f <----- Explain what this does. Where does it get the time from? goto DelayLoop <----- Thanks decfsz Delay2,f <----- goto DelayLoop end

Cualquier ayuda sería fantástica.


"Realmente no lo entiendo. Todo el código que veo en línea de alguna manera en los comentarios tiene números aleatorios de por qué está haciendo tantos ciclos, pero literalmente no hay ninguna explicación de por qué qué o qué hace quién. Realmente no tengo ni idea."

"Entiendo eso, pero me gusta, no sé de dónde sacas el tiempo exacto. ¿Cómo lo calculan? ¿De dónde vienen estos números? Si configuro VAR1 a 15, ¿qué sucede ?, ¿qué cambia? Si configuro el tres variables de retardo a 4, 16, 12, ¿de dónde viene el momento? ¿Qué sucede con esos números para hacer que el ciclo sea un cierto tiempo? Gracias - Jimmy Page "

Si entiendo tus preguntas, entonces:

La hoja de datos 16F690 dice:

Un ciclo de instrucciones consta de cuatro períodos de oscilador para una frecuencia de oscilador de 4 MHz, esto da un tiempo de ejecución de instrucción normal de 1 μs. Todas las instrucciones se ejecutan dentro de un solo ciclo de instrucción, a menos que una prueba condicional sea verdadera o el contador del programa se modifique como resultado de una instrucción. Cuando esto ocurre, la ejecución requiere dos ciclos de instrucción, y el segundo ciclo se ejecuta como NOP.

Entonces digamos que Delay1 tiene el valor 3 y tenemos este ciclo:

Top decfsz Delay1,f goto Top

Cada vez que ejecutamos decfsz obtenemos el stock de un ciclo. SI f es cero y tenemos que omitir, se convierte en una instrucción de dos ciclos. Cada vez que ejecutamos goto, la PC cambia, por lo que es una instrucción de 2 ciclos. Entonces, si recorremos el ciclo y lo muestro utilizando el formato

Valor de retardo1 antes de la instrucción, instrucción, ciclos utilizados para ejecutar, ciclos totales

3,decfsz,1,1 2,goto,2,3 2,decfsz,1,4 1,goto,2,6 1,decfsz,2,8

Así que ese bucle en sí mismo con Delay1 comenzando en 3 tomó 8 ciclos u 8us si estuviéramos corriendo a 4mhz. Es importante calcular ciclos primero, luego ajustar la velocidad del reloj de la pieza, ese mismo código podría ser 16us cuando se ejecuta a 2mhz o 32us cuando se ejecuta a 1mhz.

Entonces, mediante inspección, podemos ver que para los valores f que no son uno, el par decfsz + goto son 2 + 1 = 3 ciclos. La única vez que golpeemos decfsz con un valor de 1 será 2 ciclos. Entonces, comenzando con el Retraso1 de 3, habrá 2 valores de entrada no uno (3,2). Y agregue 2 ciclos por última vez que pulsemos decfsz y omitir, ciclos totales ((3-1) * 3) + 2 = 8.

Si hubiéramos ingresado a este bucle con Delay1 establecido en 11, sería ((11-1) * 3) + 2 = 32 ciclos, un 7 sería 20 ciclos.

Si va más allá y ajusta un ciclo de decfsz alrededor de otro, continúa multiplicando el número de ciclos ejecutados. Si Delay1 es un 3 entrante y Delay2 es un 2

Top decfsz Delay1,f goto Top decfsz Delay2,f goto Top

Entonces, la primera vez a través del Delay1 decfsz, goto loop sabemos que es de 8 ciclos. El primer decfsz Delay2, f porque Delay2 no es un 1 es 1 ciclo, somos hasta 9 en total. el goto es 2 más, 11 en total. Asumiendo que la memoria f es de 8 bits, entonces la segunda vez que golpeamos el bucle Delay1 ingresamos con un 0, pensemos que es 0x100 o 256 para la matemática que nos da ((256-1) 3) + 2 = 767 ciclos más , 778 en total hasta el momento. Delay2 ahora es un 1, así que este es el último decfsz Delay2, f, por lo que nos cuesta 2, un total de 780 ciclos. Y podríamos llegar a un algoritmo para calcular los ciclos de ese Algo cercano a ((Delay2-1) (((256-1) * 3) +2)) + (((Delay1) -1) * 3) + 2) + ((Delay2-1) * 3) +2 ciclos.

Y aunque mi loop es más pequeño en un loop de decfsz que el tuyo, si haces que el mío se parezca al tuyo, comienza con otras instrucciones:

Entry movlw .3 movwf Delay1 movl2 .2 movwf Delay2 Top decfsz Delay1,f goto Top decfsz Delay2,f goto Top

Necesitamos agregar 4 ciclos más para las dos movlw y dos movwf''s a la ecuación general para el número de ciclos a ejecutar.

Entonces, literalmente, hay una explicación de por qué está ejecutando tantos ciclos. Y esa explicación estaba en la hoja de datos para el dispositivo.

Vamos a llevar esto más allá. Permite obtener el generador de código al que patrickmdnet está vinculado para generar 780 ciclos:

; Delay = 780 instruction cycles ; Clock frequency = 4 MHz ; Actual delay = 0.00078 seconds = 780 cycles ; Error = 0 % cblock d1 d2 endc ;778 cycles movlw 0x9B movwf d1 movlw 0x01 movwf d2 Delay_0 decfsz d1, f goto $+2 decfsz d2, f goto Delay_0 ;2 cycles goto $+1

Este ciclo tiene una arquitectura un poco diferente.

comenzamos con 4 ciclos de carga de los registros f antes de llegar a Delay_0

El interior de los bucles de decfsz no se ramifica directamente a Delay_0 como el código en su pregunta y mi explicación anterior, esta salta sobre decfsz d2, f. Entonces para el que no pasa pasa por ese ciclo hay 1 ciclo para el decfsz, 2 ciclos para el goto $ + 2 y 2 ciclos para el goto Delay_0, total 5 ciclos para cada d1 no uno. Y agregue dos más por el tiempo que d1 es 1. Esto nos da ((0x9B-1) * 5) +2 = 772 ciclos agregue los 4 ciclos antes de esto estamos en 776 ciclos.

Curiosamente, el último decfsz d1, f golpea a un decfsz d2, f con d2 establecido en 0x01, lo que significa que se garantiza que omita. es 2 ciclos, un goto $ + 2 con otro goto $ + 1 en lugar de la movlw / movwf para cargar d2 habría hecho lo mismo. De todos modos, esta instrucción única de 2 ciclos nos lleva a un total de 778 ciclos

Necesitamos dos ciclos más para llegar a 780 y eso se hace aquí con un goto $ + 1, los gotos modifican la pc para que siempre sean 2 ciclos. Tenemos los 780 ciclos que solicité al programa para generar.


La idea detrás de los bucles de retardo es grabar un cierto número de ciclos que se correlacionan con una cierta cantidad de tiempo. La cantidad de tiempo por ciclo depende de la velocidad de reloj de su CPU PIC.

Lo que ha publicado es un ciclo de retardo de tres etapas similar a los generados aquí: http://www.piclist.com/techref/piclist/codegen/delay.htm

El primer bloque de instrucciones carga tres ubicaciones de memoria con contadores. Use el programa anterior para encontrar los valores óptimos para producir la demora que desea.

El segundo conjunto de instrucciones es el retraso real. "decfsz VAR, f" disminuirá VAR en 1; si VAR es cero, omite la siguiente instrucción. Entonces, en el caso anterior, decfsz se ejecutará hasta que Delay1 sea cero, luego saltará sobre "goto DelayLoop" y comenzará "decfsz Delay2, f".

Sugiero leer esta página: http://www.mstracey.btinternet.co.uk/pictutorial/progtut4.htm

y también esta página: http://www.piclist.com/techref/microchip/PIC16DelayTutorial.htm

para obtener más ayuda sobre cómo funciona decfsz y goto.


La frecuencia del oscilador RC incorporado determina el ciclo del reloj, que a su vez determina la velocidad.