Las Subrutinas La Instrucción CALL El PIC 16f84, dentro de su set de instrucciones, y para llamar a las subrutinas, posee la instrucción CALL. Esta instrucción, lo que hace es guardar en la PILA, la dirección de retorno (que es la dirección siguiente a la que se encuentra la propia instrucción call) y luego salta a la dirección indicada en la instrucción CALL. La última instrucción que nos encontraremos en una subrutina debe ser una instrucción de retorno (RETURN ó RETLW). CCFF DPE MÓDULO DE PROYECTOS 2 La Instrucción CALL Las subrutinas, se deben colocar entre las primeras 256 posiciones de memoria, debido a que el bit 8 del PC se pone a 0 si se ejecuta un CALL o cualquier instrucción que modifique el valor del PC. Las ejecución de subrutinas, como cualquier programa, pueden modificar el contenido de los registros y con toda seguridad modificarán el contenido del registro de STATUS. Como ya se ha indicado anteriormente, la pila es una zona de RAM que escapa al control del programador, y en la cual no se pueden guardar contenidos de registros (esto es así para los PIC). CCFF DPE MÓDULO DE PROYECTOS 3 La Instrucción CALL ¾ Si tenemos en cuenta lo anterior, enseguida comprenderemos que al retornar de una subrutina los valores que nos encontraremos en ciertos registros estarán corruptos y no se podrán utilizar dentro del programa principal. Por lo tanto, lo primero que se debe hacer en el programa de atención a una subrutina es salvar los contenidos de los registros que serán modificados dentro de ella; para justamente antes de retornar podamos restaurar dichos registros con sus contenidos originales (antes de efectuar el call). Gráficamente sería como sigue: CCFF DPE MÓDULO DE PROYECTOS 4 Manejo De Una Pila Auxiliar Inicio Secuencia de Instrucciones para salvar los datos en la pila PUSH Instrucción Instrucción CALL SUB_1 Instrucciones propias de la subrutina Instrucción Instrucción Secuencia de Instrucciones para restaurar el valor a los registros S U B R U T I N A 1 POP Fin RETURN ó RETLW CCFF DPE MÓDULO DE PROYECTOS 5 Salvar y Restaurar Registros (1) A la vista del juego de instrucciones, salvar y restaurar los registros sin modificar sus contenidos no es fácil ya que este micro no posee las instrucciones PUSH y POP. Además el registro W debe salvarse el primero ya que todos los demás registros deben pasar por W para el almacenamiento temporal de sus valores. Microchip recomienda la siguiente secuencia de código que permite salvar y restaurar los registros sin modificarlos. CCFF DPE MÓDULO DE PROYECTOS 6 Salvar y Restaurar Registros (2) PUSH: MOVWF W_TEMP ; Copia W en TEMP register, esta instrucción ; no modifica el R. De STATUS SWAPF STATUS, W ; Swap R. De status y déjalo en W MOVWF STATUS_TEMP ; Salva status en el registro STATUS_TEMP ISR : : ; rutina de servicio a una interrupción ó cuerpo de subrutina : POP: SWAPF STATUS_TEMP, W MOVWF STATUS SWAPF W_TEMP, F SWAPF W_TEMP, W ; intercambia nibbles en el R. ; STATUS_TEMP y déjalo en W ; copia W en el R, STATUS ; Swap nibbles en W_TEMP y déja el ;resultado en W_TEMP ;Swap nibbles en W_TEMP ;y deja el resultado en W 7 Cálculo Del Tiempo de Ejecución de Una Subrutina (1) En numerosas ocasiones, se hace preciso calcular el tiempo que tarda en ejecutarse un programa, o bien se desea “entretener” el sistema un cierto tiempo para sincronizar algunos eventos. El tiempo de ejecución se puede calcular sumando el tiempo que tarda en ejecutarse el conjunto de instrucciones en estudio. En el caso particular de los PIC, cada instrucción excepto las de salto consumen un ciclo máquina, siendo el periodo de dicho ciclo máquina de 4 periodos de reloj. Si el reloj del sistema es de 4 Mhz, cada ciclo máquina ocupa justamente 1 µsegundo. Calculemos el tiempo que tarda en ejecutarse una típica rutina de retardo. CCFF DPE MÓDULO DE PROYECTOS 8 Diagrama De Flujo De La Subrutina RETARDO_1 Definir variables CONTA_1 = 00h Decrementa CONTA_1 NO CONTA_1 = 0? si RETORNO DE SUBRUTINA CCFF DPE MÓDULO DE PROYECTOS 9 Edición De La Subrutina (1) CCFF DPE MÓDULO DE PROYECTOS 10 Edición De La Subrutina (2) CCFF DPE MÓDULO DE PROYECTOS 11 Cálculo Del Tiempo de Ejecución de La Subrutina Analicemos la subrutina: 12 Cálculo Del Tiempo de Ejecución de La Subrutina Call RETARDO_1 Clrf CONTA_1 ;se ejecuta 1 vez y tarda 1 ciclo Decfsz CONTA_1,f ;1ciclo 255 veces y 2 ciclos 1 vez Goto lazo ;255 veces 2 ciclos cada vez Return ;1 vez 2 ciclos TOTAL DEL RETARDO : 770 CICLOS La fórmula para el cálculo del retardo sería: T= 255 x 3 ciclos +1 ciclo de clrf + 2 ciclos del último decfsz + 2 ciclos de return + 2 ciclos de call = 772 ciclos 13 Cálculo del Tiempo de Ejecución Una manera rápida de verificar el tiempo que tarda en ejecutarse una subrutina es ejecutándola en el simulador y utilizando el medidor de tiempos, junto con la opción de puntos de ruptura. CCFF DPE MÓDULO DE PROYECTOS 14 Subrutina de Temporización Mejorada (1) Partiendo de la subrutina tempo_1, vamos a intentar mejorarla, para ello el valor con que iniciaremos el contador será diferente de 0h, evidentemente a menor valor de este contador, el retardo será también menor. Desarrollemos el ordinograma de dicha subrutina: CCFF DPE MÓDULO DE PROYECTOS 15 Subrutina de Temporización Mejorada (1) RETARDO_1 Definir variables CONTA_1 = N h Decrementa CONTA_1 NO CONTA_1 = 0? si RETORNO DE SUBRUTINA CCFF DPE MÓDULO DE PROYECTOS 16 Subrutina de Temporización Mejorada (2) CCFF DPE MÓDULO DE PROYECTOS 17 Subrutina de Temporización Mejorada (3) CCFF DPE MÓDULO DE PROYECTOS 18 Subrutina de Temporización Mejorada (1) Partiendo de la subrutina tempo_1, vamos a intentar mejorarla, para ello el valor con que iniciaremos el contador será diferente de 0h, evidentemente a menor valor de este contador, el retardo será también menor. Desarrollemos el ordinograma de dicha subrutina: CCFF DPE MÓDULO DE PROYECTOS 19 Cálculo Del Tiempo de Ejecución de La Subrutina Analicemos la subrutina: CCFF DPE MÓDULO DE PROYECTOS 20 Cálculo Del Tiempo de Ejecución de La Subrutina Call TEMPO_1 movlw N movfw CONTA_1 decsz CONTA_1,f Goto LAZO Return ;1 vez 2 ciclos ;1 vez 1 ciclo ;1 vez 1 ciclo ;N-1 veces 1 ciclo + 1 vez 2 ciclos ;N-1 veces 2 ciclos ;1 vez 2 ciclos La fórmula para el cálculo del retardo sería: T= (N-1) x 3 ciclos +1 ciclo de movlw + 1 ciclo de movfw + 2 ciclos del último decfsz + 2 ciclos de return + 2 ciclos de call 21 Cálculo Del Tiempo de Ejecución de La Subrutina Siendo N el valor cargado en el registro que hace de contador y que se va decrementando. Hay que tener en cuenta que el valor mínimo de temporización sería cuando N = 1 (8 ciclos), mientras que el valor máximo se obtiene cuando N= 0 (773 ciclos) ya que al almacenarse N en un registro de 8 bits, N-1 = ffh = 255d. CCFF DPE MÓDULO DE PROYECTOS 22 Subrutinas Anidadas En algunas ocasiones, el tiempo de retardo que nos facilita una subrutina es insuficiente, en el caso anterior, el retardo máximo que hemos conseguido es de 773 µsegundos. Una manera de aumentar el tiempo de ejecución es anidar una subrutina dentro de otra. Veamos su diagrama de flujo: CCFF DPE MÓDULO DE PROYECTOS 23 Subrutinas Anidadas – Diagrama de Flujo RETARDO_1 Definir variables CONTA_1 = X h CONTA_2 = Y h Decrementa CONTA_1 NO CONTA_1 = 0? NO si CONTA_1 = X h Decrementa CONTA_2 CONTA_2 = 0? si RETORNO DE SUBRUTINA 24 Edición De La Subrutina CCFF DPE MÓDULO DE PROYECTOS 25 Edición De La Subrutina CCFF DPE MÓDULO DE PROYECTOS 26 Cálculo Del Tiempo De Ejecución : CCFF DPE MÓDULO DE PROYECTOS 27 Subrutinas Anidadas – Cálculo del tiempo de ejecución En primer lugar calculamos el tiempo de ejecución del lazo corto: decsz CONTA_1,f ;(X-1) veces 1 ciclo + 1 vez 2 ciclos Goto LAZO ;X-1 veces 2 ciclos Para un valor de X= 3 obtendríamos: T= 8 ciclos Las siguientes instrucciones: movlw X ;Y veces 1 ciclo movwf CONTA_1 ;Y veces 1 ciclo Tardan en ejecutarse 2 ciclos. Este bloque se ejecuta tantas veces como indique el lazo externo (Y veces) CCFF DPE MÓDULO DE PROYECTOS 28 Subrutinas Anidadas – Cálculo del tiempo de ejecución Analicemos ahora el bucle externo, que es el que multiplica al lazo corto : decsz CONTA_2,f ;(Y-1) veces 1 ciclo + 1 vez 2 ciclos Goto LAZO ;(Y-1) veces 2 ciclos Return ;1 vez 2 ciclos Además deberemos sumar los tiempos consumidos en: Call RETARDO-2 ;1 vez 2 ciclos movlw X ;1 vez 1 ciclo movwf CONTA_1 ;1 vez 1 ciclo movlw Y ;1 vez 1 ciclo movwf CONTA_2 ;1 vez 1 ciclo CCFF DPE MÓDULO DE PROYECTOS 29 Subrutinas Anidadas – Cálculo De Tiempos Call RETARDO_2 movlw X movwf CONTA_1 movlw Y movwf CONTA_2 decsz CONTA_1,f Goto LAZO movlw X movwf CONTA_1 decsz CONTA_2,f Goto LAZO Return ;1 vez 2 ciclos ;1 vez 1 ciclo ;1 vez 1 ciclo ;1 vez 1 ciclo ;1 vez 1 ciclo ;Y(X-1 veces 1 ciclo + 1 vez 2 ciclos) ;Y(X-1 veces 2 ciclos) ;Y veces 1 ciclo ;Y veces 1 ciclo ;(Y-1) veces 1 ciclo + 1 vez 2 ciclos ;(Y-1) veces 2 ciclos ;1 vez 2 ciclos CCFF DPE MÓDULO DE PROYECTOS 30 Subrutinas Anidadas – Cálculo De Tiempos Si expresamos lo anterior como fórmula obtendríamos la siguiente expresión: T= Y[3(X-1)+4]+3(Y-1)+10 Ó T = Y [3(X-1)+7]+7 Por ejemplo: X = Y = 250 El resultado debe ser 188507 ciclos máquina que con un reloj de 4Mhz daría 0.1885 segundos Lo anterior se puede calcular mediante el simulador. CCFF DPE MÓDULO DE PROYECTOS 31 Subrutinas Anidadas – Cálculo De Tiempos CCFF DPE MÓDULO DE PROYECTOS 32 Subrutinas Anidadas – Cálculo De Tiempos Repita el programa y realice la simulación para los siguientes valores: X = 31d, Y= 103d CCFF DPE MÓDULO DE PROYECTOS 33