El microcontrolador té la possibilitat que alguns esdeveniments facin una interrupció al programa. Quan hi ha una interrupció, el microcontrolador deixa el que estava fent i executa el programa d'interrupció; quan acaba la funció d'interrupció (instrucció retfie), torna on estava i segueix el que estava fent.
Podem activar o desactivar individualment les interrupcions provinents de cada un dels elements que en poden generar. Addicionalment, podem habilitar o deshabilitar les interrupcions de forma global. El bit GIE del registre INTCON controla globalment les interrupcions. També caldrà activar la interrupció concreta al registre corresponent. La següent taula conté els registres que controlen les interrupcions més destacades. Els bits de control són els que permeten activar (quan estan a 1) o desactivar la interrupció. Les banderes són les que ens permeten saber quina interrupció és lque s'ha activat (i cal desactivar-les manualment).
Important: La interrupció del microcontrolador es produeix quan està activada la bandera corresponent a una interrupció activada i està activat el bit GIE. Això vol dir que si quan activem el bit GIE hi ha alguna bandera activada la interrupció es produirà immediatament. El microcontrolador no gestiona la desactivació de les banderes sinó que les hem de desactivar en el nostre programa un cop les hem consultat.
| Registre | Núm. bit | Adreça bit | Funció |
| INTCON | 7 | GIE | Activació global de les interrupcions |
| 6 | PEIE | Activació de les interrupcions per perifèrics (Controlats pels registres PIE1 i PIE2) |
|
| 5 | T0IE | Activació de la interrupció per Timer 0 | |
| 4 | INTE | Activació de la interrupció externa (RA2)★ | |
| 3 | RABIE | Activació de la interrupció per canvis als ports A i B★ (Controlats pels registres IOCA i IOCB) |
|
| 2 | T0IF | Bandera de la interrupció per Timer 0 | |
| 1 | INTF | Bandera de la interrupció externa (RA2) | |
| 0 | RABIF | Bandera de la interrupció per canvis als ports A i B⦿ | |
| PIE1 | 6 | ADIE | Activació de les interrupcions per conversor A/D |
| 5 | RCIE | Activació de les interrupcions per recepció de la comunicació sèrie asíncrona | |
| 4 | TXIE | Activació de les interrupcions per emissió de la comunicació sèrie asíncrona | |
| 3 | SSPIE | Activació de les interrupcions per la comunicació sèrie síncrona | |
| 2 | CCP1IE | Activació de les interrupcions per capturador/comparador | |
| 1 | TMR2IE | Activació de les interrupcions per timer 2 | |
| 0 | TMR1IE | Activació de les interrupcions per timer 1 | |
| PIE2 | 7 | OSFIE | Activació de les interrupcions per fallada de l'oscil·lador |
| 6 | C2IE | Activació de les interrupcions per comparador C2 | |
| 5 | C1IE | Activació de les interrupcions per comparador C1 | |
| 4 | EEIE | Activació de les interrupcions per EEPROM | |
| PIR1 | 6 | ADIF | Bandera de la interrupció per conversor A/D |
| 5 | RCIF | Bandera de la interrupció per recepció de la comunicació sèrie asíncrona | |
| 4 | TXIF | Bandera de la interrupció per emissió de la comunicació sèrie asíncrona | |
| 3 | SSPIF | Bandera de la interrupció per la comunicació sèrie síncrona | |
| 2 | CCP1IF | Bandera de la interrupció per capturador/comparador | |
| 1 | TMR2IF | Bandera de la interrupció per timer 2 | |
| 0 | TMR1IF | Bandera de la interrupció per timer 1 | |
| PIR2 | 7 | OSFIF | Bandera de la interrupció per fallada de l'oscil·lador |
| 6 | C2IF | Bandera de la interrupció per comparador C2 | |
| 5 | C1IF | Bandera de la interrupció per comparador C1 | |
| 4 | EEIF | Bandera de la interrupció per EEPROM | |
| OPTION_REG | 6 | INTEDG | Si està activat la interrupció externa és a l'activació Si està desactivat és a la desactivació. |
| IOCA | 0 a 5 | IOCA0 a IOCA5 | Si està activat el bit, la pota corresponent del port A farà interrupcions (a l'activar-se i al desactivar-se) |
| IOCB | 4 a 7 | IOCB4 a IOCB7 | Si està activat el bit, la pota corresponent del port B farà interrupcions (a l'activar-se i al desactivar-se) |
★ Cal que l'entrada implicada no estigui configurada com a analògica.
⦿ Cal tenir present que la bandera RABIF s'activa quan la darrera lectura del port no es correspon amb el valor actual. Si desactivem la bandera sense haver llegit encara el port ens trobarem que es torna a activar immediatament. Cal, doncs, llegir el port abans de desactivar la bandera.
Important: Atès que el PIC16F690 només pot tenir una funció d'interrupció, el més habitual és que dins d'aquesta es miri si està activat el bit corresponent a cada una de les interrupcions que es fan servir en el programa (T0IF, RABIF, TMR1IF, etc.) i, si ho està, es faci el que correspon. Això pot donar algun conflicte quan el programa fa servir diverses interrupcions que no estan sembre activades. Per exemple, imaginem un programa que fa servir Timer 1 i RA5 com a fonts d'interrupció i en un moment determinat estan desactivades les interrupcions per Timer 1 (TMR1IF) però el temporitzador segueix en marxa. Quan hi hagi una interrupció per RA5 (s'activi RABIF) es farà el que toca per aquesta interrupció però si també està activat TMR1IF també es farà la part corresponent; encara que la interrupció per Timer 1 estigui desactivada (TMR1IE desactivat). En alguns casos (com en els temporitzadors 1 i 2) és possible desactivar la font de les interrupcions (TMR1ON i TMR2ON) però en altres casos (com el temporitzador 0 o les interrupcions per entrades) això és més complicat o impossible. Per això és recomanable que la funció d'interrupció miri si estan activats simultàniament el bit de control de la interrupció (TMR1IE) i el que indica que s'ha produït l'esdeveniment (TMR1IF).
Interrup:
...
btfss RABIE ; Mira si la interrupció per canvis als ports està activada
; Si ho és, no fa la instrucció següent
goto NoRAB ; Si la interrupció no és per ports, saltem
btfss RABIF ; Mira si la interrupció és per canvis als ports
; Si ho és, no fa la instrucció següent
goto NoRAB ; Si la interrupció no és per ports, saltem
RAB: ; Programa corresponent a canvi als ports
...
NoRAB:
btfss TMR1IE ; Mira si la interrupció per timer 1 està activada
; Si ho és, no fa la instrucció següent
goto FiInt ; Si la interrupció no és per timer 1, saltem
btfss TMR1IF ; Mira si la interrupció és per timer 1
; Si ho és, no fa la instrucció següent
goto FiInt ; Si la interrupció no és per timer 1, saltem
...
FiInt:
...
retfie ; Torna al programa principal, on s'havia quedat
Atès que la interrupció pot venir en qualsevol moment, ens podem trobar que el programa d'interrupció ens modifiqui registres que poden ser importants per tal que el programa principal segueixi en la forma correcta. Cal doncs guardar una còpia d'aquests registres en una altra part de la memòria. Així doncs al començament del programa d'interrupció guardarem els registres i al final del programa els tornarem a copiar al seu lloc. Com el microcontrolador té quatre bancs de registres, podríem equivocar-nos si durant la funció d'interrupció es canvia a un altre banc o si en el moment de la interrupció no estàvem al banc esperat. Per evitar problemes, el millor és guardar aquests registres en una part de memòria que és físicament la mateixa en tots els bancs. Si mirem l'estructura dels registres, veurem que això passa a les adreces 70h a 7Fh (que si s'adrecen com F0h-FFh, 170h-17Fh o 1F0h-1FFh estan adreçant exactament el mateix registre físic).
La funció d'interrupció modificarà sempre, com a mínim, dos registres, W i STATUS, ja que els modifiquen la majoria de les instruccions. Al començar el programa o funció d'interrupció guardarem aquests valors i quan acabem la funció d'interrupció hem de recuperar els valors dels registres. Per recuperar STATUS (o altres variables) hem de fer servir l'acumulador W ja que no podem moure directament les variables; per tant cal recuperar primer STATUS i les altres variables i deixar W per al final. Si recuperéssim W amb MOVF ens trobaríem que segons el valor que tingués ens canviarien els bits d'estat (C, DC i Z) a STATUS. Hem de fer servir una funció per copiar que no canviï els bits d'estat: swapf. Així per copiar el valor guardat a W primer permutarem els nibbles sobre l'adreça on està guardat i després els tornarem a permutar guardant el resultat a W. Així aconseguim copiar el valor sense que, per exemple, ens variï Z.
; Zona de memòria que no depèn del banc triat W_Copia EQU 0x70 ; Guardarà el contingut de W durant la interrupció ST_Copia EQU 0x71 ; Guardarà STATUS durant la interrupció
Interrup:
movwf W_Copia ; Copiem l'acumulador a W_Copia
swapf STATUS,w ; Copiem STATUS a l'acumulador permutant els nibbles
clrf STATUS ; Posa a 0 i així segur que el banc és el 0
movwf ST_Copia ; Guarda STATUS permutat a ST_Copia
...
FiInt:
swapf ST_Copia,w ; Copia permutant ST_Copia a l'acumulador
movwf STATUS ; I ho passa a STATUS recuperant el valor d'abans
; de la interrupció
swapf W_Copia,f ; Permuta els bits de W_Copia
swapf W_Copia,w ; Torna a permutar els bits de W_Copia
; i els guarda a l'acumulador sense variar STATUS
retfie ; Torna al programa principal, on s'havia quedat
La memòria de programa té dues adreces reservades. L'adreça 000h és on comença a executar després de posar en marxa el microcontrolador i l'adreça 004h és on comença a executar quan hi ha una interrupció. Com entre 000h i 003h no ens hi cap el programa, el que farem serà el que es mostra a la figura següent.

Quan es volen desactivar les interrupcions des de fora de la funció d'interrupció, cal tenir present que existeix la remota possibilitat que aparegui una interrupció en el mateix instant en el que es vol desactivar el bit GIE. Si això passés, les interrupcions no es desactivarien. Per evitar aquest problema, es pot comprovar la desactivació de GIE i repetir la desactivació si no s'ha fet:
... bcf GIE ; Desactiva les interrupcions momentàniament btfsc GIE ; Comprova si el bit s'ha desactivat goto $-2 ; Si no ho ha fet, torna-ho a provar ...
Quan el microcontrolador té activades dues o més interrupcions, pot succeir que se n'activin dues de simultànies o amb poca diferència de temps. Per això és recomanable que la funció d'interrupció comprovi tots els bits ja que si només fa el que correspon a la primera interrupció que troba, alguna altra pot quedar sense servir.
En programes que fan servir diverses interrupcions pot donar-se el cas que no ens interessi desactivar completament les interrupcions perquè hi pot haver una interrupció més prioritària. Llavors el normal és establir dos nivells de prioritat (a vegades tres). Quan hi ha una interrupció del nivell més baix es desactiven les interrupcions del mateix nivell i es mantenen activades les de nivell superior. En aquests casos cal preveure que la funció d'interrupció sigui interrompuda i, per tant, cal preveure tantes variables per guardar els registres crítics (W i STATUS) com nivells d'interrupció s'hagin definit.
A l'Exemple IT es fa servir una interrupció corresponent al Timer 0.
A l'Exemple IE es fa servir una interrupció externa.
A l'Exemple IR es fa servir una interrupció per canvi al port A.
La informació completa de les interrupcions la podeu trobar a l'apartat 14.3 del document de característiques del PIC 16F690.

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.