Programació en mpasm del PIC 16F690

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

Monitor d'energia elèctrica

Programa del grup 3

Aquest grup va decidir fer els càlculs a partir del valor màxim del corrent i mostrar una pantalla de l'estil següent:

POT= XXX W
I= XX.XX A

A diferència dels altres, aquest grup no guarda els valors llegits sinó que mentre llegeix ja determina el valor màxim i així estalvia memòria. Una altra diferència d'aquest programa és que llegeix 64 valors en lloc de 32.

Per fer el càlcul de la potència, el valor més alt de tots els llegits l'hem de dividir per 37,85 (factor del sensor de corrent) per tenir el valor màxim del corrent. Aquest resultat el dividirem per arrel de dos per tenir-ne el valor eficaç. El valor eficaç del corrent s'haurà de multiplicar per 230 V per tenir la potència. Així doncs:

Càlcul de la potència

Amb aquest microcontrolador no és senzill fer multiplicacions si els nombres no són enters, per tant, el que podem fer és aproximar el 4,297 per una fracció de nombres enters. Com tampoc és senzill dividir per un nombre que no sigui potència de dos, intentarem trobar una fracció que tingui un denominador potència de dos; per exemple:

Càlcul de la potència

Un cop restats els 512, el valor màxim d'una lectura pot ser entre 0 i 189. Si el multipliquem per 275 estarà entre 0 i 51975 que cap en dos bytes.

El resultat ocuparà dos bytes (varL i varH). Com 275 és més gran que 256, podem fer la resta:

275 = 256 + 19

De manera que multiplicarem el valor màxim de la lectura per 19 (sumant-lo 19 cops) i després el sumarem un cop a varH (que equival a multiplicar per 256). Per dividir per 64 només cal fer rodar els bits sis cops cap a la dreta.

Es volia mostrar el corrent però com el seu valor és petit (entre 0 i 5 A) es va decidir calcular-lo en cA però mostrar-lo en A posant una coma davant de la penúltima xifra. Així doncs, calia fer també el càlcul:

Càlcul de la potència

Aquest grup també va implementar que tres LED s'encenguessin si la potència superava uns determinats valors:

LED Valor
1 256 W
2 512 W
3 768 W
4 1024 W

El programa d'aquest grup é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
Comptador 		; Comptador d'iteracions programa principal
Compt 			; Comptador d'iteracions subfuncions BCD5 i Separa
Temp 			; Variable temporal
Indir 			; Variable temporal per guardar FSR
Valor:2 		; Valor d'entrada (16 bits)
Resul:5 		; Valor de sortida
Control 		; Bits de control (port B)
Caracter 		; Caràcter o codi a enviar (port C)
Retard1 		; Variables per als cicles de retard
Retard2
Retard3
Retard4
Retard5
varH 			; Variables per trobar el valor màxim i calcular la potència
varL
valorsuma 		; Variable per fer la comparació del valor màxim
valorcomp 		; Variable per a la comparació amb els LED
LED1 			; Variables utilitzades per la comparació i activació de LED
LED2
LED3
LED4
LED
intensitat:2 		;variable intensitat (16 bits)
	endc
	org 0
Inici
	bsf 		STATUS,RP0 	; Tria el banc 1
	movlw 		b'10000000'	; Configuració de Timer0
					; Com a temporitzador basat en rellotge
					; 001 - Factor d'escala de 2
					; I resistències de pull-up desactivades (valor per defecte)
	movwf 		OPTION_REG 	; Ho guarda al registre de configuració del Timer0
	movlw 		0xFF 		; Posa l'acumulador a FFh (tot uns)
	movwf 		TRISA 		; Posa tots els bits del port A com a entrada
	clrf 		TRISB 		; Tot el port B és de sortida
	clrf 		TRISC 		; Tot el port C és de sortida
	movlw 		b'00010000'	; Posa el conversor a 1/8 de la freqüència
	movwf 		ADCON1 		; Copia W a la configuració del conversor A/D
	bcf 		STATUS,RP0
	bsf 		STATUS,RP1 	; Tria el banc 2
	movlw 		b'00000101'
	movwf 		ANSEL 		; Configura port AN0 i AN2 com entrades analògiques
	bcf 		STATUS,RP0
	bcf 		STATUS,RP1 	; Tria el banc 0
					; INICIALITZACIÓ DE LES VARIABLES DELS LEDS
	movlw 		b'00000001' 	; Primer LED amb valor de 256
	movwf 		LED1
	movlw 		b'00000010' 	; Segon LED amb valor de 512
	movwf 		LED2
	movlw 		b'00000011' 	; Tercer LED amb valor de 768
	movwf 		LED3
	movlw 		b'00000100' 	; Quart LED amb valor de 1024
	movwf 		LED4
	call 		IniPant 	; Inicialització del mode de funcionament de la pantalla
	call 		ConfPant 	; Configuració de la pantalla
	movlw 		b'10001001' 	; activa el conversor A/D connectat a AN2
	movwf 		ADCON0 		; amb el resultat justificat per la dreta
	call 		Escriure 	; crida a una funció on escrivim per pantalla
BucleGRAN
	movlw 		.100 		; Preselecció de 100, que són 156 iteracions (amb un factor 2 dona 312)
	movwf 		TMR0 		; Ho posa com a preselecció del temporitzador
	movlw 		.64 		; Volem 64 iteracions (64 lectures)
	movwf 		Comptador 	; Comptador d'iteracions
	clrf 		LED 		; Les següents línies netegen les variables
	clrf 		varH
	clrf 		varL
	clrf 		intensitat
	clrf 		intensitat+1
					; ANEM A BUSCAR EL VALOR MÀXIM
Bucle
	movlw 		.100 		; Preselecció de 100, que són 156 iteracions (amb un factor 2 dona 312)
	btfss 		INTCON,T0IF	; Mira si Timer0 ha arribat a zero
					; Si hi ha arribat, no fa la instrucció següent
	goto 		$-1 		; Si no hi ha arribat, repeteix la instrucció
	bcf 		INTCON,T0IF	; Si ha arribat, desactivem el bit
	movwf 		TMR0 		; Ho posa com a preselecció del temporitzador
	nop 				; espera un microsegon
	nop 				; espera un microsegon
	nop 				; espera un microsegon
	nop 				; espera un microsegon
	nop 				; espera un microsegon, en total 5
	bsf 		ADCON0,GO 	; Inicia la conversió
	btfsc 		ADCON0,GO 	; Quan el bit sigui 0 la conversió haurà acabat
	goto 		$-1 		; repetim la línia fins que deixi de ser 1
	bsf 		STATUS,RP0 	; TRIA EL BANC 1
	movf 		ADRESL,w 	; Guarda ADRESL a l’acumulador
	bcf 		STATUS,RP0 	; Tria el banc 0
	movwf 		valorsuma 	; movem el valor de l'acumulador a valorsuma
	btfsc 		ADRESH,1 	; mirem si es més gran de 512
	goto 		mostra 		; anem a la comparació
					; Si és inferior a 512
	bsf 		STATUS, RP0	; tria el banc 1
	comf 		ADRESL,w 	; rotem bits i guardem al acumulador
	bcf 		STATUS,RP0 	; TRIA EL BANC 0
	movwf 		valorsuma 	; Guardem el valor de l’acumulador a valorsuma
	incf 		valorsuma,f	; incrementem en 1 el valor de valorsuma
	movf 		valorsuma,w	; Guardem valorsuma a l’acumulador
mostra 					; Comparació amb varH, si és mes gran el valor llegir,
					; el guardem a varH, és a dir, ja es fa la multiplicació per 256
	subwf 		varH,w 		; Mirem si varH >= ADRESL
	btfsc 		STATUS,C 	; si varH més gran que ADRESL, anem a ficomparacio
	goto 		ficomparacio
	movf 		valorsuma,w 	; guardem el valor màxim a varH
	movwf 		varH
ficomparacio
	movf 		varH,w 		; passem varH a valorsuma
	movwf 		valorsuma
	decfsz 		Comptador,f	; Decrementem el comptador
	goto 		Bucle 		; Repetim-ho......FINS QUE ACABA EL BUCLE
					; ANEM A CALCULAR LA INTENSITAT EFICAÇ
					; multiplicant entre 15 i dividim entre 8
	movlw 		.15		; Fem un bucle de la suma 15 cops
	movwf 		Comptador
buclesum
	movf 		valorsuma,w	; Guardem valorsuma a l’acumulador
	addwf 		intensitat,f	; Sumem l’acumulador a la variable
	btfsc 		STATUS,C 	; Mirem si s’activa C, si està desactivat salta
	incf 		intensitat+1,f	; Passem al byte superior
	decfsz 		Comptador,f	; Decrementem el comptador
	goto 		buclesum 	; Anem a buclesum
	movlw 		.3 		; Dividim entre 8, és a dir, rotem 3 cops a la dreta
	movwf 		Comptador
bucLEDiv
	bcf 		STATUS,C	; fica a 0 la C
	rrf 		intensitat+1,f	; Rotem els bits cap a la dreta
	rrf 		intensitat,f
	decfsz 		Comptador,f	; Decrementem el comptador
	goto 		bucLEDiv 	; Anem a bucLEDiv
					; ANEM A CALCULAR LA POTÈNCIA
	movlw 		.19 		; Fem un bucle de la suma 19 cops
	movwf 		Comptador
buclesum2
	movf 		valorsuma,w	; Guardem valorsuma a l’acumulador
	addwf 		varL,f		; Sumem l’acumulador a la variable
	btfsc 		STATUS,C	; Mirem si s’activa C, si està desactivat salta
	incf 		varH,f 		; Passem al byte superior
	decfsz 		Comptador,f	; Decrementem el comptador
	goto 		buclesum2 	; Anem a buclesum2
	movlw 		.6 		; Fem un bucle per dividir, és a dir rotar bits 6 cops
	movwf 		Comptador
dividir
	bcf 		STATUS,C 	; fica a 0 la C
	rrf 		varH,f 		; Rotem bits a la dreta
	rrf 		varL,f
	decfsz 		Comptador,f	; Decrementem el comptador
	goto 		dividir 	; Anem a dividir
					; ANEM A ENCENDRE ELS LEDS
	movf 		varH,w 		; Donem un valor a cada LED i comparem si el nostre valor
					; de potència els supera
	movwf 		valorcomp 	; Guardem l’acumulador a la variable
	movf 		LED4,w 		; Guardem LED4 a l’acumulador
	subwf 		valorcomp,w	; Mirem si varH >= ADRESL
	btfss 		STATUS,C 	; C = 1 si varH >= ADRESL
	goto 		comparacioLED3
	bsf 		LED,0 		; Activa el bit 0 del port C
	bsf 		LED,1 		; Activa el bit 1 del port C
	bsf 		LED,2 		; Activa el bit 2 del port C
	bsf 		LED,3 		; Activa el bit 3 del port C
comparacioLED3
	movf 		varH,w
	movwf 		valorcomp
	movf 		LED3,w
	subwf 		valorcomp,w	; Mirem si valorcomp >= LED3
	btfss 		STATUS,C 	; C = 1 si valorcomp >= LED3
	goto 		comparacioLED2
	bsf 		LED,0 		; Activa el bit 0 del port C
	bsf 		LED,1 		; Activa el bit 1 del port C
	bsf 		LED,2 		; Activa el bit 2 del port C
comparacioLED2
	movf 		varH,w
	movwf 		valorcomp
	movf 		LED2,w
	subwf 		valorcomp,w	; Mirem si varH >= ADRESL
	btfss 		STATUS,C 	; C = 1 si varH >= ADRESL
goto comparacioLED1
	bsf 		LED,0 		; Activa el bit 0 del port C
	bsf 		LED,1 		; Activa el bit 0 del port C
comparacioLED1
	movf 		varH,w
	movwf 		valorcomp
	movf 		LED1,w
	subwf 		valorcomp,w	; Mirem si varH >= ADRESL
	btfss 		STATUS,C	; C = 1 si varH >= ADRESL
	goto 		ficomparacioLED
	bsf 		LED,0 		; Activa el bit 0 del port C
ficomparacioLED
					; ANEM A ESCRIURE A LA PANTALLA
	movlw 		0x04 		; Adreça DDRAM (Filera 1 - Posició 4)
	iorlw 		b'10000000'	; Posa el bit de DDRAM a 1
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaC 		; Ho envia
	movf 		varL,w 		; Byte inferior
	movwf 		Valor 		; Variable per a convertir a BCD
	movf 		varH,w 		; Byte superior
	movwf 		Valor+1 	; Variable per a convertir a BCD
	call 		BCD5 		; Ho convertim a BCD
	call 		Separa 		; Ho separem en 5 bytes
	movf 		Resul+3,w 	; Llegeix el caràcter
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movf 		Resul+2,w 	; Llegeix el caràcter
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movf 		Resul+1,w 	; Llegeix el caràcter
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movf 		Resul,w 	; Llegeix el caràcter
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movlw 		' ' 		; Lletra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movlw 		'W' 		; Lletra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movlw 		0x43 		; Adreça DDRAM (Filera 2 - Posició 4)
	iorlw 		b'10000000'	; Posa el bit de DDRAM a 1
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaC 		; Ho envia
	movf 		intensitat,w	; Byte inferior
	movwf 		Valor 		; Variable per a convertir a BCD
	movf 		intensitat+1,w	; Byte superior
	movwf 		Valor+1 	; Variable per a convertir a BCD
	call 		BCD5 		; Ho convertim a BCD
	call 		Separa 		; Ho separem en 5 bytes
	movf 		Resul+3,w 	; Llegeix el caràcter
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movf 		Resul+2,w 	; Llegeix el caràcter
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movlw 		'.' 		; Lletra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movf 		Resul+1,w 	; Llegeix el caràcter
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movf 		Resul,w 	; Llegeix el caràcter
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movlw 		' ' 		; Lletra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movlw 		'A' 		; Lletra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	call 		Rets
	goto 		BucleGRAN 	; Torna al BucleGRAN
					; AQUÍ COMENCEN LES SUBfuncions
					; funcions d'inici i configuració de la pantalla
Escriure
	movlw 		0x00 		; Adreça DDRAM (Filera 1 - Posició 1)
	iorlw 		b'10000000'	; Posa el bit de DDRAM a 1
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaC 		; Ho envia
	movlw 		'P' 		; Lletra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movlw 		'0' 		; Lletra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movlw 		'T' 		; Lletra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movlw 		'=' 		; Lletra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movlw 		0x40 		; Adreça DDRAM (Filera 2 - Posició 1)
	iorlw 		b'10000000'	; Posa el bit de DDRAM a 1
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaC 		; Ho envia
	movlw 		'I' 		; Lletra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	movlw 		'=' 		; Lletra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaL 		; Ho envia
	return
IniPant 				; Inicialització del mode de funcionament de la pantalla
	movlw 		0 		; Comença un cicle de durada fixa (0,2 s)
	call 		Retard 		; Crida a la funció Retard, el paràmetre està a W
	movlw 		b'00100000'	; Function set - Configuració inicial 0010 al nibble de l'esquerra
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaI 		; Envia els 4 bits superiors
					; Ara enviem la configuració 2 línea, 5x8 píxels 0010 1000
	call 		EnviaI 		; Enviem la part esquerra (ja ho teníem a Caracter)
	movlw 		b'10000000'	; I ara la part dreta (però posada a l'esquerra)
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaI 		; Envia els 4 bits superiors
	return 				; Fi de la inicialització del mode de funcionament
ConfPant				; Configuració de la pantalla
	movlw 		b'00001111'	; Display ON/OFF control - Activa la pantalla amb cursor intermitent
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaC 		; Ho envia
	movlw 		b'00000001'	; Clear display - Buida la pantalla i inicialitza
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaC 		; Ho envia
	movlw 		.5 		; El punt indica que es un valor decimal
					; Comença un cicle de durada fixa (3,9 ms)
	call 		Retard 		; Crida a la funció Retard, el paràmetre està a W
	movlw 		b'00000110'	; Entry mode - Buida la pantalla, sentit dreta i despl. automàtic
	movwf 		Caracter 	; Ho guarda a la variable
	call 		EnviaC 		; Ho envia
	return 				; Fi de la configuració de la pantalla
					; funcions d'enviament de caràcters
EnviaC 					; Enviem caràcters de control
	bcf 		Control,7 	; Desactiva E
	bcf 		Control,5 	; Desactiva RS
	goto 		Envia
EnviaL 					; Enviem caràcters a visualitzar
	bcf 		Control,7 	; Desactiva E
	bsf 		Control,5 	; Activa RS
Envia
	call 		EnviaN 		; Envia els 4 bits més alts
	swapf 		Caracter,f 	; Permuta els nibbles
	call 		EnviaN 		; Envia els 4 bits més alts
	swapf 		Caracter,f 	; Torna a deixar els nibbles com estaven
	return 				; Tornem al lloc des d'on hem vingut
EnviaI 					; Enviem nibbles de caràcters de control
	bcf 		Control,7 	; Desactiva E
	bcf 		Control,5 	; Desactiva RS
	EnviaN 				; Enviem nibbles
	decfsz 		Retard1,f 	; Funció de retard de 0,8 ms
	goto 		EnviaN
	movf 		Control,w 	; Copia Control a l'acumulador
	movwf 		PORTB 		; I ho posa al PORTB
	nop 				; Espera 1 us
	nop 				; Espera 1 us
	nop 				; Espera 1 us
	movf 		Caracter,w 	; Llegeix el caràcter
	andlw 		0xF0 		; Agafa els 4 bits més alts
	iorwf 		LED,w 		; Fa la funció inclusiva entre LED i l’acumulador
	movwf 		PORTC 		; Envia el byte
	bsf 		Control,7 	; Activa E
	movf 		Control,w 	; Copia Control a l'acumulador
	movwf 		PORTB 		; I ho posa al PORTB
	nop 				; Espera 1 us
	nop 				; Espera 1 us
	nop 				; Espera 1 us
	nop 				; Espera 1 us
	nop 				; Espera 1 us
	bcf 		Control,7 	; Desactiva E
	movf 		Control,w 	; Copia Control a l'acumulador
	movwf 		PORTB 		; I ho posa al PORTB
	return 				; Tornem al lloc des d'on hem vingut
					;
					; Bucles de retard
					;
Retard 					; Funció Retard, W conté el nombre de cicles de 771 us que cal fer
	movwf 		Retard2 	; Ho copia a la variable Retard2
BucRet
	decfsz 		Retard1,f 	; Decrementa la variable 1
					; si dona zero, no es fa la instrucció següent
	goto 		BucRet 		; Salta, excepte si el resultat ha estat zero
	decfsz 		Retard2,f 	; Decrementa la variable 2
	goto 		BucRet 		; Salta, excepte si el resultat ha estat zero
	return 				; Tornem al lloc des d'on hem vingut
					;
					; funcions de conversió a BCD
					;
BCD5 					; Converteix a BCD
	movf 		FSR,w 		; Llegim el valor de FSR
	movwf 		Indir 		; I el guardem
	bcf 		STATUS,C 	; Posa a zero C per entrar zeros a les rotacions
	movlw 		.16 		; Nombre d'iteracions
	movwf 		Compt 		; Comptador d'iteracions
	clrf 		Resul+2 	; Desenes de miler
	clrf 		Resul+1 	; Unitats de miler i centenes
	clrf 		Resul 		; Desenes i unitats
BucleBCD
	rlf 		Valor,f 	; Girem bits a l'esquerra a valor
	rlf 		Valor+1,f 	; Cap a valor+1
	rlf 		Resul,f 	; I cap als resultats
	rlf 		Resul+1,f
	rlf 		Resul+2,f
	decfsz 		Compt,f 	; Decrementa Compt
	goto 		ajust 		; Si no és zero, ajustem el resultat
	movf 		Indir,w 	; Recuperem el valor de FSR
	movwf 		FSR 		; I el guardem al seu lloc
	retlw 		0 		; Si és zero ja estem; tornem un 0 a W
ajust 					; funció d'ajust dels resultats
	movlw 		Resul 		; Agafem l'adreça del byte de menys pes
	movwf 		FSR 		; La posa a l'adreçament indirecte
	call 		ajustBCD 	; Ajusta el byte de més a la dreta
	movlw 		Resul+1 	; Agafem l'adreça del byte del mig
	movwf 		FSR 		; La posa a l'adreçament indirecte
	call 		ajustBCD 	; Ajusta el byte del mig
	movlw 		Resul+2 	; Agafem l'adreça del byte de més pes
	movwf 		FSR 		; La posa a l'adreçament indirecte
	call 		ajustBCD 	; Ajusta el byte de més a l'esquerra
	goto 		BucleBCD 	; Torna a repetir el bucle (fins a 16 cops)
ajustBCD 				; funció d'ajust d'un byte, primer el nibble de la dreta, després l'altre
	movlw 		0x03 		; Agafa el valor 03h
	addwf 		INDF,w 		; El suma al byte que ajustem
	movwf 		Temp 		; Ho guarda a Temp
	btfsc 		Temp,3 		; És més gran que 07h (s'ha activat el bit 3)?
	movwf 		INDF 		; Si és cert, sobreposa el resultat
	movlw 		0x30 		; Agafa el valor 30h
	addwf 		INDF,w 		; El suma al byte que ajustem
	movwf 		Temp 		; Ho guarda a Temp
	btfsc 		Temp,7 		; És més gran que 70h (s'ha activat el bit 7)?
	movwf 		INDF 		; Si és cert, sobreposa el resultat
	retlw 0 			; Retorna amb un zero a W
					;
					; funcions de conversió a ASCII
Separa 					; Separa els digits i els converteix a ASCII
	movf 		FSR,w 		; Llegim el valor de FSR
	movwf 		Indir 		; I el guardem
	movf 		Resul+2,w 	; Agafa les desenes de miler
	movwf 		Resul+4 	; Les posa al seu lloc
	swapf 		Resul+1,w 	; Llegeix les unitats de miler i les centenes i les
					; guarda, permutades, a w
	andlw 		0x0F 		; Es queda amb les unitats de miler
	movwf 		Resul+3 	; Les posa al seu lloc
	movf 		Resul+1,w 	; Llegeix les unitats de miler i les centenes i les guarda a w
	andlw 		0x0F 		; Es queda amb les centenes
	movwf 		Resul+2 	; Les posa al seu lloc
	swapf 		Resul,w 	; Llegeix les desenes i les unitats i les guarda, permutades, a w
	andlw 		0x0F 		; Es queda amb les desenes
	movwf 		Resul+1 	; Les posa al seu lloc
	movf 		Resul,w 	; Llegeix les desenes i les unitats i les guarda a w
	andlw 		0x0F 		; Es queda amb les unitats
	movwf 		Resul 		; Les posa al seu lloc
	movlw 		.5 		; Cal fer-ho 5 cops
	movwf 		Compt 		; Ho posem al comptador
	movlw 		Resul+4 	; Adreça de la darrera xifra
	movwf 		FSR 		; Adreçament indirecte
	movlw 		'0' 		; Carrega el codi ASCII del número 0
					; Sumant-li la xifra tindrem el codi ASCII
Bucle1
	addwf 		INDF,f 		; Ho afegeix al dígit
	decf 		FSR,f 		; Decrementa FSR
	decfsz 		Compt,f 	; Decrementa el comptador
	goto 		Bucle1 		; Si no és zero, repetim
	movlw 		.4 		; Cal fer-ho 4 cops
	movwf 		Compt 		; Ho posem al comptador
	movlw 		Resul+4 	; Adreça de la darrera xifra
	movwf 		FSR 		; Adreçament indirecte
Bucle2
	movf 		INDF,w 		; Llegeix el dígit
	xorlw 		'0' 		; Compara amb 0
	btfss 		STATUS,Z 	; Si Z està activat eren iguals
	goto 		Final 		; Si no eren iguals, ja estem
	movlw 		' ' 		; Carrega un espai en blanc
	movwf 		INDF 		; Substitueix el 0 per l'espai
	decf 		FSR,f 		; Decrementa FSR
	decfsz 		Compt,f 	; Decrementa el comptador
	goto 		Bucle2 		; Si no és zero, repetim
Final
	movf 		Indir,w 	; Recuperem el valor de FSR
	movwf 		FSR 		; I el guardem al seu lloc
	retlw 		0 		; Retorna amb un 0 a W
					; FEM UN RETARD DE 2 s
Rets
	movlw 		.10 		; Funció de retard de 2 s
	movwf 		Retard5
Bucles
	decfsz 		Retard3,f
	goto 		Bucles
	decfsz 		Retard4,f
	goto 		Bucles
	decfsz 		Retard5,f
	goto 		Bucles
	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.