TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: Bar-Tolo en 27 de Febrero de 2009, 22:07:43
-
Hola amigos.
Tengo una curiocidad con este codigo:
;-----------Rutina de Retardo-----------
retardo movlw 10 ; Aquí se cargan los registros
movwf reg1 ; reg1, reg2 y reg3
; con los valores 10, 20 y 30
tres movlw 20 ; respectivamente
movwf reg2
dos movlw 30
movwf reg3
uno decfsz reg3,1 ; Aquí se comienza a decrementar
goto uno ; Cuando reg3 llegue a 0
decfsz reg2,1 ; le quitare 1 a reg2
goto dos ; cuando reg2 llegue a 0
decfsz reg1,1 ; le quitare 1 a reg1
goto tres ; cuando reg1 llegue a 0
retlw 00 ; regresare al lugar
; de donde se hizo la llamada
---------------------------------------------------------------------------------------
Soy nuevo en los PIC y mirando este codigo de retardo, algo me dice que eso no terminaria nunca.No estoy muy familiarizado con las instrucciones de este chip. Pero en este pedazo de codigo :
decfsz reg2,1 ; le quitare 1 a reg2
goto dos ; cuando reg2 llegue a 0
Esto no cargaria de nuevo el reg3 a 30? Algo no entendi bien en este codigo o esta mal esto?
Un Saludo.
-
Esta bien! Son ciclos anidados. Fijate:
Decrementamos reg3 hasta 0. Luego decrementamos reg2 en 1, -> reg2=19
Decrementamos nuevamente reg3, decrementamos reg2, ->=18
.
.
.
Decrementamos nuevamente reg3, decrementamos reg2, ->=0, entonces decrementamos reg1, ->reg1=9.
Decrementamos reg3 hasta 0. Luego decrementamos reg2 en 1, -> reg2=19, reg1=9.
Decrementamos nuevamente reg3, decrementamos reg2, ->=18, reg1=9.
.
.
.
La rutina saldra cuando reg1, reg2, y reg3 esten en 0.
Fijate aquí (http://www.todopic.com.ar/foros/index.php?topic=24720.0) en creacion de demoras.
-
Hola Suky, gracias por responder.
Sigo confundido y es que no estoy bien familiarizado con estas instrucciones.
Por ejemplo DECFSZ = Decrementa el contenido del registro F Si es 0, el resultado se almacena en W, si d es 1 se almacena en F. Si la resta es 0 salta la siguiente instruccion, en cuyo caso costaria 2 ciclos.
Hasta aqui la cosa esta bien.Pero.
uno decfsz reg3,1
goto uno ;aqui esta bien
decfsz reg2,1 ;aqui paso porque llego a 0 en la anterior
goto dos ; aqui es donde estoy confundido, porque en la etiqueta dos dice esto:
dos movlw 30 ; pone en W el valor 30
movwf reg3 ; carga el reg3 con el valor de W (algo me perdi de esta instruccion)
Para mi esto no terminaria nunca.
Repito algo me estoy perdiendo en esta instruccion que no logro ver.
Dejame ponerla completa y mas organizada.
;-----------Rutina de Retardo-----------
retardo movlw 10 ; Aquí se cargan los registros
movwf reg1 ; reg1, reg2 y reg3
; con los valores 10, 20 y 30
tres movlw 20 ; respectivamente
movwf reg2
dos movlw 30
movwf reg3
uno decfsz reg3,1 ; Aquí se comienza a decrementar
goto uno ; Cuando reg3 llegue a 0
decfsz reg2,1 ; le quitare 1 a reg2
goto dos ; cuando reg2 llegue a 0
decfsz reg1,1 ; le quitare 1 a reg1
goto tres ; cuando reg1 llegue a 0
retlw 00 ; regresare al lugar
; de donde se hizo la llamada
Un Saludo.
-
Ok Suky ya lo tengo. :)
Veamos, decfsz reg3,1 esto es, decrementa reg3, si al decrementar te da cero saltéate una línea. El 1 que sigue a reg3, indica que guarde el valor de reg3 decrementado en el mismo reg3, es comoooo.... contador=contador-1 (se entiende...?)
goto, es saltar y goto uno es saltar a la etiqueta uno. En esta pequeña vuelta estoy decrementando reg3 hasta que se haga cero.
Cuando reg3 llegue a 0 decrementaré reg2 en una unidad, volveré a cargar reg3 y lo decrementaré nuevamente para recién restarle otra unidad a reg2, y así... hasta que reg2 se haga cero. Cuando eso ocurra decrementaré reg1 en una unidad, cargaré nuevamente reg2 y reg3, para luego decrementarlos de nuevo, todo esto ocurrirá hasta que reg1 se haga igual a cero.
Encontre la respuesta en esta explicacion del codigo.
Un Saludo.
-
Exacto, se carga nuevamente y se repite hasta que reg2 llege a 0. En este punto decrementamos reg1, volvemos a cargar reg2 y reg3, y se reanuda el ciclo anterior tantas veces hasta que reg1 llegue a 0.
-
Exacto, se carga nuevamente y se repite hasta que reg2 llege a 0. En este punto decrementamos reg1, volvemos a cargar reg2 y reg3, y se reanuda el ciclo anterior tantas veces hasta que reg1 llegue a 0.
Gracias por el enlace a tu tutorial, muy interesante.
Un Saludo.
-
Hola Bar-Tolo, que bien que ya le entendiste. bueno esta es la respuesta que estaba por publicar pero ya paque' no se como cancelarla SALUDOS
El programa de retardo esta bien. Cuando empezamos a programar pics y por ende a hacer retardos en ensamblador se suele confundir uno con los lazos anidados.
Ejemplo RETARDO CHICO:
Si queremos un retardo de aproximadamente 255 ciclos ¿que podemos hacer?... pues lo siguiente:
Retardo
movlw .255 ;en estos dos renglones cargamos reg3 con 255 en decimal
movwf reg_3 ;
ciclo1
decfsz reg_3,F ;decrementamos reg3 y saltamos si vale 0, aqui se encicla 255 veces
goto ciclo1
return
Si hasta aqui no hay problema le seguimos, podemos imaginar el ejemplo anterior como un BLOQUE NEGRO que se queda travado ahi dentro durante 255 ciclos sin hacer nada. Ahora bien, si queremos un retardo de digamos 2550 ciclos (osea 10 veces mas grande) ¿como le hacemos si los registros solo llegan hasta 255?... pues entonces tenemos que repetir el retardo anterior 10 veces, osea repetir el BLOQUE NEGRO 10 veces... ¿como le hacemos?... de la misma manera:
EJEMPLO2 (RETARDO MEDIO):
Retardo
movlw .10 ;Cargamos con el 10 al registro reg_2 para que
movwf reg_2 ;el retardito de 255 se repita 10 veces finalmente
ciclo2
;-----------------------------------------
movlw .255 ;En estos dos renglones cargamos reg3 con 255 en decimal
movwf reg_3
ciclo1
decfsz reg_3,F ;Decrementamos reg3 si NO es cero se encicla en "ciclo1"¿cuantas veces?... pues 255 veces
goto ciclo1
;----------------------------------------
decfsz reg_2,F ;Decrementa reg_2, si NO es cero se encicla en "ciclo2" ¿cuantas veces?... pues 10 veces
goto ciclo2 ;porque reg_2 lo cargamos al inicio con 10.
return
De esta manera hacemos que el primer retardo del ejemplo1 se repita 10 veces, osea que ahora tenemos un retardote de 10x255 ciclos = 2550, es decir, hicimos que el BLOQUE NEGRO se repitiera 10 veces. Pero que pasa si quieres un retardo aun mayor, digamos 25500 osea 10x2550... pues otravez, podemos imaginar el RETARDO MEDIO como nuestro NUEVO BLOQUE NEGRO y hay que repetirlo 10 veces de la misma forma otravez.
EJEMPLO 3 (RETARDO GRANDE):
Visualizamos el EJEMPLO2 (RETARDO MEDIO) como un bloque negro que se tiene que repetir N veces, en este caso 10 veces, y se procede de la misma forma que en las anteriores:
Retardo
movlw .10 ;Cargamos con 10 al reg_1
movwf reg_1 ;para que el retardo medio se repita 10 veces
ciclo3
;*****************************************************************
movlw .10 ;Cargamos con el 10 al registro reg_2 para que
movwf reg_2 ;el retardito de 255 se repita 10 veces al final
ciclo2
;-----------------------------------------
movlw .255 ;En estos dos renglones cargamos reg3 con 255 en decimal
movwf reg_3
ciclo1
decfsz reg_3,F ;Decrementamos reg3 si NO es cero se encicla en "ciclo1"¿cuantas veces?... pues 255 veces
goto ciclo1
;----------------------------------------
decfsz reg_2,F
goto ciclo2
;********************************************************************
decfsz reg_1,F
goto ciclo3
return
Asi tenemos un retardo GRANDE de 10x10x255, supongo que entonces ya te imaginas que se debe hacer si quieres un retardo aun MAYOR, y supongo que te imaginaras porque se llaman LAZOS ANIDADOS.
Los nombres RETARDO CHICO, MEDIO Y GRANDE solo son para explicar, lo mas correcto es llamarlos BUCLE 1, BUCLE 2, BUCLE 3 ... ETC.
En tu PROGRAMA tienes 3 registros de 10 20 y 30 osea que tienes un retardo de aprox 10x20x30=6000 ciclos, APROXIMADAMENTE.
Otro dato es que cada ciclo = 1microsegundo con un oscilador de 4MHz.
Hay formulas para calcular retardos en ENSAMBLADOR que despues te paso, va.
No dudes en preguntar, en estos foros aprendemos muuuuchas cosas.
Un saludo cordial
-
Hola ELECTROSWALDO, gracias por responder.
La confucion mas que nada fue un flash mental, se me perdio la vista en reg3 y reg2.No le puse antencion a reg1 que nunca se recargo en la rutina y que en cada pasada del reg2 se le restaba 1 a reg1 y al llegar a cero pues saltaria.No estoy acostumbrado todavia a instrucciones para PICs.Que a pesar de ser solamente 35 son algo compleja y se le tienen que prestar mucha atencion a algunas ya que en ellas acarreas algunas variantes.Es cosa de tiempo y machucar codigo.
Todavia no tengo programador y pues solo estudio sin practicar nada.Espero que el programador termine de llegar y pues en la practica y jugando con el codigo ya entraran mejor los PICs.
Un Saludo.