Cambio de páginas en los PIC y uso del PCLATH

no, no son los bancos de memoria, gracias igual.

cito algo que es de otro foro:
Estás confundiendo los bancos de memoria RAM con las páginas de la memoria de programa. Los cambios de bancos son para la memoria RAM y escribir datos en la memoria RAM o ver los estados de los diferentes registros ubicado en la RAM.

Lo que tu quieres hacer es con las páginas de la memoria de programa y se hace con la directiva org. Tienes que dirigirte al datasheet del microcontrolador y ver hasta que direccionamiento cambia de página.
extraido de
http://www.ucontrol.com.ar/forosmf/programacion-en-asm/como-hago-para-escribir-codigo-en-otro-banco-del-pic16f628a/?wap2
 
El contador del programa, para los microcontroladores de Rango Medio esta formado por dos registros:

PCL = contiene los primeros 8 bits del contador del programa, por lo tanto maneja hasta un máximo de 256 líneas de código.

PCLATH = contiene los últimos 5 bits del contador de programa, por lo tanto maneja, en conjunto con el PCL, hasta 8192 líneas de código.

¿Cómo influye el contador del programa en el desarrollo de mi programa?

Dependiendo de la memoria flash que tenga tu microcontrolador, 2048 líneas para el 16F628A, y de como coloques tu programa dentro de la memoria, el correcto funcionamiento de tu programa puede verse afectado por una mala paginación.

¿Como se realiza la paginación del código?

Para los microcontroladores de medio rango los primeros 11 bits del contador del programa (los 8 del PCL y los tres primeros de PCLATH (PCLATH<2:0>)) se cambian automáticamente, es decir, no es necesario manejarlos de manera manual, puedes realizar instrucciones como CALL y GOTO entre las 2048 líneas de una pagina sin ningún problema de paginación dentro de ella.

El problema viene cuando necesitas llamar una rutina que se encuentra fuera de la página que estas trabajando, es decir, cuando necesitas manejar los últimos dos bits del contador (PCLATH <4:3>) pues estos es necesario que se manejen de manera manual.

Ejemplo:

Código:
;----------------------------------------------------------------------------------------
	ORG		0x0000					;PAGINA 0 DEL PIC
CICLO_PAG_0
	;AQUI LLAMAREMOS UNA FUNCION QUE SE ENCUENTRA EN LA PAGINA 0
	
	CALL	FUNCION_0_PAGINA_0		;AQUI NO HAY PROBLEMA DE PAGINACION PUES ESTAS LLAMANDO 
									;UNA FUNCION QUE SE ENCUENTRA ENTRE LAS 2048 LINEAS
									;QUE COMPRENDE ESTA PAGINA, LA PAGINA 0
									
	;AQUI LLAMAREMOS UNA FUNCION QUE SE ENCUENTRA EN LA PAGINA 1, ES DECIR UNA FUNCION QUE ESTA
	;EN LAS SEGUNDAS 2048 LINEAS
									
	BSF		PCLATH,3				;ACCEDEMOS A LA PAGINA 1 DEL PROGRAMA DEL PIC
	CALL	FUNCION_0_PAGINA_1		;LLAMAMOS A UNA FUNCION DE LA PAGINA 1
	BCF		PCLATH,3				;VOLVEMOS A REGRESAR EL CONTANDOR DEL PROGRAMA A LA PAGINA 0
	
;NOTA:		SE MENCIONA EN EL DATASHEET QUE: PUEDES O NO REESTABLECER EL VALOR CORRECTO DEL PCLATH
;			CUANDO REGRESAS DE UNA FUNCION, PERO TE RECOMIENDO QUE LO HAGAS, PUES SI LO OLVIDAS, 
;			CUANDO REALICES EL LLAMADO DE OTRA FUNCION, YA SEA QUE SE ENCUENTRE EN LA PAGINA QUE 
;			QUIERES O EN OTRA, PUEDES TENER PROBLEMAS CON EL HILO DE COMO SE LLEVA A CABO TU PROGRAMA	
	
	;AQUI LLAMAREMOS OTRA FUNCION QUE SE ENCUENTRA EN LA PAGINA 0
	
	CALL	FUNCION_1_PAGINA_0
		
FUNCION_0_PAGINA_0
	;CODIGO DE LA FUNCION
	;
	;
	RETURN
	
	
FUNCION_1_PAGINA_0
	;CODIGO DE LA FUNCION
	
	;DENTRO DE ESTA FUNCIÓN, LLAMAMOS A OTRA FUNCION QUE SE ENCUENTRA EN LA PAGINA 1	
	BSF		PCLATH,3
	CALL	FUNCION_1_PAGINA_1
	BCF		PCLATH,3		
	;
	RETURN
	GOTO		CICLO_PAG_0

;----------------------------------------------------------------------------------------
ORG		0x0800						;PAGINA 1 DEL PIC
	
FUNCION_0_PAGINA_1
	;CODIGO DE LA FUNCION			;TODO ESTE CODIGO SE ENCUENTRA EN LA PAGINA 1 DEL PIC
	;
	;
	RETURN
		
FUNCION_1_PAGINA_1
	;CODIGO DE LA FUNCION

	;AQUI LLAMAMOS A UNA FUNCION QUE SE ENCUENTRA DENTRO DE LA PAGINA 0				
	BCF		PCLATH,3
	CALL	FUNCION_0_PAGINA_0
	BSF		PCLATH,3
	
	;CODIGO DE LA FUNCION
	;
	RETURN
	
	
	END

Esto también puede afectar cuando haces los "INCLUDE" de las librerías, pues si las librerías se encuentran entre paginas, debes de saber en que paginas se encuentran estas para no causar problemas.
En tu caso, no debes de tener ningún problema de paginación manual, pues tu microcontrolador solo maneja 2048 líneas de código, es decir, no es necesario manejar PCLATH<4:3>, esas líneas se manejan de manera automática con los 11 bits del contador del programa. Pero no esta de mas saberlo para cuando migres a microcontroladores de mayor memoria flash.
 
Al igual que BANKSEL, PAGESEL es tomado por el compilador como un comando a ser convertido a ensamblador, solo que PAGESEL es utilizado para hacer cambios de pagina del programa (memoria flash) y BANKSEL se utiliza para hacer cambios en los bancos de memoria RAM y registros especiales del micro controlador.

Cuando utilizas BANKSEL tienes que especificar el registro al que te quieres dirigir, por ejemplo:

BANKSEL.PNG

CMCON se encuentra en el banco 1 de la memoria RAM de PIC16F873A,874A,876A y 877A; por lo tanto es necesario realizar el cambio de los bits STATUS <RP1:RP0>. Y es lo que hace la comando BANKSEL, cambia esos bits para asegurarte de que estés en el Banco adecuado.

Ahora, te muestro la misma rutina, pero en ensamblador:

BANKSELASM.PNG

NOTA: Te preguntaras por que en el "Program Memory" aparece MOVWF CCPR2H en lugar de aparecer MOVWF CMCON como la instrucción lo pide. Bueno, pues es un "error" que tiene IDE, en realidad lo que sucede es que, si vas al Datasheet, CCPR2H y CMCON están a la misma "altura" de bancos:

CCMCON.PNG

Y los toma como si se tratase del mismo registro, pero no, el puntero se dirige al registro CMCON, de ahí se origina el famoso mensaje:

Message[302]C: ... Register in operand not in bank 0. Ensure that bank bits are correct.

El cual eliminas con: errorlevel -302





Ahora, y disculpa que te haya tirado el choro acá arriba pero es mejor demostrar con ejemplos, te muestro lo de PAGESEL.

Funciona de la misma manera que BANKSEL. Es un comando que toma MPLAB para convertir a ensamblador. Solo que aquí, en lugar de darle como referencia un Banco de trabajo, le das como referencia una etiqueta, es decir:

PAGESEL.PNG

Y la instrucción es cambiar los bits de PCLATH. Como podrás darte cuenta, lo que se hace es poner el comando PAGESEL seguido de la etiqueta, esto te dirigirá a la pagina en la que se encuentra esa etiqueta y después puedes llamar a esa etiqueta y a cualquier otra que se encuentre dentro de esa misma página, solo recuerda que cuando ya no vayas a trabajar con funciones o etiquetas de esa pagina debes de regresar a la página en la que estabas trabajando, puedes volver a utilizar PAGESEL y poner la etiqueta de una función que se encuentre en esa pagina, por que, cabe aclarar, PAGESEL no te dirige a funciones, te dirige a paginas donde se encuentran esas funciones, yo puedo venir y poner:

Código:
	PAGESEL    FUNCION_0_PAG_1 
	;PERO DESPUES VENIR Y LLAMAR A 
	CALL        FUNCION_1_PAG_1

Ahora, te muestro como se hace en ensamblador:

PAGESELASM.PNG

Si te das cuenta, aquí me ahorre una línea de código al poner solo BSF PCLATH,4; puesto que yo sabia que me encontraba trabajando en la pagina 0 (unas cuantas líneas arriba estaba el código ORG 0x0000), solo hice el cambio de PCLATH,4 para dirigirme a la pagina 2.

Como te darás cuenta son exactamente lo mismo, solo que PAGESEL y BANKSEL siempre tomaran 2 líneas de código de ensamblador puesto que no sabe en que página o banco se encuentran trabajando. Tú como programador sabes en que banco y pagina trabajas y puedes ahorrarte unas cuantas líneas de código al saber eso, líneas que te ahorran tiempo de procesamiento.

Esos cambios de banco y de pagina son en los que muchas veces los compiladores, no dedicados a ensamblador, abusan y generan "código basura" y te consumen memoria flash.
 
Última edición:
En tu caso, no debes de tener ningún problema de paginación manual, pues tu microcontrolador solo maneja 2048 líneas de código, es decir, no es necesario manejar PCLATH<4:3>, esas líneas se manejan de manera automática con los 11 bits del contador del programa. Pero no esta de mas saberlo para cuando migres a microcontroladores de mayor memoria flash.

o sea que no puedo tener mas de una tabla en mi programa con un pic 16f628?
segun entiendo cada tabla se relaciona con una pagina. y entonces a que se refieren en http://www.puntoflotante.net/tablas.htm cuando hablan de las 8 paginas del pic 16f628???

muchas gracias, saludos
 
Última edición:
o sea que no puedo tener mas de una tabla en mi programa con un pic 16f628?

No, nada tienen que ver las tablas con las paginas. excepto que una table se coloca dentro de una pagina, o varias paginas. y puedes tener tantas tablas como quepan en la memoria de programa.

por ejemplo aqui dice

Finalmente se ofrece un ejemplo de manejo de tablas y arreglos de datos: en este archivo se muestra un programa de ejemplo que accesa y transfiere a RAM los elementos de una tabla de 16 datos en la página 0 de la memoria de código:

el compañero a lo que se refiere es que en el 16f628 el cambio de esas paginas es automatico y no es necesario utilizar el PCLATH, en pic mas grandes o de mas de 8 paginas hay que hacerlo manual, sin descartar que en el 628 puedes hacerlo manual.

y entonces a que se refieren en http://www.puntoflotante.net/tablas.htm cuando hablan de las 8 paginas del pic 16f628???

la memoria del 16f628 es de 2048 lo divides entre 256 de cada pagina te da 8 paginas
 
Última edición:
Atrás
Arriba