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 3

El grup 3 va fer un programa amb quatre presentacions diferents a la pantalla que van apareixent successivament:

pantalla1                 pantalla2

pantalla3                 pantalla4

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
max:2
min:2
maxim:2
minim:2
	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
					; Inicialització de les variables
	clrf		max		; Posa el valor màxim a zero
	clrf		max+1
	movlw		0xFF		; Posa el mínim al més alt possible
	movwf		min		; o sigui, FFFFh
	movwf		min+1
	clrf		maxim		; Posa el valor màxim a zero
	clrf		maxim+1
	movlw		0xFF		; Posa el mínim al més alt possible
	movwf		minim		; o sigui, FFFFh
	movwf		minim+1
	movlw		b'00000100'	; PORTA,2 és on hi ha el sensor
	movwf		Port		; Ho guardem a la variable Port
	movwf		PORTA		; I ho copiem al port A
	call		IniPant		; Inicialització del mode de funcionament de la pantalla
	call		ConfPant	; Configuració de la pantalla
Bucle
	call		Llegir		; Llegeix els valors del sensor
	andlw		0xFF		; Anem a veure si W és zero
	btfss		STATUS,Z	; Si és zero, and donarà zero
	goto		Bucle		; No és zero, tornem a llegir
					; És zero, lectura correcta
	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		'H'
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'='
	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 separem en 5 bytes
	call		EscPant3	; Ho enviem a la pantalla
	movlw		'%'		; Espai en blanc
	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		'T'		; Espai en blanc
	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
	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		EscPant3	; Ho enviem a la pantalla
	movlw		b'11011111'
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'C'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		0x40		; 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		'T'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'm'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'a'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'x'		; Espai en blanc
	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
	movf		max+1,w		; W té el màxim
	xorwf		Temper+1,w	; Comparem amb Lectura+1
	btfss		STATUS,Z	; Si Z = 1 eren iguals
	goto		DifMax		; Si són diferents, provem el cas 2
	movf		max,w		; W té el màxim
	subwf		Temper,w	; W = Lectura - W = Lectura - max
	btfss		STATUS,C	; C = 1 si Lectura >= max
	goto		MenorMax	; Si és més petit, no cal fer res
	goto		NouMax		; Si és més gran, cal guardar-lo
DifMax
	movf		max+1,w		; W té el màxim
	subwf		Temper+1,w	; W = Lectura+1 - W = Lectura+1 - max+1
	btfss		STATUS,C	; C = 1 si Lectura+1 >= max+1
	goto		MenorMax	; Si és més petit, no cal fer res
NouMax
	movf		Temper+1,w	; Copiem Lectura a max
	movwf		max+1
	movf		Temper,w
	movwf		max
MenorMax				; Recollim el mínim
	movf		min+1,w		; W té el mínim
	xorwf		Temper+1,w	; Comparem amb Lectura+1
	btfss		STATUS,Z	; Si Z = 1 eren iguals
	goto		DifMin		; Si són diferents, provem el cas 2
	movf		min,w		; W té el mínim
	subwf		Temper,w	; W = Lectura - W = Lectura - min
	btfsc		STATUS,0	; C = 0 si Lectura < min
	goto		MajorMin	; Si és més gran, no cal fer res
	goto		NouMin		; Si és més petit, cal guardar-lo
DifMin
	movf		min+1,w		; W té el mínim
	subwf		Temper+1,w	; W = Lectura+1 - W = Lectura+1 - min+1
	btfsc		STATUS,C	; C = 0 si Lectura+1 < min+1
	goto		MajorMin	; Si és més petit, no cal fer res
NouMin
	movf		Temper+1,w	; Copiem Lectura a min
	movwf		min+1
	movf		Temper,w
	movwf		min
MajorMin
	movf		max+1,w		; Llegeix el byte més significatiu de la temperatura
	movwf		Valor+1		; Ho prepara per convertir-ho a BCD
	movf		max,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		EscPant3	; Ho enviem a la pantalla
	movlw		b'11011111'
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'C'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		.20		; Comença un cicle de durada fixa (0,2 s)
	call		Retards		; Crida a la funció Retard, el paràmetre està a W
	call		Llegir		; Llegeix els valors del sensor
	andlw		0xFF		; Anem a veure si W és zero
	btfss		STATUS,Z	; Si és zero, and donarà zero
	goto		Bucle		; No és zero, tornem a llegir
					; És zero, lectura correcta
	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		'H'
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'='
	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 separem en 5 bytes
	call		EscPant3	; Ho enviem a la pantalla
	movlw		'%'		; Espai en blanc
	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		'T'		; Espai en blanc
	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
	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		EscPant3	; Ho enviem a la pantalla
	movlw		b'11011111'
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'C'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		0x40		; 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		'T'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'm'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'i'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'n'		; Espai en blanc
	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
	movf		min+1,w		; Llegeix el byte més significatiu de la temperatura
	movwf		Valor+1		; Ho prepara per convertir-ho a BCD
	movf		min,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		EscPant3	; Ho enviem a la pantalla
	movlw		b'11011111'
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'C'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		.20		; Comença un cicle de durada fixa (2 s)
	call		Retards		; Crida a la funció Retard, el paràmetre està a W
	call		Llegir		; Llegeix els valors del sensor
	andlw		0xFF		; Anem a veure si W és zero
	btfss		STATUS,Z	; Si és zero, and donarà zero
	goto		Bucle		; No és zero, tornem a llegir
					; És zero, lectura correcta
	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		'H'
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'='
	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 separem en 5 bytes
	call		EscPant3	; Ho enviem a la pantalla
	movlw		'%'		; Espai en blanc
	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		'T'		; Espai en blanc
	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
	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		EscPant3	; Ho enviem a la pantalla
	movlw		b'11011111'
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'C'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		0x40		; 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		'H'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'm'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'a'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'x'		; Espai en blanc
	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
	movf		maxim+1,w	; W té el màxim
	xorwf		Humit+1,w	; Comparem amb Lectura+1
	btfss		STATUS,Z	; Si Z = 1 eren iguals
	goto		DiferMax	; Si són diferents, provem el cas 2
	movf		maxim,w		; W té el màxim
	subwf		Humit,w		; W = Lectura - W = Lectura - max
	btfss		STATUS,C	; C = 1 si Lectura >= max
	goto		MaxMin		; Si és més petit, no cal fer res
	goto		MaxNou		; Si és més gran, cal guardar-lo
DiferMax
	movf		maxim+1,w	; W té el màxim
	subwf		Humit+1,w	; W = Lectura+1 - W = Lectura+1 - max+1
	btfss		STATUS,C	; C = 1 si Lectura+1 >= max+1
	goto		MaxMin		; Si és més petit, no cal fer res
MaxNou
	movf		Humit+1,w	; Copiem Lectura a max
	movwf		maxim+1
	movf		Humit,w
	movwf		maxim
MaxMin					; Recollim el mínim
	movf		minim+1,w	; W té el mínim
	xorwf		Humit+1,w	; Comparem amb Lectura+1
	btfss		STATUS,Z	; Si Z = 1 eren iguals
	goto		DiferMin	; Si són diferents, provem el cas 2
	movf		minim,w		; W té el mínim
	subwf		Humit,w		; W = Lectura - W = Lectura - min
	btfsc		STATUS,0	; C = 0 si Lectura < min
	goto		MinMajor	; Si és més gran, no cal fer res
	goto		MinNou		; Si és més petit, cal guardar-lo
DiferMin
	movf		minim+1,w	; W té el mínim
	subwf		Humit+1,w	; W = Lectura+1 - W = Lectura+1 - min+1
	btfsc		STATUS,C	; C = 0 si Lectura+1 < min+1
	goto		MinMajor	; Si és més petit, no cal fer res
MinNou
	movf		Humit+1,w	; Copiem Lectura a min
	movwf		minim+1
	movf		Humit,w
	movwf		minim
MinMajor
	movf		maxim+1,w	; Llegeix el byte més significatiu de la temperatura
	movwf		Valor+1		; Ho prepara per convertir-ho a BCD
	movf		maxim,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		EscPant3	; Ho enviem a la pantalla
	movlw		'%'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		.20		; Comença un cicle de durada fixa (2 s)
	call		Retards		; Crida a la funció Retard, el paràmetre està a W
	call		Llegir		; Llegeix els valors del sensor
	andlw		0xFF		; Anem a veure si W és zero
	btfss		STATUS,Z	; Si és zero, and donarà zero
	goto		Bucle		; No és zero, tornem a llegir
					; És zero, lectura correcta
	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		'H'
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'='
	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 separem en 5 bytes
	call		EscPant3	; Ho enviem a la pantalla
	movlw		'%'		; Espai en blanc
	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		'T'		; Espai en blanc
	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
	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		EscPant3	; Ho enviem a la pantalla
	movlw		b'11011111'
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'C'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		0x40		; 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		'H'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'm'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'i'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		'n'		; Espai en blanc
	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
	movf		minim+1,w	; Llegeix el byte més significatiu de la temperatura
	movwf		Valor+1		; Ho prepara per convertir-ho a BCD
	movf		minim,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		EscPant3	; Ho enviem a la pantalla
	movlw		'%'		; Espai en blanc
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	movlw		.20		; Comença un cicle de durada fixa (2 s)
	call		Retards		; Crida a la funció Retard, el paràmetre està a W
	goto		Bucle
Llegir					; Llegeix els valors al sensor
					; Primer activem el funcionament del sensor
	bsf		STATUS,RP0	; Tria el banc 1
	bcf		TRISA,2		; Posem 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 posem a 1
	movlw		0x01		; podrem 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, esperem la resposta
	bsf		STATUS,RP0	; Tria el banc 1
	bsf		TRISA,2		; Posem el pin com a entrada
	bcf		STATUS,RP0	; Tria el banc 0
					; Esperem 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 esperem
	clrf		TMR0		; Comencem a comptar el temps
Esp1I					; Esperem 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		; Mirem que no passem de 90 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 45
	goto		Esp1I		; És més petit, seguim esperant
	retlw		.1		; És més gran: Error 1 - Zero inicial massa llarg
ZeroIni					; El zero inicial ja està
					; Comprovem la durada
	movf		TMR0,w		; Agafa el valor actual del temps
	movwf		Temps		; i el guarda
	clrf		TMR0		; Comencem a comptar el temps per al següent
	movlw		.35		; Mirem 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 tenim el zero inicial
					; Ara l'entrada està a u i esperem que es posi a zero
Esp0I					; Esperem 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		; Mirem que no passem de 90 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 45
	goto		Esp0I		; És més petit, seguim 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		; Comencem a comptar el temps per al següent
	movlw		.35		; Mirem 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 tenim l'u inicial
					; Ara hem de rebre els bits
	movlw		.40		; Hem de rebre 40 bits
	movwf		Bits		; Aquesta variable els comptarà
BucBits
					; Esperem 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		; Comencem a comptar el temps
Esp1B					; Esperem 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		; Mirem que no passem de 90 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 45
	goto		Esp1B		; És més petit, seguim 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		; Comencem a comptar el temps per al següent
	movlw		.5		; Mirem 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 tenim el valor 0 del bit. Ara esperem un 1
Esp0B					; Esperem 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		; Mirem que no passem de 80 us
	subwf		Temps,w		; W = Temps - W
	btfss		STATUS,C	; C = 1 si Temps >= 40
	goto		Esp0B		; És més petit, seguim 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		; Comencem a comptar el temps per al següent
					; Ja hem comprovat que no passi de 80 us
					; Si és més petit que 12 us és massa curt
	movlw		.6		; Mirem 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 hem comprovat que no sigui massa curt
					; Si és més petit que 38 us és un pols curt, o sigui un 0
	movlw		.19		; Mirem 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		; Mirem 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 entrem un 0
	goto		EntraBit
EsUn1
	bsf		STATUS,C	; Si és un 1 entrem un 1
EntraBit				; Guardem el bit rebut
	rlf		Check,f		; Entrem per Check i anem 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 hem acabat, esperem el següent
	retlw		.0		; Lectura correcta
EscPant3				; Anem a enviar la lectura de 3 caràcters
	movlw		.2		; Cal fer-ho 3 cops
	movwf		Compta		; Ho posem al comptador
	movlw		Resul+2		; Adreça de la darrera xifra
	goto		EscPant
EscPant5				; Anem a enviar la lectura de 5 caràcters
	movlw		.4		; Cal fer-ho 5 cops
	movwf		Compta		; Ho posem 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, repetim
	movlw		','		; coma
	movwf		Caracter	; Ho guarda a la variable
	call		EnviaL		; Ho envia
	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		; Comença un cicle de durada fixa (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
	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
					;
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
	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
					;
Retus					; Funció de retard; W conté el nombre de cicles de 3 us que cal fer
	movwf		Retard1
Bucleus
	decfsz		Retard1,f
	goto		Bucleus
	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
Retards					; Funció Retard, W conté el nombre de cicles de 771 us que cal fer
	movwf		Retard3		; Ho copia a la variable Retard2
BucRets
	decfsz		Retard1,f	; Decrementa la variable 1
					; si dona zero, no es fa la instrucció següent
	goto		BucRets		; Salta, excepte si el resultat ha estat zero
	decfsz		Retard2,f	; Decrementa la variable 2
	goto		BucRets		; Salta, excepte si el resultat ha estat zero
	decfsz		Retard3,f	; Decrementa la variable 2
	goto		BucRets		; Salta, excepte si el resultat ha estat zero
	return				; Tornem al lloc des d'on hem vingut
					;
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		; 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		Compta,f	; Decrementa Compta
	goto		ajust		; Si no és zero, ajustem el resultat
	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
					;
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 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		Compta,f	; Decrementa el comptador
	goto		Bucle1		; Si no és zero, repetim
	movlw		.4		; Cal fer-ho 4 cops
	movwf		Compta		; 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		Compta,f	; Decrementa el comptador
	goto		Bucle2		; Si no és zero, repetim
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.