Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Contenido:
1) Retardos por software..3 1.1 Ejemplos..5 1.2 Preguntas y Respuestas.6 2) Bucles anidados..7 2.1 Ejemplos...8 2.2 Ejercicio.9 3) Retardos como subrutinas...10 4) Retardos como supresores de ruido..11 5) Trucos..12 6) Practicas para compilar y probar.13
A menudo es necesario que nuestros programas usen demoras o retardos, por ejemplo, si deseamos hacer parpadear un led cada segundo evidentemente necesitaremos usar un retardo de 1s. Los retardos son prcticamente omnipresentes en nuestros programas. Y hay dos formas de hacerlos: -Por software -Por TMR0 Retardo por Software Los retardos por Software consisten en que el pic se quede enciclado durante un tiempo. Es decir, es necesario usar uno o varios contadores que debern ser decrementados, cuando dichos contadores lleguen a 0 habr concluido el retardo. Ejemplo con flujo-grama:
Inicio de retardo
CONTA_1
NO CONTA_1 (CONTA_1 1)
CONTA_1 = 0 ?
SI
FIN
Observe en el diagrama anterior como a una variable CONTA_1 se le asigna un numero n, posteriormente esta variable se decrementa y se pregunta si ha llegado a 0, si no ha llegado a 0 entonces se vuelve a decrementar, y asi sucesivamente hasta que llegue a 0 en cuyo caso es el FIN del retardo. El programa se quedo perdiendo el tiempo encilado dando vueltas n veces. Veamos la traduccin a ensamblador, para esto consideremos que n=100.
Inicio_retardo movlw movwf decfsz goto -----d100 CONTA_1 CONTA_1,F $-.1 --------
; CONTA_1 ; CONTA_1
;NO ha llegado a 0, entonces vuelve a decrementar ;SI llego a 0 entonces FIN del retardo,sigue el programa
Observe que tenemos una instruccin nueva decfsz, esta instruccin es equivalente a decir: Decrementa el registro f y salta si ha llegado a 0 Es una instruccin muy til y sumamente utilizada principalmente en procesos que se repiten n numero de veces, tales como lo son los retardos. Muy bien, en este punto entendemos el concepto de un retardo por software, sin embargo surge una duda obvia e importante: Cmo calculo el tiempo que durar un retardo? Muy bien, observemos esta parte del cdigo ensamblador: decfsz goto CONTA_1,F $-.1 ; CONTA_1 CONTA_1 -1 y salta si ya llego a 0
Ntese que esta parte es la que se ejecuta n veces hasta que CONTA_1 llega a 0, asi que solo debemos saber cunto tardan en ejecutarse estas dos instrucciones, luego lo multiplicamos por n y el resultado es el tiempo que dura el retardo. La instruccin decfsz dura 1us y la instruccin goto dura 2us, asi que entre ambas duran 3uS, asi pues el retardo durar:
Retardo = 3uS x n
si n= 100 entonces
Retardo = 300uS
Nota: La parte del cdigo que se ejecuta repetitivamente hasta que CONTA_1 llega a 0 se llama BUCLE.
EJEMPLO: Deseamos hacer un retardo de 100uS, entonces usamos el mismo cdigo: Inicio_retardo movlw movwf decfsz goto -----dn CONTA_1 CONTA_1,F $-.1 -------;etiqueta para dar nombre al retardo ;W n W CONTA_1 -1 y salta si ya llego a 0
; CONTA_1 ; CONTA_1
;NO ha llegado a 0, entonces vuelve a decrementar ;SI llego a 0 entonces FIN del retardo,sigue el programa
Solo que ahora no sabemos cunto valdr n. Para calcular n usamos la formula anterior: Retardo = n x 3uS Despejamos n y tenemos: n = Retardo / 3uS n = 100uS / 3uS = 33.333
Entonces sabemos que debemos cargar a la variable CONTA_1 con el numero 33 para lograr un retardo aproximado a 100uS: Retardo = n x 3us = 33 x 3us = 99uS.
EJEMPLO 2: Deseamos hacer un retardo de 100uS, para esto ahora hacemos un pequeo cambio al cdigo en ensamblador del retardo: Inicio_retardo movlw movwf nop decfsz goto -----CONTA_1,F $-.2 -------; CONTA_1 CONTA_1 -1 y salta si ya llego a 0 d100 CONTA_1 ;etiqueta para dar nombre al retardo ;W 100 W
; CONTA_1
;NO ha llegado a 0, entonces salta 2 instrucciones atras ;SI llego a 0 entonces FIN del retardo,sigue el programa
Observe que ahora tenemos una instruccin nueva: nop, esta instruccin dura 1uS y la operacin que realiza es nula, es decir, no hace nada, entonces para que la usamos? Observe esta parte del cdigo: nop decfsz goto CONTA_1,F $-.2 ; CONTA_1 CONTA_1 -1 y salta si ya llego a 0
Note que esta parte del cdigo es la que se repite n veces hasta que CONTA_1 llegue a 0 (bucle). El bucle ahora tiene 3 instrucciones: nop (1uS), decfsz (1uS) y goto (2uS), que entre las tres suman 4uS, entonces la frmula para nuestro retardo cambio: Retardo = 4uS x n Despejamos n y tenemos: n = Retardo / 4uS n = 100uS / 4uS = 25
Vemos como usando la instruccin nop el numero que cargamos a CONTA_1 es ms exacto y menor. Se puede ver la utilidad de esta instruccin que aparentemente era ociosa.
PREGUNTAS: 1) Realice un retardo que dure 1mS 2) Cuanto es el Tiempo mximo que se genera sin la instruccin nop y cuanto con la instruccin nop de los ejemplos anteriores? 3) Es posible generar un retardo mayor agregando mas instrucciones nop? ----------------------------------------------------------------------------------------------------------------------------Respuestas 1) Inicio_retardo movlw movwf nop decfsz goto -----CONTA_1,F $-.2 -------n = Retardo / 4 uS 2) Sin el nop = 765uS, con el nop = 1025uS. 3) Si es posible generar retardos ms grandes de esa manera paro hay mtodos ms efectivos para hacer retardos prolongados. ; CONTA_1 CONTA_1 -1 y salta si ya llego a 0 d250 CONTA_1 ;etiqueta para dar nombre al retardo ;W 250 W
; CONTA_1
;NO ha llegado a 0, entonces salta 2 instrucciones atras ;SI llego a 0 entonces FIN del retardo,sigue el programa n = 1000uS / 4uS = 250
Bucles anidados
Como hemos visto el retardo mximo que se puede generar de las formas enunciadas anteriormente son apenas mayores a 1mS. Para generar retardos mucho mayores necesitamos usar BUCLES ANIDADOS. Estos bucles anidados consiten generar un Retardo base que se repetir n veces, el retardo base se hace de la manera anteriormente mencionada usando un bucle que llamamos bucle interno, y al repetir este retardo base n veces estamos formando un bucle mayor o bucle externo. Veamos el ejemplo en flujo-grama:
Inicio de retardo
CONTA_2
CONTA_1
NO
CONTA_1 CONTA_1-1 CONTA_1=0?
CONTA_2
(CONTA_2 1)
NO
CONTA_2 = 0 ?
SI
FIN
Observe como primero se carga a la variable CONTA_2 con m, luego CONTA_1 se carga con n, luego se decrementa CONTA_1 hasta que llegue a 0 en cuyo caso decrementa CONTA_2, si CONTA_2 no es 0 entonces vuelve a cargar CONTA_1 con n y se vuelve a repetir el ciclo de decrementar CONTA_1 hasta 0, el ciclo se repite m veces hasta que CONTA_2 llegue a 0 en cuyo caso ser el fin del retardo. Recuerde que la frmula para el retardo simple de un solo bucle usando la instruccin nop era: Retardo = n x 4uS Utilizando dos bucles anidados la frmula del retardo sera la siguiente: Retardo = m x (n x 4uS) Muy simple verdad. Veamos como se traduce a ensamblador:
Inicio_retardo movlw movwf movlw movwf nop decfsz goto decfsz goto -----CONTA_1,F $-.2 CONTA_2,F $-.6 -------dm CONTA_2 dn CONTA_1 ;W m W
; CONTA_2 ;W n
;CONTA_1 W ;no opera ;CONTA_1 CONTA_1-1 y salta si llego a 0 ;NO es 0, entonces salta al nop ;SI es 0, entonces CONTA_2 CONTA_2 -1 y salta si llega a 0 ;No es 0, entonces regresa a cargar conta_1 ;Si es 0, entonces fin del retardo
EJEMPLO: Realizar un retardo de 10mS. Recuerde que para un retardo de 1 mS usbamos un retardo simple de un bucle y la variable CONTA_1 le asignbamos 250: Retardo interno= 4uS x 250 = 1000uS = 1mS Usaremos este retardo como reatrdo base y lo repetiremos 10 veces para hacer un retardo final de 10ms: Retardo = m x (4uS * 250) = 10 x (1mS) = 10mS Es decir, m = 10 y n = 250, con eso logramos el retardo de 10mS
Retardo de 10mS en ensamblador: Inicio_retardo movlw movwf movlw movwf nop decfsz goto decfsz goto -----CONTA_1,F $-.2 CONTA_2,F $-.6 -------d10 CONTA_2 d250 CONTA_1 ;W m W
; CONTA_2 ;W n
;CONTA_1 W ;no opera ;CONTA_1 CONTA_1-1 y salta si llego a 0 ;NO es 0, entonces salta al nop ;SI es 0, entonces CONTA_2 CONTA_2 -1 y salta si llega a 0 ;No es 0, entonces regresa a cargar conta_1 ;Si es 0, entonces fin del retardo y sigue con el programa
EJERCICIO: Genere el cdigo para hacer un retardo de 1 segundo. Solucin: 1 segundo = 1000 mS, notamos de inmediato que ser necesario un tercer bucle ya que el numero 1000 no podr ser cargado al CONTA_2 ya que supera el mximo de 255. Asi que nuestra formula con un tercer bucle seria as: Retardo = p x ( m x (n x 4uS) ) O bien: Retardo = CONTA_3 x ( CONTA_2 x (CONTA_1 x 4uS) )
Inicio_retardo movlw movwf movlw movwf movlw movwf nop decfsz goto decfsz goto decfsz goto ------
d10 CONTA_2 d100 CONTA_2 d250 CONTA_1 CONTA_1,F $-2 CONTA_2,F $-6 CONTA_3,F $-10 --------
;W m ; CONTA_3 W ;W m ; CONTA_2 W ;W n ;CONTA_1 W ;no opera ;CONTA_1 CONTA_1-1 y salta si llego a 0 ;NO es 0, entonces salta al nop ;SI es 0, entonces CONTA_2 CONTA_2 -1 y salta si llega a 0 ;No es 0, entonces regresa a cargar conta_1 ;SI es 0, entonces CONTA_2 CONTA_2 -1 y salta si llega a 0 ;No es 0, entonces regresa a cargar conta_1 ;Si es 0, entonces fin del retardo y sigue con el programa
Note la facilidad para hacer retardos, Es muy conveniente usar retardos base redondos con base en 10 es decir, que el retardo base sea de 1mS o 10mS etc para que solo se repita n veces para calcular y obtener los retardos que deseemos fcilmente y no tener que calcular tanto.
Inicio_principal bsf call bcf call goto LED Retardo_1s LED Reatrdo_1s Inicio_principal ;encendemos el LED ;Llamamos a la subrutina Retardo_1s ;apagamos el LED ;llamamos a la subrutina Retardo_1s ;Repetimos el ciclo
Retardo_1s movlw movwf movlw movwf movlw movwf nop decfsz goto decfsz goto decfsz goto return d10 CONTA_2 d100 CONTA_2 d250 CONTA_1 CONTA_1,F $-.2 CONTA_2,F $-.6 CONTA_3,F $-.10
;Subrutina Retardo_1s ;W m ; CONTA_3 W ;W m ; CONTA_2 W ;W n ;CONTA_1 W ;no opera ;CONTA_1 CONTA_1-1 y salta si llego a 0 ;NO es 0, entonces salta al nop ;SI es 0, entonces CONTA_2 CONTA_2 -1 y salta si llega a 0 ;No es 0, entonces regresa a cargar conta_1 ;SI es 0, entonces CONTA_2 CONTA_2 -1 y salta si llega a 0 ;No es 0, entonces regresa a cargar conta_1 ;Si es 0, entonces fin del retardo y regresa
Las subrutinas son segmentos de cdigo que se pueden ejecutar cada vez que el programa principal las llame y cuando terminen de ejecutarse regresan a la siguiente posicin de donde fueron llamadas. La instruccin que las manda a llamar es CALL y la instruccin que regresa a la siguiente posicin de donde fueron llamadas es RETURN. Las subrutinas deben tener un nombre para poder ser llamadas. Son una herramienta muy til que ahorra espacio de memoria y facilita la programacin.
;exploramos el boton ;no se presiono, entonces sigue explorarndo ;si se pulso, entonces demora de 20ms ;incrementa la variable CONTADOR ;enviamos CONTADOR a PORTB para ver cuenta ;repetir el ciclo
Retardo_20ms movlw movwf movlw movwf nop decfsz goto decfsz goto return
;W m ; CONTA_2 W ;W n ;CONTA_1 W ;no opera ;CONTA_1 CONTA_1-1 y salta si llego a 0 ;NO es 0, entonces salta al nop ;SI es 0, entonces CONTA_2 CONTA_2 -1 y salta si llega a 0 ;No es 0, entonces regresa a cargar conta_1 ;Si es 0, entonces fin del retardo y sigue con el programa
TRUCOS
Existe un truco muy util llamado multiplicacin de retardos base. Este truco consiste en usar uno o unos pocos retardos base y solo invocarlos y multiplicarlos por X para tener tantos retardos como queramos. Asi se puede hacer un retardo base de 1ms y generar cuando queramos retardos desde 1ms hasta 255ms sin necesidad de hacer 255 retardos diferentes. La formula que usaramos seria la siguiente: Retardo = W X Retardo_base Por ejemplo, si se desea un retardo de 10 ms solo se hara lo siguiente: movlw call d10 Retardo_x1ms
----------------------------------------------------------------------------------------------------------------------------Ejemplo: . . movlw call . . Retardo_x1ms movwf movlw movwf nop decfsz goto decfsz
goto
; subrutina Retardo x 1 ms ; CONTA_2 10 ; W 250 ;CONTA_1 W ;no opera ;CONTA_1 CONTA_1-1 y salta si llego a 0 ;NO es 0, entonces salta al nop ;SI es 0, entonces CONTA_2 CONTA_2 -1 y salta si llega a 0
return Lo que hace lo anterior es primero mover a W el 10, luego llama al reatardo, en donde a CONTA_2 se le asigna lo que tiene W, como el retardo base es de 1ms entonces el retardo total es W x 1ms. ----------------------------------------------------------------------------------------------------------------------------Podemos hacer 5 retardos base de 1ms de 10ms de 100ms de 1seg y de 10seg y asi hacer combinaciones para poder hacer todos los retardos posibles desde 1ms hasta 2550 segundos. Por ejemplo, si deseamos un retardo de 362ms entonces escribiramos lo siguiente: movlw call movlw call d3 Retardo_x100ms d62 Retardo_x1ms ;Retardo de 3 x 100ms = 300ms ;Retardo de 62 x 1ms = 62ms