Baseline PIC 12F508 Delay Loop Goto Instruction

0

He estado experimentando con un PIC 12F508 y acabo de comenzar a escribir mis propios bucles de retardo en el ensamblador. Nada lujoso, pero simplemente encender y apagar un LED conectado a GP1 (configurado como salida) para verificar el código.

Finalmente conseguí que mi bucle funcionara, pero no entiendo por qué debe escribirse de cierta manera para que funcione.

He copiado parte del código que no funciona a continuación, omití los bits de configuración y configuración de TRIS de entrada / salida para mayor claridad.

Cuando el código se escribe tal como está debajo y dly4 vuelve a su estado original, el LED no parpadea, simplemente permanece encendido.

No entiendo por qué esto se debe a que, de acuerdo con la hoja de datos, una vez que la variable count4 llega a 0, se debe omitir el goto dly4 La siguiente instrucción, goto main_loop, debe ejecutarse, la cual vuelve al inicio del código, alterna el led nuevamente y el proceso se repite.

main_loop

movf    sGPIO,w
xorlw   b'000010' ; toggle LED on GP1
movwf   sGPIO
movwf   GPIO

movlw   .80
movwf   count
movwf   count2
movwf   count3
movwf   count4

dly1    decfsz  count,f
        goto    dly1
dly2    decfsz count2,f
        goto    dly2
dly3    decfsz count3,f
        goto    dly3
dly4    decfsz  count4,f
        goto    dly4
        goto    main_loop
END

Para hacer que el código funcione, tengo que modificar el goto al final del bucle de:

goto    dly4   to    goto    dly1

¿Por qué querría volver a los cuatro bucles? ¿No disminuiría las variables de 0 al reiniciarlas de nuevo a 255? Aunque el código funciona con la modificación anterior, no puedo entender cómo se está saliendo del bucle.

Gracias por cualquier ayuda por adelantado.

    
pregunta Krankshaft

1 respuesta

2

Bueno, hice algunas excavaciones para obtener información precisa. El PIC12F508 es un dispositivo de 33 instrucciones individuales por reloj ... excepto el programa ramas, que toman dos relojes.

Entonces, si la frecuencia del oscilador de este PIC fuera de 4MHz, entonces la tasa de instrucción es de 1MIPS. El periodo de 1MIPS = 1uS. Cada bucle decfsz toma 80 * 3 (ya que hay dos instrucciones y la rama toma dos ciclos) = 240uS. Cuatro de esos total 960uS. Eso es 0.000960 segundos.

" Persistencia de la visión " es un fenómeno de la visión humana que esencialmente significa que si algo se está moviendo lo suficientemente rápido, No puedo verlo y aparece "fluido" o no nervioso. Esencialmente, cualquier cosa que cambie más rápido que 30 veces por segundo (1s / 30 = 0.0333s) es imperceptible para nuestros ojos. Entonces, si el LED cambiase a una velocidad de 0.001 s, entonces lo percibiríamos como encendido constantemente, aunque en realidad estaba parpadeando muy rápido.

Sin embargo, cuando el goto final se cambia al primer bucle, recuerda que el conteo es cero, por lo que disminuirlo hace que sea de 255. ( decfsz disminuye primero , luego salta si es cero). los tres bucles iniciales, este nuevo primer bucle agrega otros 255 * 3 = 765uS. Los dos siguientes también agregan 765uS cada uno. Pero cuando llega a la cuarta, nuevamente disminuye solo una vez y vuelve a la cima. Una y otra vez, 78 veces más. Esto se llama un bucle anidado y es muy común para crear retrasos más grandes.

La conclusión es que la primera versión funciona según lo previsto. Pero sucede tan rápido, no puedes "verlo". La segunda versión repite muchas, muchas veces, por lo que es mucho más lenta y se comporta de una manera que podemos percibir con nuestros ojos.

También tenga en cuenta que este PIC tiene un módulo de temporizador de hardware, TMR0. Esto también puede usarse para crear retrasos e intervalos, y como se implementa en hardware, deja el resto del dispositivo libre para hacer otras cosas mientras TMR0 aumenta. Puede ser un poco complicado de configurar y usar, ya que involucra interrupciones, sin embargo, son muy útiles en aplicaciones del mundo real. Recomiendo probar estos también.

    
respondido por el rdtsc

Lea otras preguntas en las etiquetas