Retardos PIC en MPLAB

12
RETARDOS POR SOFTWARE CÁLCULO DE LOS TIEMPOS DOCENTE: ING. Luis Pacheco Cribillero U.R.P. ESCUELA DE INGENIERÍA MECATRÓNICA

Transcript of Retardos PIC en MPLAB

Page 1: Retardos PIC en MPLAB

RETARDOS POR SOFTWARE

CÁLCULO DE LOS TIEMPOS

DOCENTE: ING. Luis Pacheco Cribillero

U.R.P. ESCUELA DE INGENIERÍA MECATRÓNICA

Page 2: Retardos PIC en MPLAB

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

Page 3: Retardos PIC en MPLAB

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 prácticamente 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 deberán ser decrementados, cuando

dichos contadores lleguen a 0 habrá concluido el retardo.

Ejemplo con flujo-grama:

Inicio de retardo

CONTA_1 � n

CONTA_1 � (CONTA_1 – 1)

CONTA_1 = 0 ?

FIN

NO

SI

Page 4: Retardos PIC en MPLAB

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 traducción a ensamblador, para esto consideremos que n=100.

Inicio_retardo ;etiqueta para dar nombre al retardo

movlw d’100’ ; W � 100

movwf CONTA_1 ; CONTA_1 � W

decfsz CONTA_1,F ; CONTA_1 � CONTA_1 -1 y salta si ya llego a 0

goto $-.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 instrucción nueva decfsz, esta instrucción es equivalente a decir:

Decrementa el registro f y salta si ha llegado a 0

Es una instrucción 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: ¿Cómo calculo el tiempo que durará un retardo?

Muy bien, observemos esta parte del código ensamblador:

decfsz CONTA_1,F ; CONTA_1 � CONTA_1 -1 y salta si ya llego a 0

goto $-.1 ;NO ha llegado a 0, entonces vuelve a decrementar

Nótese que esta parte es la que se ejecuta n veces hasta que CONTA_1 llega a 0, asi que solo

debemos saber cuánto tardan en ejecutarse estas dos instrucciones, luego lo multiplicamos

por n y el resultado es el tiempo que dura el retardo. La instrucción decfsz dura 1us y la

instrucción 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 código que se ejecuta repetitivamente hasta que CONTA_1 llega a 0 se llama

BUCLE.

Page 5: Retardos PIC en MPLAB

EJEMPLO:

Deseamos hacer un retardo de 100uS, entonces usamos el mismo código:

Inicio_retardo ;etiqueta para dar nombre al retardo

movlw d’n’ ; W � n

movwf CONTA_1 ; CONTA_1 � W

decfsz CONTA_1,F ; CONTA_1 � CONTA_1 -1 y salta si ya llego a 0

goto $-.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 cuánto 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 pequeño cambio al código

en ensamblador del retardo:

Inicio_retardo ;etiqueta para dar nombre al retardo

movlw d’100’ ; W � 100

movwf CONTA_1 ; CONTA_1 � W

nop

decfsz CONTA_1,F ; CONTA_1 � CONTA_1 -1 y salta si ya llego a 0

goto $-.2 ;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 instrucción nueva: nop, esta instrucción dura 1uS y la

operación que realiza es nula, es decir, no hace nada, entonces ¿para que la usamos? Observe

esta parte del código:

nop

decfsz CONTA_1,F ; CONTA_1 � CONTA_1 -1 y salta si ya llego a 0

goto $-.2 ;NO ha llegado a 0, entonces salta 2 instrucciones atras

Page 6: Retardos PIC en MPLAB

Note que esta parte del código 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 fórmula para nuestro retardo cambio:

Retardo = 4uS x n

Despejamos n y tenemos:

n = Retardo / 4uS ���� n = 100uS / 4uS = 25

Vemos como usando la instrucción nop el numero que cargamos a CONTA_1 es más exacto y

menor. Se puede ver la utilidad de esta instrucción que aparentemente era ociosa.

PREGUNTAS:

1) Realice un retardo que dure 1mS

2) ¿Cuanto es el Tiempo máximo que se genera sin la instrucción nop y cuanto con la

instrucción nop de los ejemplos anteriores?

3) ¿Es posible generar un retardo mayor agregando mas instrucciones nop?

-----------------------------------------------------------------------------------------------------------------------------

Respuestas

1)

Inicio_retardo ;etiqueta para dar nombre al retardo

movlw d’250’ ; W � 250

movwf CONTA_1 ; CONTA_1 � W

nop

decfsz CONTA_1,F ; CONTA_1 � CONTA_1 -1 y salta si ya llego a 0

goto $-.2 ;NO ha llegado a 0, entonces salta 2 instrucciones atras

------ -------- ;SI llego a 0 entonces FIN del retardo,sigue el programa

n = Retardo / 4 uS � n = 1000uS / 4uS = 250

2)

Sin el nop = 765uS, con el nop = 1025uS.

3)

Si es posible generar retardos más grandes de esa manera paro hay métodos más efectivos

para hacer retardos prolongados.

Page 7: Retardos PIC en MPLAB

Bucles anidados

Como hemos visto el retardo máximo 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_2 � (CONTA_2 – 1)

CONTA_2 = 0 ?

FIN

NO

SI

CONTA_1 � n

CONTA_1�CONTA_1-1

CONTA_1=0?

NO

Page 8: Retardos PIC en MPLAB

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 fórmula para el retardo simple de un solo bucle usando la instrucción nop era:

Retardo = n x 4uS

Utilizando dos bucles anidados la fórmula del retardo sería la siguiente:

Retardo = m x (n x 4uS)

Muy simple verdad. Veamos como se traduce a ensamblador:

Inicio_retardo

movlw d’m’ ; W � m

movwf CONTA_2 ; CONTA_2 � W

movlw d’n’ ; W � n

movwf CONTA_1 ;CONTA_1�W

nop ;no opera

decfsz CONTA_1,F ;CONTA_1�CONTA_1-1 y salta si llego a 0

goto $-.2 ;NO es 0, entonces salta al nop

decfsz CONTA_2,F ;SI es 0, entonces CONTA_2�CONTA_2 -1 y salta si llega a 0

goto $-.6 ;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 usábamos un retardo

simple de un bucle y la variable CONTA_1 le asignábamos 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

Page 9: Retardos PIC en MPLAB

Retardo de 10mS en ensamblador:

Inicio_retardo

movlw d’10’ ; W � m

movwf CONTA_2 ; CONTA_2 � W

movlw d’250’ ; W � n

movwf CONTA_1 ;CONTA_1�W

nop ;no opera

decfsz CONTA_1,F ;CONTA_1�CONTA_1-1 y salta si llego a 0

goto $-.2 ;NO es 0, entonces salta al nop

decfsz CONTA_2,F ;SI es 0, entonces CONTA_2�CONTA_2 -1 y salta si llega a 0

goto $-.6 ;No es 0, entonces regresa a cargar conta_1

------ -------- ;Si es 0, entonces fin del retardo y sigue con el programa

EJERCICIO:

Genere el código para hacer un retardo de 1 segundo.

Solución:

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 máximo 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 d’10’ ; W � m

movwf CONTA_2 ; CONTA_3 � W

movlw d’100’ ; W � m

movwf CONTA_2 ; CONTA_2 � W

movlw d’250’ ; W � n

movwf CONTA_1 ;CONTA_1�W

nop ;no opera

decfsz CONTA_1,F ;CONTA_1�CONTA_1-1 y salta si llego a 0

goto $-2 ;NO es 0, entonces salta al nop

decfsz CONTA_2,F ;SI es 0, entonces CONTA_2�CONTA_2 -1 y salta si llega a 0

goto $-6 ;No es 0, entonces regresa a cargar conta_1

decfsz CONTA_3,F ;SI es 0, entonces CONTA_2�CONTA_2 -1 y salta si llega a 0

goto $-10 ;No es 0, entonces regresa a cargar conta_1

------ -------- ;Si es 0, entonces fin del retardo y sigue con el programa

Retardo = 10 x (100 x (1mS)) = 1000mS = 1 segundo

Page 10: Retardos PIC en MPLAB

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 fácilmente y no tener que calcular tanto.

Retardos como subrutinas

Supongamos que deseamos hacer un programa para un led parpadeante, que encienda y

apague cada 1 segundo. El código en ensamblador seria asi:

Inicio_principal

bsf LED ;encendemos el LED

call Retardo_1s ;Llamamos a la subrutina Retardo_1s

bcf LED ;apagamos el LED

call Reatrdo_1s ;llamamos a la subrutina Retardo_1s

goto Inicio_principal ;Repetimos el ciclo

Retardo_1s ;Subrutina Retardo_1s

movlw d’10’ ; W � m

movwf CONTA_2 ; CONTA_3 � W

movlw d’100’ ; W � m

movwf CONTA_2 ; CONTA_2 � W

movlw d’250’ ; W � n

movwf CONTA_1 ;CONTA_1�W

nop ;no opera

decfsz CONTA_1,F ;CONTA_1�CONTA_1-1 y salta si llego a 0

goto $-.2 ;NO es 0, entonces salta al nop

decfsz CONTA_2,F ;SI es 0, entonces CONTA_2�CONTA_2 -1 y salta si llega a 0

goto $-.6 ;No es 0, entonces regresa a cargar conta_1

decfsz CONTA_3,F ;SI es 0, entonces CONTA_2�CONTA_2 -1 y salta si llega a 0

goto $-.10 ;No es 0, entonces regresa a cargar conta_1

return ;Si es 0, entonces fin del retardo y regresa

Las subrutinas son segmentos de código que se pueden ejecutar cada vez que el programa

principal las llame y cuando terminen de ejecutarse regresan a la siguiente posición de donde

fueron llamadas. La instrucción que las manda a llamar es CALL y la instrucción que regresa a

la siguiente posición 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 programación.

Page 11: Retardos PIC en MPLAB

Retardos como supresores de rebote

Sabemos que los elementos mecánicos como los pulsadores producen un efecto llamado

rebote. Cuando se presiona un botón este no se cierra idealmente, sino que antes de cerrarse

completamente “rebota” produciendo varios pulsos antes de cerrarse completamente. El

efecto de rebote suele durar menos de 20 ms. Los pulsos falsos debido al rebote suelen ser un

problema si se desea hacer un contador, ya que cuando se pulsa el botón para incrementar el

contador el contador no se incrementa en 1, sino en varias unidades, ¿Por qué? Pues porque

cuenta los pulsos falsos producidos por el rebote.

Los retardos son útiles supresores de rebote. Cuando se pulsa un botón se llama a un retardo

de aproximadamente 20ms, después del retardo de 20ms continua el programa, de esta

manera los pulsos de rebote no desaparecen pero son completamente omitidos.

EJEMPLO:

Explorar_boton

BTFSS PUSH ;exploramos el boton

GOTO explorar_boton ;no se presiono, entonces sigue explorarndo

CALL Retardo_20ms ;si se pulso, entonces demora de 20ms

INCF CONTADOR,F ;incrementa la variable CONTADOR

MOVF CONTADOR,W ;enviamos CONTADOR a PORTB para ver cuenta

MOVWF PORTB

GOTO explorar_contador ;repetir el ciclo

Retardo_20ms

movlw d’20’ ; W � m

movwf CONTA_2 ; CONTA_2 � W

movlw d’250’ ; W � n

movwf CONTA_1 ;CONTA_1�W

nop ;no opera

decfsz CONTA_1,F ;CONTA_1�CONTA_1-1 y salta si llego a 0

goto $-.2 ;NO es 0, entonces salta al nop

decfsz CONTA_2,F ;SI es 0, entonces CONTA_2�CONTA_2 -1 y salta si llega a 0

goto $-.6 ;No es 0, entonces regresa a cargar conta_1

return ;Si es 0, entonces fin del retardo y sigue con el programa

Page 12: Retardos PIC en MPLAB

TRUCOS

Existe un truco muy util llamado multiplicación 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 usaríamos seria la siguiente:

Retardo = W X Retardo_base

Por ejemplo, si se desea un retardo de 10 ms solo se haría lo siguiente:

movlw d’10’

call Retardo_x1ms

-----------------------------------------------------------------------------------------------------------------------------

Ejemplo:

.

.

movlw d’10’ ;W�10

call Retardo_x1ms ;Asi tendriamos un retardo de 10 x 1mS = 10mS

.

.

Retardo_x1ms ; subrutina Retardo x 1 ms

movwf CONTA_2 ; CONTA_2 � 10

movlw d’250’ ; W � 250

movwf CONTA_1 ;CONTA_1�W

nop ;no opera

decfsz CONTA_1,F ;CONTA_1�CONTA_1-1 y salta si llego a 0

goto $-.2 ;NO es 0, entonces salta al nop

decfsz CONTA_2,F ;SI es 0, entonces CONTA_2�CONTA_2 -1 y salta si llega a 0

goto $-.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 escribiríamos lo siguiente:

movlw d’3’

call Retardo_x100ms ;Retardo de 3 x 100ms = 300ms

movlw d’62’

call Retardo_x1ms ;Retardo de 62 x 1ms = 62ms