Programació en mpasm del PIC 16F690

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

Exemple AI - Adreçament indirecte

Aquest cas és una variant de l'exemple CP. Ara també comptarem cada cop que es prem el polsador però el valor que mostrarem als LED no serà binari natural sinó binari Gray. El codi binari Gray es caracteritza pel fet que entre dos nombres consecutius sempre només canvia un bit i els altres romanen igual. En canvi en binari natural (el que hem vist a format de les dades) hi ha posicions en les que només en canvia un i altres en les que canvien tots. La següent taula ens mostra els dos codis per a nombres de quatre bits:

Valor
decimal
Binari
natural
Binari
Gray
          Valor
decimal
Binari
natural
Binari
Gray
0 0000 0000 8 1000 1100
1 0001 0001 9 1001 1101
2 0010 0011 10 1010 1111
3 0011 0010 11 1011 1110
4 0100 0110 12 1100 1010
5 0101 0111 13 1101 1011
6 0110 0101 14 1110 1001
7 0111 0100 15 1111 1000

Guardarem els 16 codis Gray en una zona de memòria de 16 bytes i farem servir l'adreçament indirecte per anar a buscar el valor corresponent. El programa seria:

#include <p16F690.inc>
	__config (_INTRC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_OFF&_MCLRE_OFF&_CP_OFF&_BOR_OFF&_IESO_OFF&_FCMEN_OFF)
	cblock	0x20
Polsador		; Una variable amb l'estat del polsador (1 = premut)
Previ			; I una amb l'estat previ del polsador
Visualit		; Una variable on guardem el que mostraran els LED
Compta			; Una variable per comptar iteracions
Retard1			; Variable per al bucle de retard
Gray:16			; Els codis Gray dels números del 0 al 15
	endc
	org 0
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
	bcf		STATUS,RP0
	clrf		Compta		; Posa el comptador d'iteracions a valor zero
	clrf		Visualit	; Posa el comptador dels LED a valor zero
	bcf		STATUS,IRP	; Preventivament, posem IRP a 0
	movlw		Gray		; Adreça del primer codi
	movwf		FSR		; Preparem l'adreçament indirecte
	movlw		b'00000000'	; 0
	call		Guarda		; Funció que ho guarda a la memòria
	movlw		b'00000001'	; 1
	call		Guarda
	movlw		b'00000011'	; 2
	call		Guarda
	movlw		b'00000010'	; 3
	call		Guarda
	movlw		b'00000110'	; 4
	call		Guarda
	movlw		b'00000111'	; 5
	call		Guarda
	movlw		b'00000101'	; 6
	call		Guarda
	movlw		b'00000100'	; 7
	call		Guarda
	movlw		b'00001100'	; 8
	call		Guarda
	movlw		b'00001101'	; 9
	call		Guarda
	movlw		b'00001111'	; 10
	call		Guarda
	movlw		b'00001110'	; 11
	call		Guarda
	movlw		b'00001010'	; 12
	call		Guarda
	movlw		b'00001011'	; 13
	call		Guarda
	movlw		b'00001001'	; 14
	call		Guarda
	movlw		b'00001000'	; 15
	call		Guarda
	clrf		Previ		; L'estat previ del polsador és no premut
	clrf		PORTC		; Comencem amb els LED apagats
Bucle
	movlw		b'00000001'
	movwf		Polsador	; Activem polsador abans de comprovar
	btfsc		PORTA,3		; Mira si està desactivada l'entrada A3
					; Si desactivat (premut), no fa la instrucció següent
	clrf		Polsador	; Si no està premut, desactiva polsador
	movf		Previ,w		; Copia Previ a l'acumulador
	xorwf		Polsador,w	; Compara Previ amb Polsador, si són iguals s'activa Z
	btfsc		STATUS,Z	; Si són iguals va a Final
	goto		Esborra
	incf		Compta,f	; Si són iguals, incrementa el valor de Compta
	movf		Compta,w	; Copia Compta a l'acumulador
	xorlw		.4		; Comprova si val 4, si ho val s'activa Z
	btfss		STATUS,Z	; Si val 4 no fa la instrucció següent
	goto		Final		; Si no era 4 va a Final
	movf		Polsador,w	; Copia Polsador a W, si val 0 s'activa Z
	btfsc		STATUS,Z	; Si Polsador valia 1 (Z=0) no fa la instrucció següent
	goto		Invert		; Si no està premut, ja estem
	incf		Visualit,f	; Si ho està, incrementa el valor de Visualit
	btfsc		Visualit,4	; Mira si hem arribat a 16
	clrf		Visualit	; Si hem arribat a 16, torna a posar el comptador a zero
	movlw		Gray		; Adreça del primer codi
	addwf		Visualit,w	; Li suma el valor a mostrar
	movwf		FSR		; I ho posa per a l'adreçament indirecte
	movf		INDF,w		; Llegeix el valor a mostrar
	movwf		PORTC		; I ho posa als LED
Invert
	movf		Previ,w		; Copia Previ a l'acumulador
	xorlw		b'00000001'	; Inverteix el valor
	movwf		Previ		; I ho guarda a Previ
Esborra
	clrf		Compta		; Posa el comptador d'iteracions a valor zero
Final					; Funció de retard 1 ms
	nop
	decfsz		Retard1,f	
	goto		Final
	goto		Bucle		; Repetim-ho...
Guarda
	movwf		INDF		; Adreçament indirecte
	incf		FSR,f		; Incrementem el punter
	return
	end

 

 

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