Autor Tema: Sobre cambio de pagina en 16f877  (Leído 3019 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado CMECKARDT

  • PIC10
  • *
  • Mensajes: 5
Sobre cambio de pagina en 16f877
« en: 08 de Febrero de 2004, 10:41:00 »
  hola a todos, logre solucionar mi problema de cambio de paginas en el programa... para los que se consigan con este problema en el futuro les brindo la respuesta
                ...
                ...
   movlw    HIGH Sub_rut
   movwf    PCLATH
                CALL        Sub_rut
                ...
                ...

y en la subrutina que debe estar en otro banco antes de hacer el RETURN hay que decir a que pagina se quiere regresar... es decir la pagina de donde se hizo el llamado a CALL

                ...
                ...
                BCF       PCLATH,3
                BCF       PCLATH,4
                RETURN

 asi devuelve a la pagina 0...  revisen el data sheet para identificar las paginas en el registro PCLATH... que son los bits 3:4 del registro


importante  esto no solo funciona en el f877 funciona por igual en casi todos los PIC

espero que le sirva a alguien  


Desconectado elreypic

  • PIC12
  • **
  • Mensajes: 79
RE: Sobre cambio de pagina en 16f877
« Respuesta #1 en: 08 de Febrero de 2004, 11:52:00 »
Que tal CMECKARDT!!!. Es muy buena idea la tuya para cambiar de página. Te parece bien si te paso otro tip para hacerlo?

Yo utilizo la directiva PAGESEL del asembler, pero cómo funciona?

Bien sencillo, vamos suponer que tienes una subrutina en las páginas 2 o superior, y esta se llama INI_LCD, al utilizar esta directiva la podrás llamar desde cualquier página y el asembler configura automáticamente el PCLATH, el código sería pues:

PAGESEL INI_LCD
CALL LCD

También se puede utilizar la directiva LCALL, es decir:

LCALL LCD

Con esta directiva no importa en cual página se encuentre tu subrutina. Cabe hacer mención que esta directiva lo que realmente hace es, agregar automáticamente dos instrucciones de BSF o BCF al PCLATH, es decir, si la subrutina se encuentra en la página 2, entonces lo que hace es agregar:

bsf pclath,3
bcf pclath,4

Si la subrutina se encuebtra en la página 3, entonces la directiva agrega:

bcf pclath,3
bsf pclath,4

y así sucesivamente.

Esta directiva también funciona con los saltos largos utilizando el GOTO. Ejemplo:

Suponiendo que deseas hacer un salto a una etiqueta o procedimiento que está mas alla de los 2K (es decir de la página 2 en delante) y la etiqueta se llama ROTAR, entonces, el código sería:

PAGESEL ROTAR
goto ROTAR.

También se puede utilizar la instrucción LGOTO que es equivalente a lo anterior, es decir:

LGOTO ROTAR

Las anteriores directivas también agregan los BSF y BCF a los bits 3 y 4 del registro PCLATH, por lo que se debe tener cuidado, al utilizarlos.

Por ejemplo:

btfss status,c
goto ROTAR
bcf status,c

Si tomamos el ejemplo anterior mencionaba, que ROTAR se encuentra mas allá de los 2K, por lo que una forma incorrecta sería hacer lo siguiente:

btfss status,c
LGOTO ROTAR
bcf status,c

Pero, porqué lo anterior no es correcto? Recordando nuevamente:

LGOTO y LCALL agregará dos instrucciones en donde se coloque la directiva, entonces realmente nuestro código es:

btfss status,c
bsf pclath,3
bcf pclath,4
goto ROTAR
bcf status,c

lo anterior nos provoca un error de lógica, por lo que se tiene que utilizar el PAGESEL como la solución adecuada, que dando entonces, nuestro código, de manera correcta:

PAGESEL ROTAR
btfss status,c
goto ROTAR
bcf status,c

Lo anterior también aplica para el LCALL.

Bueno espero y esto te sea de utilidad.

Nota: Estas directivas son válidas par el MPASM de microchip.

Desconectado CMECKARDT

  • PIC10
  • *
  • Mensajes: 5
RE: Sobre cambio de pagina en 16f877
« Respuesta #2 en: 08 de Febrero de 2004, 23:09:00 »
     Gracias, elreypic, no sabia como funcionaban los Lcall y Lgoto... aunque en algun momento probe con el PAGESEL y PAGESELW.. con las cuales no tuve mas que un PIC colgado... ... ahora me queda la duda y si me la puedes responder me gustaria..

  hago mis llamados ya sea con el PAGESEL o con LCALL...  salte a la otra pagina perfecto hizo lo debido.. y cuando voy de regreso con RETURN necesito cargar el PCLATH <3:4> con la pagina de donde hice el llamado o ellas por si solas hacen estos cambios???

  sabes lo que dije antes sobre cuando voy de regreso antes del return setear o borrar los bits del PCLATH para que vuelva a la pagina??

Desconectado elreypic

  • PIC12
  • **
  • Mensajes: 79
RE: Sobre cambio de pagina en 16f877
« Respuesta #3 en: 09 de Febrero de 2004, 10:38:00 »
Que tal. Pues mira cuando utilizas los PAGESEL, LCALL al utilizar el RETURN, el apuntador o contador de programa regresa a PC + 1, es decir una instrucción después de donde fue llamada la subrutina, es decir a la página 1,2, etc. La consideración que debes tener es que el PCLATH contiene los ultimos bits cargados al utilizar el LCALL o el PAGESEL. Esto quiere decir que si en la continuación de tu programa existe otro CALL, pero este esta dentro de la página cero entonces provocarás un error de salto.

Para eliminar este problema lo que Microchip recomienda, es que cuando ya has utilizado los PAGESEL, LCALL y/o LGOTO, será necesario utilizarlos en todo el programa, es decir ahora tendrás que agregar PAGESEL siempre que lo requieras en tu programa.

Espero haber sido claro. Lo que en realidad pasa es que no tienes que resetear los bits del PCLATH antes del return, ya que esta intrucción abarca completamente todas las páginas de memoria, de lo que te debes preocupar es al realizar un salto u otra llamada a subrutina, agregando el PAGESEL respectivo antes de realizarlo.

Desconectado FirmSoft

  • PIC16
  • ***
  • Mensajes: 118
RE: Sobre cambio de pagina en 16f877
« Respuesta #4 en: 04 de Enero de 2005, 14:19:00 »
   Tengo Mplab IDE 6.60 y todo actualizado al dia.. pero al intentar utilizar la directiva PAGESEL el mplab me avisa que no puede reemplazar la directiva por el codigo correspondiente. Programo un F84A, Eso puede ser el problema?... alguien sabe como puedo reemplazar esa directiva? . Gracias y Saludos!