El PIC16F690 pot tenir interrupcions per canvis d'estat en les entrades dels ports A i B. En aquest exemple farem servir l'entrada RA5.
Els polsadors no són bons per treballar amb interrupcions perquè quan es prem un polsador el seu contacte rebota i el microcontrolador detecta diverses activacions de l'entrada. Per evitar aquest problema, en aquest exemple hem fet servir dues plaques de microcontrolador. En la primera placa mirarem el polsador i quan es detecti que s'ha activat activarem la sortida RA5 durant un temps i després la desactivarem. Connectant la sortida RA5 d'una placa amb l'entrada RA5 de l'altra tindrem una activació única. Això no caldria si la interrupció la volguéssim fer, per exemple, amb un sensor, sempre que no tingui sortida per relé.
Aquest primer programa correspon a la primera placa:
#include <p16F690.inc> __config (_INTRC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_OFF&_MCLRE_OFF&_CP_OFF&_BOR_OFF&_IESO_OFF&_FCMEN_OFF)
cblock 0x20 ; Zona de memòria de dades habitual Retard1 ; Variables de retard Retard2 Retard3 endc
org 0 Inici bsf STATUS,RP0 ; Tria el banc 1 movlw b'11011111' ; RA5 és sortida movwf TRISA ; Tota la resta és entrada clrf TRISC ; El port C és de sortida bcf STATUS,RP0 ; Tria el banc 0 bsf STATUS,RP1 ; Tria el banc 2 clrf ANSEL ; Desactiva entrades analògiques bcf STATUS,RP1 ; Tria el banc 0 clrf PORTA ; Desactiva les sortides del port A clrf PORTC ; Desactiva les sortides del port C Bucle btfsc PORTA,3 ; Mira si està premut el polsador goto $-1 ; Si no ho està, espera bsf PORTA,5 ; Activa la sortida RA5 bsf PORTC,0 ; Activa un LED movlw .2 call Rets ; Retard de 0,4 s bcf PORTA,5 ; Desactiva la sortida RA5 bcf PORTC,0 ; Desactiva el LED movlw .2 call Rets ; Retard de 0,4 s goto Bucle ; Repetim-ho...
; ; Funció de retard de 0,2 W s ; Rets movwf Retard3 Bucles decfsz Retard1,f goto Bucles decfsz Retard2,f goto Bucles decfsz Retard3,f goto Bucles return end
Un cop enviat aquest programa al microcontrolador ja podem desconnectar-lo i connectar l'altra placa. Per a les proves caldrà connectar les dues plaques de manera que totes dues estigui alimentades. Així unirem els borns VDD, VSS i RA5 d'un microcontrolador amb els del mateix nom de l'altre.
El programa del segon microcontrolador és el següent:
#include <p16F690.inc> __config (_INTRC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_OFF&_MCLRE_OFF&_CP_OFF&_BOR_OFF&_IESO_OFF&_FCMEN_OFF)
cblock 0x20 ; Zona de memòria de dades habitual Visualit ; Una variable on guardem el que mostraran els LED Retard1 ; Variable per al cicle de retard endc cblock 0x70 ; Zona de memòria de dades que no depèn del banc triat W_Copia ; Guardarà el contingut de W durant la interrupció ST_Copia ; Guardarà STATUS durant la interrupció endc
org 0 goto Inici ; Saltem al lloc on hi ha el programa principal nop ; Zona de memòria de programa que no utilitzem nop nop
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 btfss INTCON,RABIF ; Mira si la interrupció és per canvis als ports ; Si ho és, no fa la instrucció següent goto FiInt ; Si la interrupció no és per ports no fem res ; Només havíem activat les interrupcions per canvi als ports ; Però, en general, és bo comprovar que l'origen ; de la interrupció és el que esperem RAB ; Programa corresponent a canvi als ports btfss PORTA,RA5 ; Mira si la interrupció ha estat per activació ; Ja hem llegit el port A, ja es podrà desactivar RABIF goto NoAct ; Si era desactivació no fem res incf Visualit,f ; Incrementem Visualit btfsc Visualit,4 ; Mirem si s'ha activat el bit 4 clrf Visualit ; Posa Visualit a 0 NoAct bcf INTCON,RABIF ; Desactivem el bit (després d'haver llegit el port A) 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
Inici bsf STATUS,RP0 ; Tria el banc 1 movlw 0xFF ; Posa l'acumulador a FFh (tot uns) movwf TRISA ; Posa tots els bits del port A com a entrada clrf TRISC ; Posa tots els bits del port C com a sortida movlw b'00100000' ; Activa interrupció a RA5 movwf IOCA ; Ho guarda al registre de configuració bcf STATUS,RP0 ; Tria el banc 0 bsf STATUS,RP1 ; Tria el banc 2 clrf IOCB ; Desactiva interrupcions del port B clrf ANSEL ; Desactiva entrades analògiques bcf STATUS,RP1 ; Tria el banc 0 clrf Visualit ; Posa Visualit a 0 movlw b'10001000' ; Activem GIE i RABIE movwf INTCON ; Activa les interrupcions globals i la dels ports Bucle movf Visualit,w ; Copia Visualit a l'acumulador movwf PORTC ; I ho posa als LED goto Bucle ; Repetim-ho... end
Quan provem el programa veurem que inicialment els LED estan apagats i van comptant cada cop que s'activa el polsador. Si no tinguéssim en compte si l'entrada està activada o desactivada tindríem que es comptaria tant en prémer el polsador com en deixar-lo anar. En aquest cas, però, hauríem de consultar igualment l'estat del port A abans de desactivar RABIF ja que en cas contrari no es desactivaria.

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