Retardos por software en los microcontroladores PIC.

La semana pasada, en la segunda parte del tutorial 1, se habló un poco sobre los retardos por software.
Ahora vamos a ver esto de la lógica de los retardos un poco más a fondo para poder crear nuestras
propias subrutinas.
Como ya se dijo el pic 16F628A tiene un oscilador interno de 4MHz, si utilizamos ese oscilador
tenemos que todas las instrucciones se ejecutan en 1uS, exceptuando los saltos que tardan 2 ciclos, 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:

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 tecera decfsz toma (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, despejando tenemos N=(100-1)/3=33, asi que para tener un retardo
de 100uS el valor de la variable N debe ser 33. Ahora veamos esta rutina:

y funciona muy bien! .99 segundos pero no el segundo completo. utilizando los valores para las variables N. tomando en cuenta que M multiplica al retardo original de modo que la expresión ahora queda de la siguiente manera: [3N+1]M+1+1+(1)(M-1)+2+(2) (M-1). y reduciendo terminos la expresion seria [(3N+1)M+3M+1]P+3P+1. así que es como si M multiplicara a nuestro retardo.Podemos darnos cuenta que ahora nuestra rutina original (desde CICLO2 hasta goto CICLO) está afectada por la variable M. o lo que es lo mismo [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. Para obtener un retardo de 1 segundo utilizaremos la siguiente rutina: Aqui 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 [(3N+1)M+3M+1 ]P+1+1+(1)(P-1)+2+(2)(P-1). en tiempo esto es aproximadamente igual a 0. así que para un retardo de 10mS nuestra variable N debe valer 33 y la variable M debe tener un valor de 97. si queremos que ese retardo sea de 100uS entonces N=33. despejando tenemos M=(9999)/103. esto son 1000000 ciclos. por lo que nuestra expresión del retardo debe ser igual a un millón: [(3N+1)M+3M+1 ]P+3P+1=1000000. esto es aproximadamente igual a 97. así que igualamos nuestra expresión a ese número: [(3*33)+1]M+3M+1=10000. M y P que calculamos tenemos que al final del retardo solamente se realizaron 999501 ciclos. sin embargo para aplicaciones que no necesitan una gran precisión este metodo funciona. Sustituyendo N y M tenemos 9995P+1=1000000. entonces tenemos que P=(999999)/9995 y P entonces es aproximadamente igual a 100. Queremos un retardo de 1 segundo. si ahora queremos que el retardo total sea de 10mS entonces ocupamos completar 10000 ciclos. Esta no es la forma más precisa de realizar retardos. Así podemos seguir anidando retardos. Para saber el nuevo valor del retardo de nuevo sumamos todos los ciclos.