Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 6

7.

Subrutinas Una subrutina o subprograma es una parte de programa que hace algo concreto y se repite a menudo, para ahorrar memoria y esfuerzo y para hacer el programa mas comprensible se agrupa en forma de subrutina. Una subrutina se debe ejecutar siempre llamndola con la instruccin CALL y al final de dicha subrutina debe haber siempre un RETURN. El esquema de la derecha muestra como funcionan las subrutinas: Durante el programa principal se llama varias veces a la subrutina SUBR (el nombre es lo de menos) con la instruccin CALL. Cuando el pic ejecuta una instruccin CALL se guarda en memoria la direccin de cdigo de programa a la que tiene que retornar de tal forma que cuando se encuentra con la instruccin RETURN vuelve al programa principal donde lo dej. Una subrutina no solo puede ser llamada desde el programa principal, tambin puede hacerse desde otra subrutina (una subrutina que llama a otra subrutina) o desde una interrupcin (enseguida las veremos). El siguiente ejemplo muestra un programa que utiliza una subrutina de retardo a la que llama DELAY. Esta subrutina de retardo se hace decrementando el registro CUENTA2 desde FFh hasta 00h 16 veces (las veces que se decrementa CUENTA2 son contadas hacia atrs por CUENTA1) De esta forma se consigue perder tiempo (el tiempo perdido con esta subrutina depende de la frecuencia a la que opere el pic)
;********************************** ;* Este programa configura RB0 como salida* ;* y genera una intermitencia en dicha * ;* salida * ;********************************** STATUS TRISB PORTB CUENTA1 EQU EQU EQU EQU 0CH 03H 06H 06H ;Las variables que usemos siempre a

;partir de la direccin 0Ch CUENTA2 F w EQU EQU EQU 0DH 1 0

ORG BSF BCF BCF INICIO CALL BCF CALL GOTO

00H STATUS,5 TRISB,0 STATUS,5 BSF TRISB,0 DELAY TRISB,0 DELAY INICIO

;banco 1 ;RB0 como salida ;banco 0 ;Pone a "1" RB0 (enciende) ;Llama a la subrutina de retardo ;Cuando vuelve del retardo pone ;a "0" RB0 (apaga) ;llama a la subrutina de retardo ;cuando vuelve del retardo ;ejecuta el GOTO

;=================================================== ;= DELAY: Subrutina de retardo = ;= Modifica los siguientes registros: = ;= CUENTA1 = ;= CUENTA2 = ;= ACUMULADOR = ;= STATUS = ;(Conviene hacerse un pequeo resumen de lo que ;hace cada subrutina, puede sernos muy til para ;usarla en otros programas) DELAY MOVWF acumulador ACA1 FFH MOVWF acumulador ACA resultado siguiente GOTO ACA ;instruccin ;vuelve a decrementar mientras ;CUENTA2 no sea cero MOVLW CUENTA1 010H ;Carga el acumulador con el valor ;10H (16 en decimal) ;Mueve el contenido del ;a CUENTA1 ;Carga el acumulador con el valor ;Mueve el contenido del

MOVLW 0FFH CUENTA2

;a CUENTA2 DECFSZ CUENTA2,F ;Decrementa CUENTA2, guarda el ;en f, y si es cero se salta la

DECFSZ que GOTO recarga RETURN

CUENTA1,F

;Se decrementa CUENTA1 cada vez ;CUENTA2 llega a cero ;mientras CUENTA1 no llegue a cero ;CUENTA2 y repite el proceso ;retorna al programa principal

ACA1

;= = ;= FIN DE LA SUBRUTINA DELAY = ;=========================== END ;Fin del programa

Interrupciones Cuando se produce una interrupcin el pic deja automticamente lo que est haciendo, va directo a la direccin 04h de programa y ejecuta lo que encuentre a partir de all hasta encontrarse con la instruccin RETFIE que le har abandonar la interrupcin y volver al lugar donde se encontraba antes de producirse dicha interrupcin. Para que se pueda producir una interrupcin hay que habilitar las interrupciones globalmente y la interrupcin en concreto que queremos utilizar (con el registro INTCON). Este pic tiene 4 tipos de posibles interrupciones:
1. 1. 2. 3. 4.

Por cambio en los bits RB4-RB7 Por el estado de RB0 Por desbordamiento del Timer-contador Por fin de ciclo de escritura de la EEPROM de datos

Mientras se est ejecutando una interrupcin no se puede producir otra interrupcin, el pic no lo permite. Una cosa importante a tener en cuenta al usar interrupciones es que cuando estas se producen podramos estar trabajando con registros que pueden ser modificados en la propia interrupcin, como el acumulador o el STATUS. Para que la interrupcin no eche a perder el buen funcionamiento del programa principal conviene guardar los valores de estos registros en otras variables que no vayamos a modificar. Antes de salir de la interrupcin volvemos a restaurar los valores guardados y todo solucionado. El siguiente ejemplo muestra un programa que usa la interrupcin por cambio en el puerto B (En pines RB4 a RB7)

;******************************************* ;* Este programa invierte el estado del pin* ;* RA0 cada vez que se modifica el estado * ;* de alguno de los pines RB4, RB5, RB6 o * ;* RB7. Para ello habilita la interrupcin * ;* por cambio de RB4-RB7 * ;*******************************************

STATUS EQU 03H TRISA EQU 05H PORTA EQU 05H TRISB EQU 06H PORTB EQU 06H INTCON EQU 0BH ACUM EQU 0CH STAT EQU 0DH F EQU 1 w EQU 0 #DEFINE BANCO0 BCF STATUS,5 #DEFINE BANCO1 BSF STATUS,5

ORG 00H GOTO INICIO poner de

;ponemos este GOTO al principio para poder ;el subprograma de las interrupciones a partir ;la direccin 04h

;Comienza la interrupcin: ;========================= ORG 04H BCF INTCON,0 recuerda que ;El pic salta a esta direccin cuando se produce ;una interrupcin ;bit que indica un cambio en RB4-RB7, ;hay que ponerlo a "0" por programa, este es el ;momento ;comenzamos guardando el contenido del acumulador ;y del STATUS para restaurarlos antes de salir de ;la interrupcin (es recomendable hacer esto ;siempre que se usen interrupciones)

MOVWF ACUM MOVF STATUS,W BANCO0 MOVWF STAT

;Copia el acumulador al registro ACUM ;Guarda STATUS en el acumulador ;Por si acaso, nunca se sabe en que parte de ;programa principal salta la interrupcin ;Copia el acumulador al registro STAT

;Invertimos el estado de RA0: ;============================ BTFSC PORTA,0 GOTO ESUNO BSF PORTA,0 GOTO HECHO ESUNO BCF PORTA,0 ;si RA0 es "0" salta la siguiente instruccin ;vete a ESUNO ;Pon a "1" RA0 (porque era "0") ;ya est invertido RA0, vete a HECHO ;Pon a "0" RA0 (Porque era "1")

;Ya se ha invertido el estado de RA0 ;=================================== ;ahora hay que restaurar los valores del STATUS y ;del acumulador antes de salir de la interrupcin: HECHO MOVF STAT,W acumulador MOVWF STATUS SWAPF ACUM,F SWAPF ACUM,W restaura para no ;alterar el STATUS, la instruccin MOVF altera el RETFIE ;bit 2 del STATUS) ;fin de la interrupcin ;Fin de la interrupcin ;====================== ;Guarda el contenido de STAT en el ;Restaura el STATUS ;Da la vuelta al registro ACUM ;Vuelve a dar la vuelta al registro ACUM y ;el acumulador (Con la instruccion SWAPF

INICIO BANCO1 MOVLW 0FFH MOVWF TRISB entradas BCF TRISA,0 BANCO0

;Pasamos al banco 1 ;Todos los bits del acumulador a "1" ;configuramos todo el puerto B como ;RA0 como salida ;Volvemos al banco 0 ;Configuracin de las interrupciones:

;==================================== BSF INTCON,7 BSF INTCON,3 puerto B ;Habilita las interrupciones globalmente ;Habilita la interrupcin por cambio de

;==================================== ;ya estn configuradas las interrupciones, a ;partir de ahora cuando haya un cambio en RB4RB7 ;saltar la interrupcin (a la direccin 04h de ;programa) NADA GOTO NADA programa salte la ;interrupcin. La verdadera utilidad de las ;interrupciones es que se pueden hacer "cosas" ;mientras sin preocuparse de la interrupcin ;En este ejemplo no se hace nada en el ;principal, simplemente se espera a que

END

;FIN DE PROGRAMA

También podría gustarte