Saludos, es muy cierto que en esta gama sólo hay un vector de interrupción a la cual todas las interrupciones acceden
La solución
es hacer una rutina que evalue una a una las posibles interrupciones habilitadas en nuestro programa y atenderlas por orden de prioridad
Por ejemplo, si en nuestro programa sólo deseamos tener interrupciones por desbordamiento del TMR0 (T0IE=1) y por cambio de estado en PORTB (RBIE=1), además de habilitar el permiso general de interrupciones (GIE=1) y borrar los respectivos FLAGS de las mismas (T0IF=0 y RBIF=0). Ahora debemos de dar prioridades de atención y para nuestro ejemplo TMR0 será la de mayor importancia, seguida por RBIE y así sucesivamente si tuvieramos más interrupciones. El código que se muestra, es la estructura que sigo para atender las fuentes de interrupción.
Codigo:
; VECTOR DE INTERRUPCION
ORG 4
MOVWF W_TEMP ;SALVO EL REGISTRO W
SWAPF STATUS,W
MOVWF STATUS_TEMP ;SALVO EL REGISTRO STATUS
CLRF STATUS ;TRABAJO EN BANK 0
MOVFW PCLATH ;SALVO EL REGISTRO PCLATH
MOVWF PCLATH_TEMP
CLRF PCLATH
; EXPLORANDO QUE FLAG ACTIVO LA INT.
OTHER_INT1
BTFSS INTCON,TOIF ;INT POR TMR0
GOTO OTHER_INT2
BCF INTCON,TOIF ;BORRAMOS FLAG
-
-
-
-
OTHER_INT2
BTFSS INTCON,RBIF
GOTO SALIR
BCF INTCON,RBIF ;BORRAMOS FLAG
-
-
-
-
SALIR
MOVFW PCLATH_TEMP
MOVWF PCLATH
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
RETFIE
Supongamos este primer evento... nuestro programa se está ejecutando y de pronto sólo el TMR0 se desborda. En este caso se activará su respectivo FLAG (T0IF=1) haciendo que el programa salte a la dirección 0x04 para atender la interrupcíón; a su vez se desabilita GIE=0 lo que no quiere decir que si por algún motivo ocurra otra posible "interrupción" no deje de activarse su respectivo FLAG. Aquí debemos verificaremos si es que realmente ocurrió la interrupción revisando el estado de su respectivo FLAG, luego borramos su FLAG para que no origine una falsa interrupción a la hora de salir de esta rutina, después procedemos a realizar el código para esa interrupción. Por último, verificamos las demás fuentes de posibles interrupciones por si alguna se originó durante el análisis de la primera. Al ejecutar el comando RETFIE habilitamos nuevamente GIE=1 para permitir que el programa salte nuevamente a la posición 0x04 cuando se ejecute alguna interrupción.
Ahora supongamos este segundo evento... que las 2 fuentes de interrupción (T0IF = RBIF = 1) se activen al mismo tiempo. Al igual que en el primer caso, el programa saltará a la posición 0x04 y GIE=0, pero la prioridad de atención a las interrupciones se ejecutará de acuerdo a como lo estabecimos en nuestra rutina, y para nuestro ejemplo sería primero TMR0 y por último RB. Siempre se verificará el estado del FLAG y se borrará por software para que no origine falsas interrupciones al salir de la rutina de servicio de interrupciones.
Como último evento... que sólo se active la interrupción por RB, en este caso se evalúa el FLAG de TMR0 y al encontrarse en 0 saltará para atender la interrupción que origino el salto del programa.
Bueno espero haber sido claro en esta explicación y no haberlos confundido