Programació en mpasm del PIC 16F690

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

Exemple PP - Visualitzem el valor del potenciòmetre a la pantalla

En aquest exemple llegirem el valor del potenciòmetre, el convertirem a BCD i mostrarem el resultat per la pantalla.

El programa és similar al de l'exemple EA però amb algunes diferències. Ara volem treballar amb tots els bits del conversor, per tant justificarem el resultat per la dreta i farem servir els dos bytes del resultat. El resultat el convertirem a 5 dígits BCD i aquests a ASCII. El resultat final el mostrarem a la pantalla paral·lel de 4 bits. Per emprar aquest programa cal tenir el contrast de la pantalla controlat externament ja que sinó quan canviem la posició del potenciòmetre no podrem llegir bé els valors. El programa que emprarem serà:

#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 
Control			; Bits de control (port B)
Caracter		; Caràcter o codi a enviar (port C)
Retard1			; Variables per als cicles de retard
Retard2
	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		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		0xFF		; Posa l'acumulador a FFh (tot uns)
	movwf		ANSEL		; Configura AN0-AN7 com entrades analògiques
	bcf		STATUS,RP0
	bcf		STATUS,RP1	; Tria el banc 0
	call		IniPant		; Inicialització del mode de funcionament de la pantalla
	call		ConfPant	; Configuració de la pantalla
	movlw		b'10000001'	; activa el conversor A/D connectat a AN0
	movwf		ADCON0		; amb el resultat justificat per la dreta
Bucle
	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
	movf		ADRESH,w	; Llegim byte superior del resultat
	movwf		Valor+1		; El guardem
	bsf		STATUS,RP0	; Tria el banc 1
	movf		ADRESL,w	; Llegim byte inferior del resultat
	bcf		STATUS,RP0	; Tria el banc 0
	movwf		Valor		; El guardem
	call		BCD5		; Ho converteix en BCD en 3 bytes
	call		Separa		; Ho separem en 5 bytes
	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
					; Anem a enviar la lectura
	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
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
	goto		Bucle
					;
					; Inicialització del mode de funcionament de la pantalla
					;
IniPant					
	movlw		0		; Els cicles de retard són de 0,2 s
	call		Retard		; Crida a la funció Retard
	call		Retard		; Crida a la funció Retard
	call		Retard		; Crida a la funció Retard
	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
					;
					; Configuració de la pantalla
					;
ConfPant				
	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
					;
					; Enviem 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
	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
					;
					; Funció Retard, W conté el nombre de cicles de 771 us que cal fer
					;
Retard					
	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
					;
					; Converteix a BCD
					;
BCD5					
	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)
					;
					; funció d'ajust d'un byte, primer el nibble de la dreta, després l'altre
					;
ajustBCD				
	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 els digits i els converteix a ASCII
					;
Separa					
	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

El valor del potenciòmetre és només de 10 bits. Podríem simplificar el programa per no haver de treballar amb 16 però hem considerat que no calia.

 

 

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