Programació en mpasm del PIC 16F690

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

Programes que fan servir dues pàgines de la memòria de programa

La memòria de programa interna del PIC16F690 té 4 k paraules dividides en dues pàgines. Les adreces de cada una de les pàgines són les següents:

Pàgina Adreces (decimal) Adreces (hexadecimal) Adreces (binari)
0 0   a   2047 000h   a   7FFh 0000 0000 0000   a   0111 1111 1111
1 2048   a   4095 800h   a   FFFh 1000 0000 0000   a   1111 1111 1111

Observem que les adreces requereixen nombres de dotze bits.

D'altra banda, les instruccions de salt del PIC16F690 només emmagatzemen adreces d'onze bits. Per tant, si no fem res especial, les dues instruccions següents anirien a parar al mateix lloc:

	goto		0x004
	goto		0x804

Si nosaltres tenim un programa que ocupa més de 2 kB ens apareixerà un missatge d'error quan intentem enviar el programa al microcontrolador:

	Error - section '.org_0' can not fit the absolute section. 

Aquest missatge ens diu que ha estat impossible posar tot el programa en una sola pàgina, en aquest cas la que comença a la posició 0 (org 0).

Per a poder tenir programes que ocupin més de 2 kB cal dividir-los en dues parts i posar-ne una part a cada pàgina. Una opció és posar el programa principal en la pàgina 0 i totes les funcions o una part d'elles a la pàgina 1.

Quan vulguem fer instruccions com goto i call hem de tenir present que les adreces que es guarden amb la instrucció són de només 11 bits. Els altres dos bits es guarden a les posicions corresponents (bits 3 i 4) del registre PCLATH. Així, per a saltar a l'adreça 804 faríem servir el següent tros de programa:

	bsf		PCLATH,3	; Canviem a la segona pàgina
	goto		0x804

o bé aquest altre (tots dos fan el mateix):

	bsf		PCLATH,3	; Canviem a la segona pàgina
	goto		0x004

El registre PCLATH no es modifica si no el toquem nosaltres, per tant els següents goto i els següents call seguirant sent a la pàgina 1 fins que tornem a desactivar els bits.

Cal tenir present que la pila on es guarden les adreces de retorn (per als return, retlw i retfie) sí que és de 13 bits i, per tant, retorna a la pàgina des d'on s'ha saltat i no modifica els bits 3 i 4 de PCLATH.

Així doncs, la manera més habitual de treballar serà la que expliquem a continuació. Quan hem de saltar a una posició de la pàgina 1 farem:

	bsf		PCLATH,3	; Canviem a la segona pàgina
	goto		AdrPag1

I quan haguem de tornar a la pàgina 0 farem:

	bcf		PCLATH,3	; Tornem a la primera pàgina
	goto		AdrPag0

A l'hora de fer la crida a una funció que està a la pàgina 1, el més habitual serà:

	bsf		PCLATH,3	; Canviem a la segona pàgina
	call		FuncPag1
	bcf		PCLATH,3	; Tornem a la primera pàgina

En aquest cas (si no modifiquem PCLATH) tots els goto (i els call) que hi hagi en la funció aniran a la pàgina 1. El retorn de la funció (return o retlw) torna a la pàgina 0 però no modifica PCLATH i, per tant, el modifiquem nosaltres després (si cal).

El següent programa intenta mostrar com funciona el canvi de pàgina. La primera part del programa està situada a la pàgina 0 (org 0x000) i el programa encén primer el LED 1 i passat un segon l'apaga i encén el 2. Passat un altre segon tornaria a repetir encenent el LED 1.

Hi ha un altre programa gairebé igual posat a la pàgina 1 (org 0x800) que només canvia en el fet que els LED que hi intervenen són el 3 i el 4. En el programa de la pàgina 1 hem substituït per nop les quatre primeres instruccions perquè, de fet, no s'executaran mai i l'objectiu és que la resta de programa es correspongui en les adreces (és a dir que cada instrucció de la pàgina 1 estigui en la mateixa adreça que la de la pàgina 0 però sumant-hi 800h). Al programa s'hi han afegit dues instruccions (marcades en groc) que fan que cada cop que s'arriba al final del bucle es salti a l'altra pàgina. El resultat serà que primer s'activarà el LED 1, després el 2; després es saltarà de pàgina i s'activarà el 3, després s'activarà el 4 i, finalment, es tornarà a saltar de pàgina i haurem tornat a veure activar el LED 0. El resultat, doncs, serà una rotació de LED.

#include <p16F690.inc>
	__config (_INTRC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_OFF&_MCLRE_OFF&_CP_OFF&_BOR_OFF&_IESO_OFF&_FCMEN_OFF)
	cblock	0x20
Retard1			; Variables de retard	
Retard2
Retard3
	endc
	org 0x000
Inici
	bsf		STATUS,RP0	; Tria el banc 1
	movlw		0xFF		; Posa l'acumulador a FFh (tot uns)
	clrf		TRISC		; Posa tots els bits del port C com a sortida
	bcf		STATUS,RP0
Bucle
	movlw		b'00000001'	; Encén el LED 1 (el més proper al polsador)
	movwf		PORTC
	movlw		.5		; Bucle de retard d'un segon
	call		Rets
	movlw		b'00000010'	; Encén el LED 2
	movwf		PORTC
	movlw		.5		; Bucle de retard d'un segon
	call		Rets
	bsf		PCLATH,3	; Canviem a la segona pàgina
	goto		Bucle		; Salta a Bucle8
					;
					; Funció de retard de 0,2 W s
					;
Rets
	movwf		Retard3
Bucles
	decfsz		Retard1,f		
	goto		Bucles		
	decfsz		Retard2,f		
	goto		Bucles		
	decfsz		Retard3,f	
	goto		Bucles
	return
	org 0x800
Inici8
	nop				; Substitueix a bsf
	nop				; Substitueix a movlw
	nop				; Substitueix a clrf
	nop				; Substitueix a bcf
Bucle8
	movlw		b'00000100'	; Encén el LED 3
	movwf		PORTC
	movlw		.5		; Bucle de retard d'un segon
	call		Rets8
	movlw		b'00001000'	; Encén el LED 4
	movwf		PORTC
	movlw		.5		; Bucle de retard d'un segon
	call		Rets8
	bcf		PCLATH,3	; Canviem a la primera pàgina
	goto		Bucle8		; Salta a Bucle
					;
					; Funció de retard de 0,2 W s
					;
Rets8
	movwf		Retard3
Bucles8
	decfsz		Retard1,f		
	goto		Bucles8		
	decfsz		Retard2,f		
	goto		Bucles8		
	decfsz		Retard3,f	
	goto		Bucles8
	return
	end

Quan ja tenim el codi màquina, podem fer:

View Program Memory

I se'ns obrirà una finestra on veurem el nostre programa en codi màquina i també en ensamblador però amb tots els paràmetres en forma numèrica hexadecimal. D'aquesta visualització hem agafat els dos trossos de programa que hem creat:

Program Memory       Program Memory

Si ens hi fixem, veurem que els dos trossos són gairebé iguals i que, en concret, les adreces que hi ha a les instruccions goto i call dels dos costats són iguals.

En el PIC16F690 podem tenir també 4 kB de memòria externa. En cas de tenir-la, podríem adreçar-nos-hi activant el bit 4 de PCLATH.

Una forma alternativa de saltar a una altra pàgina és fer servir l'opció pagesel. Per exemple:

	pagesel		Bucle8		; Canviem de pàgina
	goto		Bucle8		; Salta a Bucle8

 

 

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