Professional Documents
Culture Documents
GRUPO ESTUDIANTIL
INVENTRONICA
Joel Oswaldo Campos
Prez
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
Pgina 2
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 n
NO
CONTA_1 (CONTA_1 1)
CONTA_1 = 0 ?
SI
FIN
Pgina 3
Inicio_retardo
movlw
d100
; W 100
movwf
CONTA_1
; CONTA_1 W
decfsz
CONTA_1,F
goto
$-.1
------
--------
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
CONTA_1,F
goto
$-.1
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.
Pgina 4
EJEMPLO:
Deseamos hacer un retardo de 100uS, entonces usamos el mismo cdigo:
Inicio_retardo
movlw
dn
;Wn
movwf
CONTA_1
; CONTA_1 W
decfsz
CONTA_1,F
goto
$-.1
------
--------
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
d100
; W 100
movwf
CONTA_1
; CONTA_1 W
decfsz
CONTA_1,F
goto
$-.2
------
--------
nop
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
CONTA_1,F
goto
$-.2
Pgina 5
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
d250
; W 250
movwf
CONTA_1
; CONTA_1 W
decfsz
CONTA_1,F
goto
$-.2
------
--------
nop
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.
Pgina 6
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 m
CONTA_1 n
NO
CONTA_1CONTA_1-1
CONTA_1=0?
CONTA_2 (CONTA_2 1)
NO
CONTA_2 = 0 ?
SI
FIN
Pgina 7
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
dm
;Wm
movwf
CONTA_2
; CONTA_2 W
movlw
dn
;Wn
movwf
CONTA_1
;CONTA_1W
nop
;no opera
decfsz
CONTA_1,F
goto
$-.2
decfsz
CONTA_2,F
goto
$-.6
------
--------
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
Pgina 8
d10
;Wm
movwf
CONTA_2
; CONTA_2 W
movlw
d250
;Wn
movwf
CONTA_1
;CONTA_1W
nop
;no opera
decfsz
CONTA_1,F
goto
$-.2
decfsz
CONTA_2,F
goto
$-.6
------
--------
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
--------
;Wm
; CONTA_3 W
;Wm
; CONTA_2 W
;Wn
;CONTA_1W
;no opera
;CONTA_1CONTA_1-1 y salta si llego a 0
;NO es 0, entonces salta al nop
;SI es 0, entonces CONTA_2CONTA_2 -1 y salta si llega a 0
;No es 0, entonces regresa a cargar conta_1
;SI es 0, entonces CONTA_2CONTA_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
Pgina 9
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
LED
;encendemos el LED
call
Retardo_1s
bcf
LED
;apagamos el LED
call
Reatrdo_1s
goto
Inicio_principal
;Subrutina Retardo_1s
Retardo_1s
movlw
movwf
movlw
movwf
movlw
movwf
nop
decfsz
goto
decfsz
goto
decfsz
goto
return
;Repetimos el ciclo
d10
CONTA_2
d100
CONTA_2
d250
CONTA_1
CONTA_1,F
$-.2
CONTA_2,F
$-.6
CONTA_3,F
$-.10
;Wm
; CONTA_3 W
;Wm
; CONTA_2 W
;Wn
;CONTA_1W
;no opera
;CONTA_1CONTA_1-1 y salta si llego a 0
;NO es 0, entonces salta al nop
;SI es 0, entonces CONTA_2CONTA_2 -1 y salta si llega a 0
;No es 0, entonces regresa a cargar conta_1
;SI es 0, entonces CONTA_2CONTA_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.
Pgina 10
Explorar_boton
BTFSS
GOTO
CALL
INCF
MOVF
MOVWF
GOTO
Retardo_20ms
movlw
movwf
movlw
movwf
nop
decfsz
goto
decfsz
goto
return
PUSH
explorar_boton
Retardo_20ms
CONTADOR,F
CONTADOR,W
PORTB
explorar_contador
d20
CONTA_2
d250
CONTA_1
CONTA_1,F
$-.2
CONTA_2,F
$-.6
;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
;Wm
; CONTA_2 W
;Wn
;CONTA_1W
;no opera
;CONTA_1CONTA_1-1 y salta si llego a 0
;NO es 0, entonces salta al nop
;SI es 0, entonces CONTA_2CONTA_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
Pgina 11
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
d10
;W10
Retardo_x1ms ;Asi tendriamos un retardo de 10 x 1mS = 10mS
CONTA_2
d250
CONTA_1
CONTA_1,F
$-.2
CONTA_2,F
; subrutina Retardo x 1 ms
; CONTA_2 10
; W 250
;CONTA_1W
;no opera
;CONTA_1CONTA_1-1 y salta si llego a 0
;NO es 0, entonces salta al nop
;SI es 0, entonces CONTA_2CONTA_2 -1 y salta si llega a 0
$-.6
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
Pgina 12
LED PARPADEANTE: Enciende y apaga un led conectado a RB0 con una duracin de 1
segundo.
list
p=16f877a ; list directive to define processor
#include <p16f877a.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _XT_OSC & _WRT_OFF & _LVP_OFF &
_CPD_OFF
CBLOCK
CONTA_1
CONTA_2
CONTA_3
ENDC
#define LED
ORG
Goto
ORG
0X20
PORTB,0
0
inicio
5
Inicio
Bsf
Bcf
Movlw
Movwf
Clrf
Bcf
STATUS,RP0
STATUS,RP1
d7
ADCON1
TRISB
STATUS,RP0
Inicio_principal
Bsf
Call
BCF
Call
Goto
LED
Retardo_1s
LED
Retardo_1s
Inicio_prinicpal
;encendemos led
;esperamos 1 segundo
;apagamos led
;esperamos 1 segundo
;repetimos el ciclo
Retardo_1s
movlw
movwf
movlw
movwf
movlw
movwf
nop
decfsz
goto
decfsz
goto
decfsz
goto
return
d10
;Wm
CONTA_2; CONTA_3 W
d100
;Wm
CONTA_2; CONTA_2 W
d250
;Wn
CONTA_1;CONTA_1W
;no opera
CONTA_1,F
;CONTA_1CONTA_1-1 y salta si llego a 0
$-.2
;NO es 0, entonces salta al nop
CONTA_2,F
;SI es 0, entonces CONTA_2CONTA_2 -1 y salta si llega a 0
$-.6
;No es 0, entonces regresa a cargar conta_1
CONTA_3,F
;SI es 0, entonces CONTA_2CONTA_2 -1 y salta si llega a 0
$-.10
;No es 0, entonces regresa a cargar conta_1
;Si es 0, entonces fin del retardo y regresa
Pgina 13
LED PARPADEANTE 2: Enciende un led el 20% del tiempo, el led conectado a RB0. Periodo de
1 segundo, frecuencia de 1Hz. Usando el truco de multiplicacin de retardo base.
list
p=16f877a ; list directive to define processor
#include <p16f877a.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _XT_OSC & _WRT_OFF & _LVP_OFF &
_CPD_OFF
CBLOCK
CONTA_1
CONTA_2
CONTA_3
ENDC
#define LED
ORG
Goto
ORG
0X20
PORTB,0
0
inicio
5
Inicio
Bsf
Bcf
Movlw
Movwf
Clrf
Bcf
STATUS,RP0
STATUS,RP1
d7
ADCON1
TRISB
STATUS,RP0
Inicio_principal
Bsf
Movlw
Call
BCF
Movlw
Call
Goto
LED
d2
Retardo_x100ms
LED
d8
Retardo_x100ms
Inicio_prinicpal
Retardo_x100ms
movwf
movlw
movwf
movlw
movwf
nop
decfsz
goto
decfsz
goto
decfsz
goto
return
CONTA_2; CONTA_3 W
d100
;Wm
CONTA_2; CONTA_2 W
d250
;Wn
CONTA_1;CONTA_1W
;no opera
CONTA_1,F
;CONTA_1CONTA_1-1 y salta si llego a 0
$-.2
;NO es 0, entonces salta al nop
CONTA_2,F
;SI es 0, entonces CONTA_2CONTA_2 -1 y salta si llega a 0
$-.6
;No es 0, entonces regresa a cargar conta_1
CONTA_3,F
;SI es 0, entonces CONTA_2CONTA_2 -1 y salta si llega a 0
$-.10
;No es 0, entonces regresa a cargar conta_1
;Si es 0, entonces fin del retardo y regresa
;encendemos led
;esperamos 200ms
;apagamos led
;esperamos 800 ms
;repetimos el ciclo
Pgina 14
0X20
PORTA,0
0
inicio
5
Inicio
Bsf
Bcf
Movlw
Movwf
Clrf
Bcf
STATUS,RP0
STATUS,RP1
d7
ADCON1
TRISB
STATUS,RP0
explorar_boton
BTFSS
GOTO
CALL
INCF
MOVF
MOVWF
GOTO
PUSH
explorar_boton
Retardo_20ms
CONTADOR,F
CONTADOR,W
PORTB
explorar_boton
Retardo_20ms
movlw
movwf
movlw
movwf
nop
decfsz
goto
decfsz
goto
return
d20
;Wm
CONTA_2; CONTA_2 W
d250
;Wn
CONTA_1;CONTA_1W
;no opera
CONTA_1,F
;CONTA_1CONTA_1-1 y salta si llego a 0
$-.2
;NO es 0, entonces salta al nop
CONTA_2,F
;SI es 0, entonces CONTA_2CONTA_2 -1 y salta si llega a 0
$-.6
;No es 0, entonces regresa a cargar conta_1
;Si es 0, entonces fin del retardo y regresa
;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
Pgina 15
GRUPO ESTUDIANTIL
INVENTRONICA
Pgina 16