UNIVERSIDAD TECNOLÓGICA DEL PERÚ INGENIERÍA ELECTRÓNICA CIRCUITOS DIGITALES II: MICROCONTROLADORES
DOCENTE: ING. Luis Pacheco Cribillero
MICROCONTROLADOR PIC 16F84A: EJEMPLOS PARA MANEJO DE INTERRUPCIONES MÚLTIPLES – TMR0
1. Realicemos un programa completo que contenga varias interrupciones. Por ejemplo si la causa
ha sido la activación del pin RB0, se debe mostrar un número dos en binario en el puerto A. Si ha sido un cambio de nivel en RB4:RB7, se debe mostrar el uno en binario en el puerto A. Si se ha desbordado el TMR0, se debe mostrar el cuatro en binario en el puerto A.
SOLUCIÓN
LIST P=16F84A INCLUDE P16F84A.INC
W_TEMP equ 20H ; Se declaran los registros generales para ESTADO_TEMP equ 21H ; salvar los registros STATUS y W
org 00H goto INICIO org 04H ; Se coloca el vector interrupción para que se goto RUTINTERR ; Ejecute la rutina de interrupción
RUTINTERR movwf W_TEMP ; Se inicia a la rutina de servicio de interrupción
swapf W_TEMP,1 ; se salva el valor actual de W, el SWAPF es para no modificar ; los bits del registro de estado movf STATUS,0 ; se “toman” los bits de estado actuales (W STATUS) y movwf ESTADO_TEMP ; se guardan
;*** Exploramos los bits FLAGS del registro INTCON, uno a uno para ver si alguno se activó
btfsc INTCON,0 ; Se empieza exploración de causa de interrupción goto INTERRB47 ; Si RBIF=1, se va a ejecutar
btfsc INTCON,1 ; si no se hace este segundo testeo goto INTERRB0 ; Si INTF=1, se va a ejecutar btfsc INTCON,2 ; si no se hace este tercer testeo goto INTERRTMR ; Si TOIF=1, se va a ejecutar
goto SALIRINT ; Si no es ninguna, se sale de la interrupción SALIRINT bsf INTCON,7 ; Se habilita GIE, para permitir de nuevo otra
movf ESTADO_TEMP,0 ; Interrupción y se restaura el entorno, observa movwf STATUS ; como recuperamos el STATUS y swapf W_TEMP,0 ; el contenido de W, que había antes de …. Interr .. retfie ; El uso de return o retlw k, puede producir
; errores en la ejecución del programa ;********************************************** ;*** Subrutina de tratamiento de cambio de RB4:RB7 *** ;********************************************** INTERRB47 bcf INTCON,0 ; apagamos RBIF
movlw 01H ; mandamos a mostrar lo pedido movwf PORTA ; por el PORTA movf PORTB,0 ; Ver NOTA (1) bcf INTCON,0 ; Se borra por software el señalizador de esta goto SALIRINT ; Interrupción
;************************************************ ;*** Subrutina de tratamiento de activación de INT/RB0 *** ;************************************************ INTERRB0 movlw 02H ; carga dato a mostrar
movwf PORTA ; y lo envía por el PORTA
UNIVERSIDAD TECNOLÓGICA DEL PERÚ INGENIERÍA ELECTRÓNICA CIRCUITOS DIGITALES II: MICROCONTROLADORES
DOCENTE: ING. Luis Pacheco Cribillero
bcf INTCON,1 ; Se borra por software el señalizador goto SALIRINT
;********************************************** ;*** Subrutina de tratamiento del desborde del TMR0 *** ;********************************************** INTERRTMR movlw 04H ; cargamos el valor a mostrar
movwf PORTA ; y lo enviamos por el PORTA movlw d'01' ; Se carga el valor calculado para el TMR0 movwf TMR0 ; para asegurarnos que al regresar tenga este valor bcf INTCON,2 ; Se borra el señalizador goto SALIRINT
;************************* ;***PROGRAMA PRINCIPAL*** ;************************* INICIO bsf STATUS,5
clrf PORTA ; PORTA como entrada movlw 0FFH movwf PORTB ; PORTB como entrada movlw b'01000110' movwf OPTION_REG ; Diga: ¿Cómo se configuró OPTION? bcf STATUS,5 movlw b'10111000' ; Se habilita GIE y las interrupciones movwf INTCON ; Individuales
DORMIR nop movlw d'01' movwf TMR0
SINFIN CLRWDT goto SINFIN ; Se coloca al microcontrolador en bucle o lazo sin fin end
; NOTA (1): En este tipo de interrupción, internamente el procesador lee el nibble alto del puerto B y hace una copia. ; La interrupción se genera cuando la lectura del nibble alto del puerto B es diferente de la copia. Dentro de ; la ejecución de esta rutina de interrupción, es importante que se lea el puerto B, para actualizar la copia, y ; el procedimiento adecuado es el mostrado anteriormente. 2. Se pide escribir un programa que genere una señal cuadrada de 200 Hz. Diseño libre.
Paso 1. Enunciado y delimitación del problema:
Como no se ha especificado por cual pin del microcontrolador saldrá la señal, asumiremos RB0.
Cuando se trabaja con el Timer 0, se deben incluir los cálculos que se hayan realizado para generar el
retardo deseado. Para una frecuencia de 200 Hz, tendremos un período de:
Como no se ha especificado el ciclo de trabajo, asumiremos el 50 %, por lo que el período en alto y en bajo
serán iguales, es decir 2,5 ms. Hagamos los cálculos para 2,5 ms:
De la fórmula proporcionada, despejando nos quedará:
Sustituyendo los valores (Como no se nos especificó el oscilador, asumiremos el estándar de 4 MHz:
UNIVERSIDAD TECNOLÓGICA DEL PERÚ INGENIERÍA ELECTRÓNICA CIRCUITOS DIGITALES II: MICROCONTROLADORES
DOCENTE: ING. Luis Pacheco Cribillero
Por lo que el valor a cargar en el TMR0= 217 Paso 2. Hacemos un diagrama de flujo, en este caso mostramos 2 formas de encarar el problema:
UNIVERSIDAD TECNOLÓGICA DEL PERÚ INGENIERÍA ELECTRÓNICA CIRCUITOS DIGITALES II: MICROCONTROLADORES
DOCENTE: ING. Luis Pacheco Cribillero
FORMA A. POR EXPLORACIÓN (POLLING) DEL BIT TOIF:
LIST P=16F84A INCLUDE P16F84A.inc org 00H goto INICIO
;*************************** ;***PROGRAMA PRINCIPAL*** ;*************************** INICIO bsf STATUS,5 ; Zona de configuraciones
clrf TRISB movlw B'00010101' ; Predivisor= 128 movwf OPTION_REG bcf STATUS,5 clrf PORTB ; Inicializamos el Puerto B nop
CICLO bsf PORTB,0 ; Señal a nivel alto call DELAY2_5MS ; Llamamos subrutina 2,5 ms bcf PORTB,0 ; Señal a nivel bajo call DELAY2_5MS ; Llamamos subrutina 2,5 ms goto CICLO ; Repetimos ciclo
DELAY2_5MS movlw .217 ; Cargamos TMR0 con valor movwf TMR0 ; calculado previamente bcf INTCON,2 ; Borramos el señalizador
ESPERA btfss INTCON,2 ; Se desbordó el TMR0? goto ESPERA ; No. Seguimos esperamos return ; Si, han transcurrido 2,5 ms end
FORMA B. POR INTERRUPCIÓN
LIST P=16F84A INCLUDE P16F84A.inc org 00H goto INICIO org 04H goto RSI
;******************************** ;***RUTINA DE INTERRUPCIÓN*** ;******************************** RSI bcf INTCON,7 ; Deshabilitamos las interrupciones
btfss INTCON,2 ; La causa de la interrupción es desborde ; del TIMER0 TOIF=1?
goto SALIR ; No, Salimos bcf INTCON,2 ; Si, borramos el señalizador TOIF movlw .01 xorwf PORTB,1 movlw .217 ; Cargamos el valor del TMR0 movwf TMR0 ; Para una nueva temporización
SALIR bsf INTCON,7 ; Habilitamos las interrupciones retfie
;*************************** ;***PROGRAMA PRINCIPAL*** ;*************************** INICIO bsf STATUS,5
clrf TRISB movlw B'00010101' ;Predivisor= 128 movwf OPTION_REG
UNIVERSIDAD TECNOLÓGICA DEL PERÚ INGENIERÍA ELECTRÓNICA CIRCUITOS DIGITALES II: MICROCONTROLADORES
DOCENTE: ING. Luis Pacheco Cribillero
movlw B'10100000' ; Habilitamos las interrupciones movwf INTCON ; Con GIE=1 y TOIE=1 bcf STATUS,5 clrf PORTB ; Inicializamos el Puerto B movlw .217 ; Cargamos el TMR0 con el movwf TMR0 ; valor previamente calculado
SINFIN clrwdt ; Usamos esta instrucción para goto SINFIN ; evitar reinicio del programa
; De resto, el programa se queda en este bucle sin fin esperando el desborde ; del TMR0, que ocurrirá según sea el tiempo calculado.
end Nota: Generalmente cuando los puertos A y/o B pueden sufrir modificaciones dentro de la rutina de
interrupción, se salva el entorno, sin embargo para este ejemplo, no se modifican otros bits de los puertos, por lo que no es necesario salvar el entorno.