Autor Tema: Problema con el tamaño de un programa  (Leído 3804 veces)

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

Desconectado pepe-grillo

  • PIC10
  • *
  • Mensajes: 13
Problema con el tamaño de un programa
« en: 11 de Mayo de 2006, 14:18:18 »
Hola a todos!!

Estoy trabajando con un pic 16F877A, tengo implementadas rutinas de conversion A/D, transmision serial (al PC), transmision de datos via SPI a otro pic..., ademas manejo algunas interrupciones en el puerto B y del TMR0.

Todo mi programa esta escrito en assembler. Estoy trabajando con MPLAB 7.31 y mi programador es un JDM manejado con el WinPic800 (excelente software para programar).

Todo mi programa funciona bien, tiene apenas 300 palabras de las 8000 posibles, pero al agregar mas o menos 10 instrucciones mas (por ejemplo 10 NOP seguidos), ya nada funciona. Esto lo descubri debido a que necesitaba agregar algo mas en una parte del codigo, pero no se que sucede, todo simplemente deja de funcionar.

Mi pregunta es sobre las limitaciones del winpic800, existe la posibilidad que solo pueda quemar programas de un tamaño menor a 300 lineas?.

No creo que sean problemas en el PIC, debido a que ensaye con tres PICs 16f877A y con un 16f877, y en todos sucede el mismo problema.

Muchas gracias por todo

pepe-grillo

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Problema con el tamaño de un programa
« Respuesta #1 en: 11 de Mayo de 2006, 17:19:08 »
Hola. ¿Tu programa utiliza subrutinas con tablas dentro?
Las tablas se realizan sumando un valor al PC del PIC.
Una tabla se vería asi:


call GetValue
...
...
...
GetValue movf agregar,w
addwf PCL.F
retlw 0x10
retlw 0x80
...
...
...

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado pepe-grillo

  • PIC10
  • *
  • Mensajes: 13
Re: Problema con el tamaño de un programa
« Respuesta #2 en: 11 de Mayo de 2006, 23:32:24 »
Hola BrunoF!!

Si, en mi programa utilizo una rutina para convertir el valor binario de un numero (por ejemplo 3 = 00000011), en un numero del codigo ascii para enviarlo via serial. Y como vos lo describes, en esat subrutina le agrego al PCl el valor deseado para el "salto" y luego retorne. ¿Esto genera algun problema?

Muchas gracias.

pepe-grillo
« Última modificación: 11 de Mayo de 2006, 23:35:23 por pepe-grillo »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Problema con el tamaño de un programa
« Respuesta #3 en: 12 de Mayo de 2006, 01:04:09 »
Sí lo genera cuando no se toman los recaudos necesarios.
Te explico.
Si tu/s tabla/s está/n dentro de las primeras 256 líneas de código ENSAMBLADO, no hay problemas, y no hay necesidad de tomar precauciones. Cuando la/s tabla/s está/n cruzando o mas allá de las primeras 256 líneas sí hay que tomar ciertos recaudos.
Lo que ha sucedido es que los 10 nop que agregaste, desplazaron la tabla de lugar, haciendo que la mísma se grabe más adelante en la FLASH del PIC.Por lo tanto, tu tabla está, o bien cruzando estos pasos cada 256 líneas, o bien directamente más alla de los primeros 256.
El comportamiento del PIC es el siguiente:
El PC(PCL) se autoincrementa(cuando se ejecuta una linea(obviamente descartemos las excepciones tales como goto,call,etc)).Cada 256 líneas sucede un overflood cuando el PCL pasa de valer 0xff a 0x00. Cuando esto sucede, el PCLATH se incrementa en 1. Es decir, que en realidad, al contador del programa lo tenemos seccionado.
Generalmente en 3 partes(esto depende del PIC):

Y si lo uniésemos, obtendríamos algo asi:

XX  XXXXXX XXXXXXXX

Cada X asociada a un bit correpondiente a:

STATUS,RP1  STATUS,RP0  registro PCLATH  registro PCL

Si bien esto puede depender del pic utilizado, ya que, por ejemplo, los PICs pequeños no tienen implementados ciertos registros(no los necesitan ya que poseen menos memoria FLASH), básicamente es asi.
Entonces, supongamos un pic con 1K de memoria FLASH.Esto sería, 1024 líneas.
Cada uno de estos pasos que mencioné abarca 256 líneas(1 Byte).
Entonces, a un PIC con 1K de memoria, lo tenemos seccionado en 4 sub-bancos:

Desde la posición 0x000 hasta la 0x0FF
Desde la posición 0x100 hasta la 0x1FF
Desde la posición 0x200 hasta la 0x2FF
Desde la posición 0x300 hasta la 0x3FF

Tu tabla NUNCA debe cruzar desde un sub-banco a otro. Es decir, que la tabla NO DEBE ir ubicada en posiciones de la FLASH que crucen justo dos sub-bancos.
Entonces, veamos cómo hacer para que no las cruce.
Lo que yo hago generalmente, es tratar de ubicar las tablas dentro de las primeras 256 posiciones de la FLASH del PIC.
En caso de que por X motivo no se pueda(demasiadas tablas,etc) las ubico en el ultimo sub-banco del primer banco del PIC.
Mirandolo desde la práctica:
Un asm podría ser asi:

org  0x00
goto inicio
;más código acá

inicio nop
;más código acá

org 0x300  ;apunto a la primer posición del último sub-banco de la FLASH (suponiendo un PIC de 1K, claro está)
TABLA MOV VALOR;W
          ADDWF PCL,F
          RETLW 0x60
          ;más código acá
          end
Al hacer esto, me aseguro que la tabla no cruce ningún sub-banco.
Obviamente, si tenes muchas tablas, asegurate que ninguna cruce ningún sub-banco.
Una vez contemplado esto, procederemos a cargar el valor correcto del PCLATH mediante SOFTWARE antes de llamar a la tabla.
Por lo tanto, vuelvo a plantear el asm:

org  0x00
goto inicio
;más código acá

inicio nop
        BANKSEL TABLA ;instrucción que carga los registros del contador con los valores donde está ubicada la etiqueta "TABLA".
        call TABLA
;más código acá

org 0x300  ;apunto a la primer posición del último sub-banco de la FLASH (suponiendo un PIC de 1K, claro está)
TABLA MOV VALOR;W
          ADDWF PCL,F
          RETLW 0x60
          ;más código acá
          end

Listo. Nos aseguramos que la tabla no cruce ningún sub-banco, y que el PCLATH sea previamente cargado con los valores correctos antes de llamarla.
Espero no haberte mareado, y que haya quedado claro. Si no lográs hacerlo funcionar, posteá el código y lo solucionamos.
Saludos.








"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado pepe-grillo

  • PIC10
  • *
  • Mensajes: 13
Re: Problema con el tamaño de un programa
« Respuesta #4 en: 12 de Mayo de 2006, 12:29:38 »
Hola BrunoF!!

Tremenda respuesta la que me has dado. Yo creo que ese es el problema. Jamas me habia imaginado esto de los bancos (como uno siempre trabaja con el PCL simple), pero ahora todo tiene mas sentido. Voy a correr esta subrutina al principio (despues de inicio) pues solo tengo una tabla, que ademas es solo de los 10 primeros numeros (0-9). Yo creo que con eso no es necesario hacer mayores arreglos. Ahora mismo lo pruebo y te cuento apenas termine.

Muchas gracias por tu respuesta, en verdad que estuvo excelente!!!

pepe-grillo


Desconectado pepe-grillo

  • PIC10
  • *
  • Mensajes: 13
Re: Problema con el tamaño de un programa
« Respuesta #5 en: 12 de Mayo de 2006, 13:29:20 »
Hola BrunoF!!

Estuve mirando el codigo del programa como lo muestra la ventana program memory, y sucedia lo que vos habias predicho, ya lo he corregido subiendo simplemente la subrutina aunque no lo he probado, en la ventana del program memory si se observa que la subrutina si se encuentra en el inicio del primer banco de memoria.

Muchas gracias BrunoF. Realmente no entendia porque este programa no me funcionaba, además que me has enseñado algo nuevo de lo que no tenia idea.

Saludos.

pepe-grillo

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Problema con el tamaño de un programa
« Respuesta #6 en: 12 de Mayo de 2006, 14:59:58 »
Pues... de nada!!. Espero que no tengas mas problemas. Cualquier cosa me avisas.
Exitos!
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Syphroot

  • PIC10
  • *
  • Mensajes: 3
    • Sistemas Digitales - SPTech
Re: Problema con el tamaño de un programa
« Respuesta #7 en: 28 de Mayo de 2006, 17:49:09 »
Hola BrunoF. Soy nuevo en el foro y he mirado este post porque tengo un problema similar.

He probado lo que dices y no me ha funcionado, ademas he checado exactamente para
que sirve BANKSEL y si, efectivamente es para ajustar los valores del STATUS y
acceder a la memoria SRAM y no a la de programa...  :(

tengo muchas tablas que aloje asi:

org 0x200
      #include "Uchars.inc"
org 0x300
      #include "Lchars.inc"

El contenido de los "inc" es algo parecido a esto

ChrA      addwf PCL,F
         dt b'01111110', b'10010001', b'10010001', b'10010001', b'11111110'
ChrB      addwf PCL,F
         dt b'01111111', b'11001001', b'11001001', b'11001001', b'10110110'
.
.
.
En si cada archivo contiene 27 tablas que me definen los valores del abecedario para
una matriz de Led de 7 x 5. Todas las tablas caben perfectamente entre cada pagina
de programa y no excede la frontera como dices...

Mi codigo que utiliza estas tablas lo tengo en las primeras 2 paginas de programa (00h-FF,100- 1FF)
Nota: Utilizo un pic 16F627A

Me di cuenta que al ensamblar me ponia mensajes de advertencia de que no generó codigo para
los BANKSEL y que ademas la locacion de RAM es incorrecta. El mensaje es el siguiente:

Warning[219] C:\16F627\MATRIX.ASM 46 : Invalid RAM location specified.

en la linea 46 tengo el BANKSEL.

Investigando encontre que para hacer lo mismo pero para bancos de memoria de programa y no de RAM
se utiliza PAGESEL o PAGESELW... Lo probe pero aun asi no se resulve el problema, ya que simulando
con el propio MPLAB se carga correctamente el PCLATH y recoge el valor de la tabla pero al retornar
me brinca instrucciones y se cuelga el programa con un loop infinito en la direccion 0000h.

Pongo el segmento de codigo que es una macro:

Llenar   macro Buffer,Frames
local nextb
      movlw PTR       ;PTR = 20h
      movwf FSR   ;
nextb        movf FSR,W     ;
      andlw 0Fh        ;
      BANKSEL Buffer   ; AKI ESTA EL BANKSEL, TAMBIEN PROBE CON PAGESEL y no =(
      call Buffer
      movwf INDF
      incf FSR
      movlw PTR+5
      subwf FSR,W
      btfss STATUS,Z
      goto nextb           ; aki tambien se produce un problema,: PCLATH > 0  esto lleva a la dir 00h y se estanca
      movlw Frames
      call Barrer
      
      endm

En si lo que deberia hacer la macro es Llenar desde 20h hasta 25h con los valores de la tabla (algo asi como un buffer de video)

Despues que ya esta listo el buffer la Subrutina "Barrer" hace un barrido a la matriz de leds con el Buffer que cargamos,
esto lo hace el numero de veces especificado en la constante "Frames" , esto si funciona ok =)...

No se que es lo que pasa ezactamente y no funciona, ahorita acabo de bajar una nota de aplicacion de Microchip
referente a esto ( http://ww1.microchip.com/downloads/en/AppNotes/00586b.pdf  AN586 - Macros for Page and Bank Switching ) , pero aun asi espero de su ayuda...

Gracias de antemano

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Problema con el tamaño de un programa
« Respuesta #8 en: 28 de Mayo de 2006, 22:47:34 »
Hola. Bueno, antes que nada, fue un error mio. La funcion correcta era la PAGESEL, no la BANKSEL, se me chispoteo :D :-)
En fin, obviamente con la BANKSEL te va a tirar un error, porque BANKSEL se utiliza para setear los valores RP0 y RP1 del STATUS, segun donde este ubicada la variable a utilizar, nada que ver con lo que vos necesitas.
Vos necesitas que se cargue el PCLATH con los valores correctos para poder redireccionarte a otras paginas.

Tu macro decis que es asi:

Llenar   macro Buffer,Frames
local nextb
      movlw PTR       ;PTR = 20h
      movwf FSR   ;
nextb        movf FSR,W     ;
      andlw 0Fh        ;
      BANKSEL Buffer   ; AKI ESTA EL BANKSEL, TAMBIEN PROBE CON PAGESEL y no =(
      call Buffer
      movwf INDF
      incf FSR
      movlw PTR+5
      subwf FSR,W
      btfss STATUS,Z
      goto nextb           ; aki tambien se produce un problema,: PCLATH > 0  esto lleva a la dir 00h y se estanca
      movlw Frames
      call Barrer
     
      endm

Bueno, nunca fui partidario de las macros, ya que, a mi parecer, son un desperdicio gigante de memoria FLASH, y prefiero hacer una buena sub-rutina que reemplace a la macro.

Proba haciendo esto:

Llenar   macro Buffer,Frames
local nextb
      movlw PTR       ;PTR = 20h
      movwf FSR   ;
nextb
      PAGESELW Buffer    Cargar en W el valor del sub banco donde se ubica la sub rutina "Buffer"
      movwf PCLATH       Volcar en el registro PCLATH el valor obtenido.
      movf FSR,W     ;
      andlw 0Fh        ;
      call Buffer
      movwf INDF
      incf FSR
      movlw PTR+5
      subwf FSR,W
      btfss STATUS,Z
      goto nextb
      movlw Frames
      call Barrer
     
      endm

Probalo asi y me contas que paso.
Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.