Existen diferentes formas de realizar un retardo, lo importante es entender que un retardo se logra por medio de un lazo que
se repite varias veces, dentro de otro lazo que se repite otro numero de veces y así sucesivamente hasta alcanzar el tiempo
que necesitamos en nuestra aplicación, las formas sencillas normalmente son inexactas y pueden ser usadas cuando las
aplicaciones que estamos construyendo no requieren estrictamente el tiempo que nos piden.
Por ejemplo en nuestra primera actividad tenemos una sirena de 1seg, realmente nadie notaría la diferencia si la sirena
suena 0.8seg o 1seg. Pero en otros casos la exactitud es crítica, como en nuestra segunda práctica donde se quiere
controlar tiempo para activar una campana, o en aplicaciones de comunicaciones por ejemplo los retardos deben tener
exactitud intachable.
En éstos casos utilizamos algunas técnicas que nos toman mas tiempo pero garantizan mayor precisión en nuestros
proyectos.
Finalmente, luego de la creación del código se pueden usar herramientas como MPLAB para medir el tiempo exacto que
están registrando nuestros retardos.
Bueno, antes que se me duerman con ésta lectura entremos en materia:
Si utilizamos un cristal externo para el PIC de 4MHz tenemos que todas las instrucciones se ejecutan en 1uS porque cada
instrucción se toma 4 ciclos de reloj:
Ciclo de reloj: 1/4MHz: 0,00000025 segundos
4 Ciclos de reloj: 4 x 0,00000025= 0,000001 = 1uS
Cada línea que contenga instrucción (ejemplo: ptob equ 06) tarda 1 micro segundo en ejecutarse.
Exceptuando las instrucciones que tiene saltos que tardan 2 ciclos (decfsz por ejemplo), es decir 2uS. Tomando en cuenta
eso vamos a generar nuestros retardos, pero siempre partiendo de la suposición de que se esta trabajando a una frecuencia
de 4MHz, si es así, crear rutinas de retardo para nuestro pic es muy sencillo.
Supongamos que tenemos la siguiente rutina:
Tranquilos estas ecuaciones no muerden no salgan corriendo, necesitamos hallar N para que nuestro retardo sea de 100us.
A la derecha de cada instrucción aparece el número de ciclos que tomará cada una. Las primeras dos toman solamente 1
ciclo.
La tercera decfsz toma 1*(N-1)+2, porque decrementará N-1 veces la
variable N y en el último decremento hará un salto, es por eso el +2.
La instrucción goto se ejecuta en 2 ciclos y se ejecutará N-1 veces, es por
eso que se toma como 2*(N-1).
De esta forma tenemos que el número de ciclos, y por lo tanto el tiempo que
tendremos de retardo está dado por la siguiente expresión:
1 + 1 + (1)*(N-1)+2 + (2)*(N-1) , ó
4 + (N-1) + (2N-2) , o lo que es lo mismo
[3N+1]
Si queremos un retardo de 100uS entonces tenemos que 3N+1=100 porque:
100uS / 1uS que demora cada instrucción: 100
Despejando tenemos N=(100-1)/3=33, así que para tener un retardo de 100uS el valor de la variable N debe ser 33.
Ahora veamos esta rutina:
Podemos darnos cuenta que ahora nuestra rutina
original (desde CICLO2 hasta goto CICLO) está afectada
por la variable M, así que es como si M multiplicara a
nuestro retardo. Para saber el nuevo valor del retardo de
nuevo sumamos todos los ciclos, tomando en cuenta que
M multiplica al retardo original de modo que la expresión
ahora queda de la siguiente manera:
1 +1 + [3N+1]*M + (1)*(M-1)+2 + (2)*(M-1), ó
o lo que es lo mismo:
1 +1 + [3N+1]*M + M -1 +2 + 2M – 2 , ó
[3N+1]*M + 3M + 1
De manera que tenemos dos retardos anidados. Para saber cuanto sería el retardo total primero calculamos el retardo
básico, si queremos que ese retardo sea de 100uS entonces N=33, si ahora queremos que el retardo total sea de 10mS
entonces ocupamos completar 10000 ciclos(10mS) porque:
10mS/ 1uS que demora cada instrucción: 10000
Así que igualamos nuestra expresión a ese número:
[(3*33)+1]*M+3M+1=10000, despejando tenemos M=(9999)/103, esto es aproximadamente igual a 97, así que para un
retardo de 10mS nuestra variable N debe valer 33 y la variable M debe tener un valor de 97
Cansados? Yo también, pero ánimo si
entendemos esta parte no tendremos
mas dudas acerca de los retardos,
sigamos…
Así podemos seguir anidando retardos.
Para obtener un retardo de 1 segundo
utilizaremos la siguiente rutina.
Aquí vemos que la variable P afecta a
los dos retardos que ya habíamos
definido de modo que la expresión para
calcular el nuevo retardo total seria:
1 +1 + [[3N+1]*M + 3M + 1]*P + (1)*(P-1)+2 + (2)*(P-1) , ó
1 +1 + [[3N+1]*M + 3M + 1]*P + P-1+2 + 2P-2 , y reduciendo términos la expresión seria:
[[3N+1]*M + 3M + 1]*P + 3P + 1
Queremos un retardo de 1 segundo, esto son 1.000.000 ciclos porque:
1/ 1uS que demora cada instrucción: 1.000.000
Por lo que nuestra expresión del retardo debe ser igual a un millón: [[3N+1]*M + 3M + 1]*P +3P+1=1.000.000
Sustituyendo N y M tenemos 9995P+1=1000000, entonces tenemos que P=(999999)/9995 y P entonces es
aproximadamente igual a 100.
Al final nuestro retardo quedaría asi:
RETARDO MOVLW .100 ;1
MOVWF CONT3 ;1
CICLO3 MOVLW .97 ;1
MOVWF CONT2 ;1
CICLO2 MOVLW .33 ;1
MOVWF CONT ;1
CICLO DECFSZ CONT,F ;1*(N-1)+2
GOTO CICLO ;2*(N-1)
DECFSZ CONT2,F ;1*(M-1)+2
GOTO CICLO2 ;2*(M-1)
DECFSZ CONT3,F ;1*(P-1)+2
GOTO CICLO3 ;2*(P-1)
RETURN
Hoy en día existen infinidad de herramientas para crear el código donde solo tienes que ingresar la frecuencia del cristal (4MHz
en este caso) y el tiempo que necesitas del retardo y ahorrarte todos estos cálculos: he aquí algunos enlaces proporcionados por
los demás compañeros del curso:
http://www.piclist.com/cgi-bin/delay.exe
http://www.todopic.com.ar/utiles/calcular_retardos.zip
FIN
Fuente de información:
http://micropic.wordpress.com/2007/02/09/retardos-por-software/

Rutinas de retardo

  • 1.
    Existen diferentes formasde realizar un retardo, lo importante es entender que un retardo se logra por medio de un lazo que se repite varias veces, dentro de otro lazo que se repite otro numero de veces y así sucesivamente hasta alcanzar el tiempo que necesitamos en nuestra aplicación, las formas sencillas normalmente son inexactas y pueden ser usadas cuando las aplicaciones que estamos construyendo no requieren estrictamente el tiempo que nos piden. Por ejemplo en nuestra primera actividad tenemos una sirena de 1seg, realmente nadie notaría la diferencia si la sirena suena 0.8seg o 1seg. Pero en otros casos la exactitud es crítica, como en nuestra segunda práctica donde se quiere controlar tiempo para activar una campana, o en aplicaciones de comunicaciones por ejemplo los retardos deben tener exactitud intachable. En éstos casos utilizamos algunas técnicas que nos toman mas tiempo pero garantizan mayor precisión en nuestros proyectos. Finalmente, luego de la creación del código se pueden usar herramientas como MPLAB para medir el tiempo exacto que están registrando nuestros retardos. Bueno, antes que se me duerman con ésta lectura entremos en materia: Si utilizamos un cristal externo para el PIC de 4MHz tenemos que todas las instrucciones se ejecutan en 1uS porque cada instrucción se toma 4 ciclos de reloj: Ciclo de reloj: 1/4MHz: 0,00000025 segundos 4 Ciclos de reloj: 4 x 0,00000025= 0,000001 = 1uS Cada línea que contenga instrucción (ejemplo: ptob equ 06) tarda 1 micro segundo en ejecutarse. Exceptuando las instrucciones que tiene saltos que tardan 2 ciclos (decfsz por ejemplo), es decir 2uS. Tomando en cuenta eso vamos a generar nuestros retardos, pero siempre partiendo de la suposición de que se esta trabajando a una frecuencia de 4MHz, si es así, crear rutinas de retardo para nuestro pic es muy sencillo.
  • 2.
    Supongamos que tenemosla siguiente rutina: Tranquilos estas ecuaciones no muerden no salgan corriendo, necesitamos hallar N para que nuestro retardo sea de 100us. A la derecha de cada instrucción aparece el número de ciclos que tomará cada una. Las primeras dos toman solamente 1 ciclo. La tercera decfsz toma 1*(N-1)+2, porque decrementará N-1 veces la variable N y en el último decremento hará un salto, es por eso el +2. La instrucción goto se ejecuta en 2 ciclos y se ejecutará N-1 veces, es por eso que se toma como 2*(N-1). De esta forma tenemos que el número de ciclos, y por lo tanto el tiempo que tendremos de retardo está dado por la siguiente expresión: 1 + 1 + (1)*(N-1)+2 + (2)*(N-1) , ó 4 + (N-1) + (2N-2) , o lo que es lo mismo [3N+1] Si queremos un retardo de 100uS entonces tenemos que 3N+1=100 porque: 100uS / 1uS que demora cada instrucción: 100
  • 3.
    Despejando tenemos N=(100-1)/3=33,así que para tener un retardo de 100uS el valor de la variable N debe ser 33. Ahora veamos esta rutina: Podemos darnos cuenta que ahora nuestra rutina original (desde CICLO2 hasta goto CICLO) está afectada por la variable M, así que es como si M multiplicara a nuestro retardo. Para saber el nuevo valor del retardo de nuevo sumamos todos los ciclos, tomando en cuenta que M multiplica al retardo original de modo que la expresión ahora queda de la siguiente manera: 1 +1 + [3N+1]*M + (1)*(M-1)+2 + (2)*(M-1), ó o lo que es lo mismo: 1 +1 + [3N+1]*M + M -1 +2 + 2M – 2 , ó [3N+1]*M + 3M + 1 De manera que tenemos dos retardos anidados. Para saber cuanto sería el retardo total primero calculamos el retardo básico, si queremos que ese retardo sea de 100uS entonces N=33, si ahora queremos que el retardo total sea de 10mS entonces ocupamos completar 10000 ciclos(10mS) porque: 10mS/ 1uS que demora cada instrucción: 10000 Así que igualamos nuestra expresión a ese número: [(3*33)+1]*M+3M+1=10000, despejando tenemos M=(9999)/103, esto es aproximadamente igual a 97, así que para un retardo de 10mS nuestra variable N debe valer 33 y la variable M debe tener un valor de 97
  • 4.
    Cansados? Yo también,pero ánimo si entendemos esta parte no tendremos mas dudas acerca de los retardos, sigamos… Así podemos seguir anidando retardos. Para obtener un retardo de 1 segundo utilizaremos la siguiente rutina. Aquí vemos que la variable P afecta a los dos retardos que ya habíamos definido de modo que la expresión para calcular el nuevo retardo total seria: 1 +1 + [[3N+1]*M + 3M + 1]*P + (1)*(P-1)+2 + (2)*(P-1) , ó 1 +1 + [[3N+1]*M + 3M + 1]*P + P-1+2 + 2P-2 , y reduciendo términos la expresión seria: [[3N+1]*M + 3M + 1]*P + 3P + 1 Queremos un retardo de 1 segundo, esto son 1.000.000 ciclos porque: 1/ 1uS que demora cada instrucción: 1.000.000 Por lo que nuestra expresión del retardo debe ser igual a un millón: [[3N+1]*M + 3M + 1]*P +3P+1=1.000.000 Sustituyendo N y M tenemos 9995P+1=1000000, entonces tenemos que P=(999999)/9995 y P entonces es aproximadamente igual a 100.
  • 5.
    Al final nuestroretardo quedaría asi: RETARDO MOVLW .100 ;1 MOVWF CONT3 ;1 CICLO3 MOVLW .97 ;1 MOVWF CONT2 ;1 CICLO2 MOVLW .33 ;1 MOVWF CONT ;1 CICLO DECFSZ CONT,F ;1*(N-1)+2 GOTO CICLO ;2*(N-1) DECFSZ CONT2,F ;1*(M-1)+2 GOTO CICLO2 ;2*(M-1) DECFSZ CONT3,F ;1*(P-1)+2 GOTO CICLO3 ;2*(P-1) RETURN Hoy en día existen infinidad de herramientas para crear el código donde solo tienes que ingresar la frecuencia del cristal (4MHz en este caso) y el tiempo que necesitas del retardo y ahorrarte todos estos cálculos: he aquí algunos enlaces proporcionados por los demás compañeros del curso: http://www.piclist.com/cgi-bin/delay.exe http://www.todopic.com.ar/utiles/calcular_retardos.zip FIN Fuente de información: http://micropic.wordpress.com/2007/02/09/retardos-por-software/