Programació en pic-as del PIC 16F690

Referència Trucs Perifèrics   Recursos CITCEA
Tutorial Exemples Projectes   Inici

Exemple IR - Interrupció per canvi al port A

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:

PROCESSOR 16F690
#include <xc.inc>
config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
Retard1 EQU 0x20  ; Variable per al cicle de retard
Retard2 EQU 0x21
Retard3 EQU 0x22
PSECT code, class=CODE, delta=2, abs  ; A l'inici de la memòria
main:
  bsf RP0  ; Tria el banc 1
  movlw 11011111B  ; RA5 és sortida
  movwf TRISA  ; Tota la resta és entrada
  clrf TRISC  ; El port C és de sortida
  bcf RP0  ; Tria el banc 0
  bsf RP1  ; Tria el banc 2
  clrf ANSEL  ; Desactiva entrades analògiques
  bcf 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 main

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:

PROCESSOR 16F690
#include <xc.inc>
config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
; Zona de memòria de dades habitual
Visualit EQU 0x20  ; Una variable on guardem el que mostraran els LED
Retard1 EQU 0x21  ; Variable per al cicle de retard
;
; Zona de memòria de dades 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ó
PSECT code, class=CODE, delta=2, abs
main:  ; Adreça 0 h
  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	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 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 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 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 00100000B  ; Activa interrupció a RA5
  movwf IOCA  ; Ho guarda al registre de configuració
  bcf RP0  ; Tria el banc 0
  bsf RP1  ; Tria el banc 2
  clrf IOCB  ; Desactiva interrupcions del port B
  clrf ANSEL  ; Desactiva entrades analògiques
  bcf RP1  ; Tria el banc 0
  clrf Visualit  ; Posa Visualit a 0
  movlw 10001000B  ; 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 main

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.

 

 

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