Programació en mpasm 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:

#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.

 

 

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