Programació en mpasm del PIC 16F690

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

Sensor de temperatura i humitat

Programa del grup 4

El grup 4 va fer un programa amb dues presentacions diferents a la pantalla. En funcionament normal, la pantalla mostra la temperatura i la humitat:

pantalla1

I quan es prem el polsador la pantalla mostra els valors màxim i mínim de temperatura:

pantalla1

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
Compta		; Comptador d'iteracions
Temp		; Variable temporal
Valor:2		; Valor d'entrada (16 bits)
Resul:5		; Valor de sortida
Port		; Valor a escriure al port A
Temps		; Variable per a guardar-hi el temps
Bits		; Compta els bits que es van rebent
Control		; Bits de control (port B)
Caracter	; Caràcter o codi a enviar (port C)
Retard1		; Variables per als cicles de retard
Retard2
Retard3
Humit:2		; Valor de la humitat relativa (en %) multiplicat per 10
Temper:2	; Valor de la temperatura (en °C) multiplicat per 10
Check		; Suma de comprovació de la lectura del sensor
maxT:2		; Variables per al càlcul de màxims i mínims
minT:2		 
maxL:2		; Variables límit de la temperatura per als LED
minL:2
Leds		; Variable per a encendre i apagar els LED
	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
	bcf		TRISA,2		; De moment, RA2 és sortida
	clrf		TRISB		; Tot el port B és de sortida
	clrf		TRISC		; Tot el port C és de sortida
	movlw		b'10000000'	; Configuració de Timer0
					; Com a temporitzador basat en rellotge
					; 000 - Factor d'escala de 2
					; TMR0 s'incrementarà cada 2 us
					; I resistències de pull-up desactivades (valor per defecte)
	movwf		OPTION_REG	; Ho guarda al registre de configuració del Timer0
	bcf		STATUS,RP0
	bsf		STATUS,RP1	; Tria el banc 2
	movlw		b'11111011'
	movwf		ANSEL		; Posa AN2 (RA2) com entrada binària
	bcf		STATUS,RP0
	bcf		STATUS,RP1	; Tria el banc 0
	movlw		b'00000100'	; PORTA,2 és on hi ha el sensor
	movwf		Port		; Ho guarda a la variable Port
	movwf		PORTA		; I ho copia al port A
					; Inicialització de les variables
	clrf		maxT		; Posa el valor màxim a zero
	clrf		maxT+1
	movlw		0xFF		; Posa el mínim al més alt possible
	movwf		minT
	movwf		minT+1
					; Posa valor a les variables límit de la temperatura
	movlw	   	b'11111111'	; 25,5 °C al límit superior
	movwf	   	maxL
	movlw	   	b'11001000'	; 20 °C al límit inferior
	movwf	   	minL
	clrf		maxL+1
	clrf		minL+1
	clrf		Leds		; Posa a 0 tots els bits, tots els LED apagats
Bucle
	call		IniPant		; Inicialització del mode de funcionament de la pantalla
	call		ConfPant	; Configuració de la pantalla
	call		Llegir		; Llegeix els valors del sensor
	andlw		0xFF		; Mira si W és zero
	btfss		STATUS,Z	; Si és zero, and donarà zero
	goto		Bucle		; No és zero, torna al Bucle
					; És zero, lectura correcta
   	call		sumcomp		; Compara la suma de temperatura i humitat amb el checksum rebut
   	btfss		STATUS,Z	; Si són iguals donarà 0
	goto		Bucle		; No és zero, torna al Bucle
					; És zero, la lectura s'ha rebut correctament
	call		comparacio	; Mira si la temperatura supera la màxima i mínima guardades
	call		comparacio2	; Mira si la temperatura se surt dels límits guardats
  	btfss		PORTA,3		; Mira si està activada l'entrada A3
	goto		MAXMIN		; Si el bit és 0, el polsador està premut, mostra els màxims i mínims
TH					; Si el bit és 1, mostra la temperatura i humitat
	movlw		0x04		; Adreça DDRAM (Fila 1 - Posició 5)
	iorlw		b'10000000'	; Posa el bit de DDRAM a 1
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaC		; Ho envia
	movlw		'T'		; T (temperatura)
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		' '		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		':'		; Dos punts
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movf		Temper+1,w	; Llegeix el byte més significatiu de la temperatura
	movwf		Valor+1		; Ho prepara per convertir-ho a BCD
	movf		Temper,w	; Llegeix el byte menys significatiu de la temperatura
	movwf		Valor		; Ho prepara per convertir-ho a BCD
	call		BCD5		; Ho converteix en BCD en 3 bytes
	call		Separa		; Ho separem en 5 bytes
	call		EscPant5	; Ho enviem a la pantalla afegint la coma del decimal
	movlw		' '		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		b'11011111'	; ° (graus)
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'C'		; C (centigrads)
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		0x44		; Adreça DDRAM (Fila 2 - Posició 5)
	iorlw		b'10000000'	; Posa el bit de DDRAM a 1
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaC		; Ho envia
	movlw		'H'		; H (humitat)
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'R'		; R (relativa)
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		' '		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		':'		; Dos punts
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movf		Humit+1,w	; Llegeix el byte més significatiu de la humitat
	movwf		Valor+1		; Ho prepara per convertir-ho a BCD
	movf		Humit,w		; Llegeix el byte menys significatiu de la humitat
	movwf		Valor		; Ho prepara per convertir-ho a BCD
	call		BCD5		; Ho converteix en BCD en 3 bytes
	call		Separa		; Ho separa en 5 bytes
	call		EscPant5	; Ho envia a la pantalla, afegint la coma del decimal
	movlw		' '		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'%'		; %
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		.8		; Comença un cicle de durada fixa (1,6 s)
	call		Retard5		; Crida a la funció Retard5, el paràmetre està a W
	goto		Bucle		; Tornem al Bucle
MAXMIN
	movlw		0x01		; Adreça DDRAM (Fila 1 - Posició 2)
	iorlw		b'10000000'	; Posa el bit de DDRAM a 1
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaC		; Ho envia
	movlw		'T'		; T (temperatura)
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'm'		; m
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'a'		; a
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'x'		; x
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		' '		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		':'		; Dos punts
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movf		maxT+1,w	; Llegeix el byte més significatiu de la temperatura
	movwf		Valor+1		; Ho prepara per convertir-ho a BCD
	movf		maxT,w		; Llegeix el byte menys significatiu de la temperatura
	movwf		Valor		; Ho prepara per convertir-ho a BCD
	call		BCD5		; Ho converteix en BCD en 3 bytes
	call		Separa		; Ho separem en 5 bytes
	call		EscPant5	; Ho enviem a la pantalla, afegint la coma del decimal
	movlw		' '		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		b'11011111'	; ° (graus)
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'C'		; C (centigrads)
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		0x41		; Adreça DDRAM (Fila 2 - Posició 2) 
	iorlw		b'10000000'	; Posa el bit de DDRAM a 1
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaC		; Ho envia
	movlw		'T'		; T (temperatura)
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'm'		; m
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'i'		; i
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'n'		; n
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		' '		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		':'		; Dos punts
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movf		minT+1,w	; Llegeix el byte més significatiu de la temperatura
	movwf		Valor+1		; Ho prepara per convertir-ho a BCD
	movf		minT,w		; Llegeix el byte menys significatiu de la temperatura
	movwf		Valor		; Ho prepara per convertir-ho a BCD
	call		BCD5		; Ho converteix en BCD en 3 bytes
	call		Separa		; Ho separa en 5 bytes
	call		EscPant5	; Ho envia a la pantalla, afegint la coma del decimal
	movlw		' '		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		b'11011111'	; ° (graus)
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'C'		; C (centigrads)
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		.8		; Comença un cicle de durada fixa (1,6 s)
	call		Retard5		; Crida a la funció Retard, el paràmetre està a W
	goto		Bucle		; Tornem al Bucle
sumcomp					; Fa la suma de comprovació de les lectures
	movf		Temper,w	; Byte menys significatiu de la temperatura
	addwf		Temper+1,w	; Li suma el byte més significatiu de la temperatura
	addwf		Humit,w		; Li suma el byte menys significatiu de la humitat
	addwf		Humit+1,w	; Li suma el byte més significatiu de la humitat
	xorwf		Check,w		; La comparem amb la suma de comprovació rebuda
	return				; Torna al programa principal
comparacio				; Guarda el màxim i el mínim
	movf		maxT+1,w	; W té el byte més significatiu del màxim
	xorwf		Temper+1,w	; Ho compara amb la lectura de la Temperatura
	btfss		STATUS,Z	; Si Z = 1 són iguals
	goto		DifMax		; Si són diferents, va a mirar quin és més gran
					; Són iguals, compara el byte menys significatiu
	movf		maxT,w		; W té el byte menys significatiu del màxim
	subwf		Temper,w	; W = Temper - W = Temper - maxT
	btfss		STATUS,C	; C = 1 si Temper >= maxT
	goto		MenorMax	; Si és més petit, no cal fer res
	goto		NouMax		; Si és més gran, cal guardar-lo
DifMax
	movf		maxT+1,w	; W té el byte més significatiu del màxim
	subwf		Temper+1,w	; W = Temper+1 - W = Temper+1 - maxT+1
	btfss		STATUS,C	; C = 1 si Temper+1 >= maxT+1
	goto		MenorMax	; Si és més petit, no cal fer res
NouMax					; Si és més gran, cal guardar-ho
	movf		Temper+1,w	; Copia la lectura al màxim
	movwf		maxT+1		; Primer, el byte més significatiu
	movf		Temper,w	; Després, el byte menys significatiu
	movwf		maxT
MenorMax				; Compara amb el mínim
	movf		minT+1,w	; W té el byte més significatiu del mínim
	xorwf		Temper+1,w	; Ho compara amb Temper+1
	btfss		STATUS,Z	; Si Z = 1 són iguals
	goto		DifMin		; Si són diferents, mira quin és més gran
	movf		minT,w		; W té el byte menys significatiu del mínim
	subwf		Temper,w	; W = Temper - W = Temper - minT
	btfsc		STATUS,0	; C = 0 si Temper < minT
	goto		MajorMin	; Si és més gran, no cal fer res
	goto		NouMin		; Si és més petit, cal guardar-lo
DifMin
	movf		minT+1,w	; W té el byte més significatiu del mínim
	subwf		Temper+1,w	; W = Temper+1 - W = Temper+1 - minT+1
	btfsc		STATUS,C	; C = 0 si Temper+1 < minT+1
	goto		MajorMin	; Si és més gran, no cal fer res
NouMin					; Si és més petit, cal guardar-ho
	movf		Temper+1,w	; Copia la lectura al mínim
	movwf		minT+1		; Primer, el byte més significatiu
	movf		Temper,w	; Després, el byte menys significatiu
	movwf		minT
MajorMin	
	return				; Torna al programa principal
comparacio2				; Mira si la temperatura surt dels límits
	movf		maxL+1,w	; W té el byte més significatiu del límit superior
	xorwf		Temper+1,w	; Compara amb Temper+1
	btfss		STATUS,Z	; Si Z = 1 són iguals
	goto		DifMax2		; Si són diferents, cal veure quin és més gran
	movf		maxL,w		; W té el byte menys significatiu del límit superior
	subwf		Temper,w	; W = Temper - W = Temper - maxL
	btfss		STATUS,C	; C = 1 si Temper >= maxL
	goto		MenorMax2	; Si és més petit, comproba el límit inferior
	goto		EncenLeds	; Si és més gran, encen els LED
DifMax2					
	movf		maxL+1,w	; W té el byte més significatiu del límit superior
	subwf		Temper+1,w	; W = Temper+1 - W = Temper+1 - maxL+1
	btfss		STATUS,C	; C = 1 si Temper+1 >= maxL+1
	goto		MenorMax2	; Si és més petit, no cal fer res
EncenLeds				; Si és més gran, encen els LED
	movlw		b'00001111'	; Activa els quatre bits dels LED
	movwf		Leds
	return				; Torna al programa principal
MenorMax2				; Compara amb el límit inferior
	movf		minL+1,w	; W té el byte més significatiu del límit inferior
	xorwf		Temper+1,w	; Comparem amb Temper+1
	btfss		STATUS,Z	; Si Z = 1 són iguals
	goto		DifMin2		; Si són diferents, cal veure quin és més gran
	movf		minL,w		; W té el byte menys significatiu del límit inferior
	subwf		Temper,w	; W = Temper - W = Temper - minL
	btfsc		STATUS,0	; C = 0 si Temper < minL
	goto		MajorMin2	; Si és més gran, apaga els LED
	goto		EncenLeds	; Si és més petit, cal encendre els LED
DifMin2
	movf		minL+1,w	; W té el byte més significatiu del límit inferior
	subwf		Temper+1,w	; W = Temper+1 - W = Temper+1 - minL+1
	btfsc		STATUS,C	; C = 0 si Temper+1 < minL+1
	goto		MajorMin2	; Si és més petit, apaga els LED
	goto		EncenLeds	; Si és més gran, encen els LED
MajorMin2				; La temperatura està dins dels límits
	movlw		b'00000000'	; Desactiva els quatre bits dels LED
	movwf		Leds
	return				; Torna al programa principal
Llegir					; Llegeix els valors al sensor
					; Primer activa el funcionament del sensor
	bsf		STATUS,RP0	; Tria el banc 1
	bcf		TRISA,2		; Posa el pin com a sortida
	bcf		STATUS,RP0	; Tria el banc 0
	clrf		Humit+1		; Posa a zero les variables on ha d'anar la lectura
	clrf		Humit
	clrf		Temper+1	; Els primers bits de Humit+1 seran 0; així
	clrf		Temper		; si el bit de més a la dreta de Check el posa a 1
	movlw		0x01		; es podrà veure on ha quedat aquest 1
	movwf		Check		; en cas que hi hagi una errada de lectura
	bcf		Port,2		; Posa la sortida a 0
	movf		Port,w		; Ho copia a W
	movwf		PORTA		; I ho envia al port
	movlw		.2		; Retard d'1,54 ms
	call		Retard		; Espera el temps
	bsf		Port,2		; Posa la sortida a 1
	movf		Port,w		; Ho copia a W
	movwf		PORTA		; I ho envia al port
	movlw		.5		; El retard serà de 3*5 = 15 us
	call		Retus
					; Un cop activat, espera la resposta
	bsf		STATUS,RP0	; Tria el banc 1
	bsf		TRISA,2		; Posa el pin com a entrada
	bcf		STATUS,RP0	; Tria el banc 0
					; Espera a rebre el pols d'inici
					; Primer un L d'uns 80 us
					; Per començar, s'ha de desactivar l'entrada
					; i s'ha de reactivar al cap d'entre 70 i 90 us
Esp0
	btfsc		PORTA,2		; S'ha desactivat l'entrada?
	goto		Esp0		; No, doncs espera
	clrf		TMR0		; Comenca a comptar el temps
Esp1I					; Espera que s'activi l'entrada
	btfsc		PORTA,2		; S'ha activat l'entrada?
	goto		ZeroIni		; Sí, doncs el zero inicial ja està
	movf		TMR0,w		; No, agafa el valor actual del temps
	movwf		Temps		; i el guarda
	movlw		.45		; Mira que no passi de 90 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 45
	goto		Esp1I		; És més petit, segueix esperant
	retlw		.1		; És més gran: Error 1 - Zero inicial massa llarg
ZeroIni					; El zero inicial ja està
					; Comprova la durada
	movf		TMR0,w		; Agafa el valor actual del temps
	movwf		Temps		; i el guarda
	clrf		TMR0		; Comença a comptar el temps per al següent
	movlw		.35		; Mira que no sigui menor que 70 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 35
	retlw		.2		; És més petit: Error 2 - Zero inicial massa curt
					; Ja té el zero inicial
					; Ara l'entrada està a u i espera que es posi a zero
Esp0I					; Espera a que es desactivi l'entrada
	btfss		PORTA,2		; S'ha desactivat l'entrada?
	goto		UIni		; Sí, doncs l'u inicial ja està
	movf		TMR0,w		; No, agafa el valor actual del temps
	movwf		Temps		; i el guarda
	movlw		.45		; Mira que no passi de 90 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 45
	goto		Esp0I		; És més petit, segueix esperant
	retlw		.3		; És més gran: Error 3 - U inicial massa llarg
UIni					; L'u inicial ja està
	movf		TMR0,w		; Agafa el valor actual del temps
	movwf		Temps		; i el guarda
	clrf		TMR0		; Comença a comptar el temps per al següent
	movlw		.35		; Mira que no sigui menor que 70 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 35
	retlw		.4		; És més petit: Error 4 - U inicial massa curt
					; Ja té l'u inicial
					; Ara ha de rebre els bits
	movlw		.40		; Ha de rebre 40 bits
	movwf		Bits		; Aquesta variable els comptarà
BucBits					; Espera a rebre un bit
					; Primer un L d'uns 80 us
					; Ara l'entrada està a zero
					; S'ha d'activar al cap d'entre 10 i 90 us
	clrf		TMR0		; Comença a comptar el temps
Esp1B					; Espera que s'activi l'entrada
	btfsc		PORTA,2		; S'ha activat l'entrada?
	goto		ZeroB		; Sí, doncs el valor 0 del bit ja està
	movf		TMR0,w		; No, agafa el valor actual del temps
	movwf		Temps		; i el guarda
	movlw		.45		; Mira que no passi de 90 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 45
	goto		Esp1B		; És més petit, segueix esperant
	retlw		.5		; És més gran: Error 5 - Valor 0 del bit massa llarg
ZeroB					; El valor 0 del bit ja està
	movf		TMR0,w		; Agafa el valor actual del temps
	movwf		Temps		; i el guarda
	clrf		TMR0		; Comença a comptar el temps per al següent
	movlw		.5		; Mira que no sigui menor que 10 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 5
	retlw		.6		; És més petit: Error 6 - Valor 0 del bit massa curt
					; Ja té el valor 0 del bit. Ara espera un 1
Esp0B					; Espera a que es desactivi l'entrada
	btfss		PORTA,2		; S'ha desactivat l'entrada?
	goto		UB		; Sí, doncs el valor 1 del bit ja està
	movf		TMR0,w		; No, agafa el valor actual del temps
	movwf		Temps		; i el guarda
	movlw		.40		; Mira que no passi de 80 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 40
	goto		Esp0B		; És més petit, segueix esperant
	retlw		.7		; És més gran: Error 7 - Valor 1 del bit massa llarg
UB					; El valor 1 del bit ja està
	movf		TMR0,w		; Agafa el valor actual del temps
	movwf		Temps		; i el guarda
	clrf		TMR0		; Comença a comptar el temps per al següent
					; Ja ha comprovat que no passi de 80 us
					; Si és més petit que 12 us és massa curt
	movlw		.6		; Mira si és menor que 12 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 8
	retlw		.8		; És més petit: Error 8 - Valor 1 del bit massa curt
					; Ja ha comprovat que no sigui massa curt
					; Si és més petit que 38 us és un pols curt, o sigui un 0
	movlw		.19		; Mira si és menor que 38 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 19
	goto		EsUn0		; Si està entre 16 i 38 us és un 0
					; No era un pols curt
					; Si és més gran que 60 us és un pols llarg, o sigui un 1
	movlw		.30		; Mira si és menor que 60 us
	subwf		Temps,w		; W = Temps - W
	btfsc		STATUS,C	; C = 1 si Temps >= 30
	goto		EsUn1		; Si està entre 60 i 80 us és un 1
	retlw		.9		; No és ni llarg ni curt: Error 9 - Valor 1 del bit incorrecte
EsUn0
	bcf		STATUS,C	; Si és un 0 entra un 0
	goto		EntraBit
EsUn1
	bsf		STATUS,C	; Si és un 1 entra un 1
EntraBit				; Guarda el bit rebut
	rlf		Check,f		; Entra per Check i va rodant fins a Humit+1
	rlf		Temper,f
	rlf		Temper+1,f
	rlf		Humit,f
	rlf		Humit+1,f
	decfsz		Bits,f		; Un altre bit rebut
	goto		BucBits		; Si no ha acabat, espera el següent
	retlw		.0		; Lectura correcta
EscPant5				; Va a enviar la lectura de 5 caràcters, amb la coma del decimal
	movlw		.4		; Cal fer-ho 4 cops
	movwf		Compta		; Ho posa al comptador
	movlw		Resul+4		; Adreça de la darrera xifra
EscPant
	movwf		FSR		; Adreçament indirecte
BuclePant
	movf		INDF,w		; Llegeix el caràcter
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	decf		FSR,f		; Decrementa FSR
	decfsz		Compta,f	; Decrementa el comptador
	goto		BuclePant	; Si no és zero, repeteix
Decimal					; Afegeix el decimal
	movlw		','		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		Resul		; W té el decimal
	movf		INDF,w		; Llegeix el caràcter
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	return				; Fi de l'enviament a la pantalla
IniPant					; Inicialització del mode de funcionament de la pantalla
	movlw		0		; Comencen dos cicles de durada 0,2 s
	call		Retard		; Crida a la funció Retard, el paràmetre està a W
	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 envia 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'00001100'	; Display ON/OFF control - Activa la pantalla sense 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
					;
EnviaC					; Envia caràcters de control
	bcf		Control,7	; Desactiva E
	bcf		Control,5	; Desactiva RS
	goto		Envia
EnviaL					; Envia 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	   	Leds, w		; Afegeix els bits dels LED al byte
	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				; Torna al lloc des d'on ha vingut
					;
Retus					; Funció de retard; W conté el nombre de cicles de 3 us que cal fer
	movwf		Retard1		; Ho copia a la variable Retard1
Bucleus
	decfsz		Retard1,f	; Decrementa la variable
					; Si dona 0 no es fa la instrucció següent
	goto		Bucleus		; Salta excepte quan és zero
	return
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

Retard5					; Funcio de retard, W conté el nombre de cicles de 0,2 s que cal fer
	movwf		Retard3		; Ho copia a la variable Retard3
BucRet5
	decfsz		Retard1,f	; Decrementa la variable 1
					; si dona zero, no es fa la instrucció següent
	goto		BucRet5		; Salta, excepte si el resultat ha estat zero
	decfsz		Retard2,f	; Decrementa la variable 2
	goto		BucRet5		; Salta, excepte si el resultat ha estat zero
	decfsz		Retard3,f	; Decrementa la variable 3
	goto		BucRet5		; Salta, excepte si el resultat ha estat zero
	return

BCD5					; Converteix a BCD
	bcf		STATUS,C	; Posa a zero C per entrar zeros a les rotacions
	movlw		.16		; Nombre d'iteracions
	movwf		Compta		; 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		; Gira 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		Compta,f	; Decrementa Compta
	goto		ajust		; Si no és zero, ajusta el resultat
	retlw		0		; Si és zero ja està; torna un 0 a W
ajust					; funció d'ajust dels resultats
	movlw		Resul		; Agafa 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		; Agafa 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		; Agafa 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
					;
Separa					; Separa els digits i els converteix a ASCII
	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		Compta		; Ho posa 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		Compta,f	; Decrementa el comptador
	goto		Bucle1		; Si no és zero, repeteix
	movlw		.4		; Cal fer-ho 4 cops
	movwf		Compta		; Ho posa 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 està
	movlw		' '		; Carrega un espai en blanc
	movwf		INDF		; Substitueix el 0 per l'espai
	decf		FSR,f		; Decrementa FSR
	decfsz		Compta,f	; Decrementa el comptador
	goto		Bucle2		; Si no és zero, repeteix
Final
	retlw		0		; Retorna amb un 0 a W
	end

 

 

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