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ó, torna on estava i segueix el que estava fent.
La funció d'interrupció és una funció especial que no es crida enlloc del programa sinó que hi accedeix directament el microcontrolador. Hi ha dues possibles sintaxis:
void interrupt temporit(void){ // funció d'interrupcions
...
}
void __interrupt() temporit(void){ // funció d'interrupcions
...
}
El nom de la funció d'interrupció no té gaire importància ja que no la cridem des del programa. Sembla que algunes versions del compilador XC8 només admeten una de les dues. Si una d'elles falla podem provar amb l'altra.
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 | INTCONbits.GIE | Activació global de les interrupcions |
| 6 | INTCONbits.PEIE | Activació de les interrupcions per perifèrics (Controlats pels registres PIE1 i PIE2) |
|
| 5 | INTCONbits.T0IE | Activació de la interrupció per Timer 0 | |
| 4 | INTCONbits.INTE | Activació de la interrupció externa (RA2)★ | |
| 3 | INTCONbits.RABIE | Activació de la interrupció per canvis als ports A i B★ (Controlats pels registres IOCA i IOCB) |
|
| 2 | INTCONbits.T0IF | Bandera de la interrupció per Timer 0 | |
| 1 | INTCONbits.INTF | Bandera de la interrupció externa (RA2) | |
| 0 | INTCONbits.RABIF | Bandera de la interrupció per canvis als ports A i B⦿ | |
| PIE1 | 6 | PIE1bits.ADIE | Activació de les interrupcions per conversor A/D |
| 5 | PIE1bits.RCIE | Activació de les interrupcions per recepció de la comunicació sèrie asíncrona | |
| 4 | PIE1bits.TXIE | Activació de les interrupcions per emissió de la comunicació sèrie asíncrona | |
| 3 | PIE1bits.SSPIE | Activació de les interrupcions per la comunicació sèrie síncrona | |
| 2 | PIE1bits.CCP1IE | Activació de les interrupcions per capturador/comparador | |
| 1 | PIE1bits.TMR2IE | Activació de les interrupcions per timer 2 | |
| 0 | PIE1bits.TMR1IE | Activació de les interrupcions per timer 1 | |
| PIE2 | 7 | PIE2bits.OSFIE | Activació de les interrupcions per fallada de l'oscil·lador |
| 6 | PIE2bits.C2IE | Activació de les interrupcions per comparador C2 | |
| 5 | PIE2bits.C1IE | Activació de les interrupcions per comparador C1 | |
| 4 | PIE2bits.EEIE | Activació de les interrupcions per EEPROM | |
| PIR1 | 6 | PIR1bits.ADIE | Bandera de la interrupció per conversor A/D |
| 5 | PIR1bits.RCIE | Bandera de la interrupció per recepció de la comunicació sèrie asíncrona | |
| 4 | PIR1bits.TXIE | Bandera de la interrupció per emissió de la comunicació sèrie asíncrona | |
| 3 | PIR1bits.SSPIE | Bandera de la interrupció per la comunicació sèrie síncrona | |
| 2 | PIR1bits.CCP1IE | Bandera de la interrupció per capturador/comparador | |
| 1 | PIR1bits.TMR2IE | Bandera de la interrupció per timer 2 | |
| 0 | PIR1bits.TMR1IE | Bandera de la interrupció per timer 1 | |
| PIR2 | 7 | PIR2bits.OSFIE | Bandera de la interrupció per fallada de l'oscil·lador |
| 6 | PIR2bits.C2IE | Bandera de la interrupció per comparador C2 | |
| 5 | PIR2bits.C1IE | Bandera de la interrupció per comparador C1 | |
| 4 | PIR2bits.EEIE | Bandera de la interrupció per EEPROM | |
| OPTION_REG | 6 | OPTION_REGbits.INTEDG | Si està activat la interrupció externa és a l'activació Si està desactivat és a la desactivació. |
| IOCA | 0 a 5 | IOCAbits.IOCA0 a IOCAbits.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 | IOCBbits.IOCB4 a IOCBbits.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).
void __interrupt() inter(void){ // Gestió de les interrupcions
if(RABIF && RABIE){ // Mira si la interrupció és per canvis als ports
...
}
if(TMR1IF && TMR1IE){ // Mira si la interrupció és per timer 1
...
}
}
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:
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.
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.