TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: jukinch en 07 de Febrero de 2010, 03:01:17

Título: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: jukinch en 07 de Febrero de 2010, 03:01:17
Estimados amigos del foro. Estoy complicado con el uso de #separate.
Hice el programa zorra.c que está debajo, que quedó muuuuuuuuy largo. Ya casi lo termino. Y me está dando el error de memoria insuficiente. Pero es porque un segmento de programa me quedó muy largo. Es decir, main no puede ser tan largo como lo he hecho.
Buscando en el foro encontré
http://www.todopic.com.ar/foros/index.php?topic=22315.40
y Gonzalo_BlackHawk  explica como hacer para cortar una función en dos con la directiva #separate para que no se gaste toda la memoria de programa.
Coloqué dicha directiva antes de main y sigo con el mismo problema.
No me queda claro en que parte del código debo utilizar #separate ?
Leyendo encontré que se debe poner en la declaración de una funcion y en la definición de la misma.
Probé poniendo #separate por todos lados y sigo con el problema del error de out of rom.
Probé compilar el código para un 18f4550 y va bien. Pero no me quiero quedar sin solucionar ese error.
Se que debería optimizar el código para no hacerlo tan largo pero igual quiero aprender a usar #separate o en su caso alguna opcion para hacer programas bien largos y evitar el error referido.

                      Saludos.
                              Jukinch



Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Suky en 07 de Febrero de 2010, 10:06:01
Me parece que por más que uses separate si la función es más larga que una pagina no podrás solucionarlo. Tienes que organizar mejor el main en funciones.


Saludos!
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: jukinch en 07 de Febrero de 2010, 11:18:03
Suky:
        gracias por tu ayuda y pronta respuesta.
        Coincido con vos, creo que no me va a quedar otra que reestructurar todo el código.
        Uso muchas funciones para hacer cosas parecidas.
        Estoy configurando un rtc. con todos sus valores de día, mes, año, hora, minutos, y segundos..., usando dos botones, para subir y bajar los valores, y otro botón para confirmar la selección. Todo ello usando diferentes funciones. De allí el largo del código.
        Deberé estudiar la forma de usar una función del tipo menu_select(parámetro) para que me devuelva los valores que quiero establecer  en el rtc.
        Estoy desde el mes de agosto de 2009 con este proyecto, en el cual fui aprendiendo a usar el lcd, el rtc, etc, etc, y no me va a torcer el brazo.
        En cuanto tenga el código nuevamente en marcha lo posteo, por si a alguien le sucede lo mismo.
        Saludos desde San Nicolás, Argentina.
                         
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Nocturno en 07 de Febrero de 2010, 12:40:54
Es que en vez de utilizar etiquetas y goto deberías usar funciones y llamadas a funciones. Tal y como lo tienes montado resulta muy fácil de separar en funciones.
¿Este programa estaba escrito en Basic y lo has traducido al C?
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: jukinch en 07 de Febrero de 2010, 16:20:16
Nocturno:
            No lo migré del basic. Lo hice en c. El tema es que es mi primer proyecto grande. Y buscando como hacer un menú vi un ejemplo en c que lo hacían así con el label y goto.
             ¿Normalmente como hacés los menúes? ¿con un while y ahí dentro vas eligiendo las opciones?
            Te cuento que el proyecto que estoy haciendo es un poco ambicioso para ser principiante. Pero investigando y estudiando espero poder terminarlo. Fui aprendiendo de todo en esta aventura. Aprendí a ver los rebotes de los botones, a usar el lcd, luego el rtc. Aprendí a hacer los pcb con el método de la plancha. Después tendré que ver el protocolo i2c para comunicar con otros pics para sincronizarlos. etc. En verdad no creía que llegaría a avanzar tanto.
            El proyecto es para una competencia de radioaficionados.  (Fox hunting en inglés).
            Son 5 pics que controlan 5 transmisores que se esconden por toda la ciudad y luego salen los competidores a buscarlos mediante triangulación con antenas direccionales.
             Transmiten de manera sincronizada la siguiente secuencia, que se repite cada 5 minutos.
Emite durante el primer minuto el transmisor 1 en código morse una palabra que lo identifica.
MOE que equivale a -- --- .
Emite durante el segundo minuto el transmisor 2 en código morse una palabra que lo identifica.
MOI que equivale a -- --- ..
emite el transmisor 3 en código morse una palabra que lo identifica. MOSque equivale a -- --- ...
emite el transmisor 4 en código morse una palabra que lo identifica. MOHque equivale a -- --- ....
emite el transmisor 5 en código morse una palabra que lo identifica. MO5que equivale a -- --- .....
Esa secuencia se inicia en una fecha y hora dada y para también en un tiempo determinado.
Ahora estaba agregando al programa la posibilidad de usar fechas. Ya que hasta adonde había llegado a compilar bien sólo funcionaba durante un único día. Y va a estar bueno que los equipos puedan esconderse uno o dos días antes.
probé compilarlo para un pic más grande y lo compiló bien.
Por eso quería usar lo de #separate para ver si se solucionaba el error de out of rom.
            Arranqué mal con el planteo del programa al usar muchas rutinas que se repiten y la forma en la que quedó desarrollado el menú.
            Tendré que reestructurarlo todo desde cero. Y pasarlo a funciones como dices.             
             
                     Un abrazo.
                               jukinch
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Suky en 07 de Febrero de 2010, 18:25:07
Los menúes por lo general los trabajo en una única función que recibe como parámetro el menú a mostrar. Entonces para controlar el menú utilizo una variable (o 2 si el menú tiene muchos submenues), que dependiendo del valor se puede saber cual es. Dentro de la función con un switch solucionas el problema.

Saludos!
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Nocturno en 07 de Febrero de 2010, 18:32:19
Efectivamente, como te dice Suky es lo más lógico.

Te dejo un par de trozos de un código que tengo para un proyecto en el que uso menús.

En esta parte imprimo la opción que corresponda:

Código: C
  1. switch (Estado) {
  2.       case eDIFARRANQUE:  
  3.          lcd_gotoxy(1,1);
  4.          printf(LCD_PUTC,"Dif. Arranque   ");
  5.          ImprimeParametro(0);
  6.          break;
  7.       case eDIF_PARO:  
  8.          lcd_gotoxy(1,1);
  9.          printf(LCD_PUTC,"Dif. Paro       ");  
  10.          ImprimeParametro(1);
  11.          break;  
  12.       case eTMAX_DEPOSITO:  
  13.          lcd_gotoxy(1,1);
  14.          printf(LCD_PUTC,"T. Max. Deposito");  
  15.          ImprimeParametro(2);
  16.          break;
  17.       case eTMAX_PANEL:  
  18.          lcd_gotoxy(1,1);
  19.          printf(LCD_PUTC,"T. Max. Panel   ");  
  20.          ImprimeParametro(3);        
  21.          break;  
  22.     }

Y en esta otra actúo según la tecla pulsada:

Código: C
  1. switch (Estado) {
  2.       case eDIFARRANQUE:
  3.          switch (vTecla) {
  4.             case tMENU:
  5.                break;
  6.             case tOK:
  7.                EditaParametro(0);
  8.                break;
  9.             case tABAJO:
  10.                Estado = eDIF_PARO;
  11.                break;
  12.             case tARRIBA:  
  13.                Estado = ePARAM_SALIR;
  14.                break;
  15.          };
  16.          break;
  17.       case eDIF_PARO:
  18.          switch (vTecla) {
  19.             case tMENU:
  20.                break;
  21.             case tOK:
  22.                EditaParametro(1);
  23.                break;
  24.             case tABAJO:
  25.                Estado = eTMAX_DEPOSITO;
  26.                break;
  27.             case tARRIBA:  
  28.                Estado = eDIFARRANQUE;
  29.                break;
  30.          };
  31.          break;
  32. }

Como puedes ver, utilizando una variable (Estado) y esa función te facilita tanto la impresión como la navegación por los menús.
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: jukinch en 07 de Febrero de 2010, 19:10:45
Una vez más, gracias por su ayuda. Nocturno y Suky.
Esta noche reformulo el código y les comento.           
                     Un sincero saludo.
                             Jukinch
Título: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: jukinch en 10 de Junio de 2010, 12:59:54
[SOLUCIONADO]

Por si a alguien le sirve. Les cuento que separé todo el código en funciones como recomendaron Suky y Nocturno, y de esta manera se liberó la memoria de programa.
Ahora estoy migrando el código a c18 así que cuando esté listo lo posteo.
            Jukinch.
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: fidodido18 en 10 de Junio de 2010, 14:35:38
[SOLUCIONADO]

Por si a alguien le sirve. Les cuento que separé todo el código en funciones como recomendaron Suky y Nocturno, y de esta manera se liberó la memoria de programa.
Ahora estoy migrando el código a c18 así que cuando esté listo lo posteo.
            Jukinch.

alguna vez tuve este problema aunque yo si trabajaba con métodos y aplicaba todas las recomendaciones de los maestros suky y Nocturno, y cuando ocurre esto solo queda comprar un PIC con mas ROM.

En aquella ocasión me toco pasar de un 18f4550 a un 18f4620, ya que tenia que manejar un lcd 128x64 y un menú demasiado largo, ademas tenia que leer ibutton, código de barra, banda magnética, consultar con una base de datos a un servidor (por rs232) los productos de la canastillas, manejar la impresión de facturas y manejar la entrada y salida del personal, fue todo un proyecto, lastima que cuando lo terminamos (solo faltaba la carcasa) el negocio se vino abajo y se perdió esa investigación.

Son aquellas cosas que solo te pasan 1 vez! la próxima es con anticipo...  :D :D

que mas da, toca reírse de la vida!!
Título: Out of ROM, A segment or the program is too large [SOLUCIONADO]
Publicado por: jukinch en 10 de Junio de 2010, 18:11:57
Memoria rom insuficiente - Out of ROM, A segment or the program is too large

fidodido18:
             Que lástima que no se te dió con tan lindo proyecto. Al menos te quedó la experiencia y el conocimiento de armonizar todo lo que investigaste.
          Con respecto al error, si mal no entendí, el problema radica en que en la familia de los pic16, como el que estoy usando yo, la memoria está segmentada y por ello si una función se pasa en tamaño de "un segmento" genera ese problema.
          En mi caso como estaba trabajando todo "dentro" de main y tenía tantas pero tantas cosas allí dentro llegó un punto que me daba ese error "a segment or the program is too large" , porque a la función main no la podía separar de un segmento a otro. Pese a que había memoria libre en el pic, pero en otro segmento de memoria. Se entiende?
          Luego cuando separé el código larguísimo en código seccionado en funciones, logré achicar el programa principal y puedo seguir trabajando, manteniendo todo el código que estaba usando, pero disgregado.
          El problema de usar label: y goto label:  como lo hacía yo en proton basic, es que te queda todo dentro de main, y así para el pic se genera una única función. (además no es recomendable el uso de goto y los label porque altera la programación del tipo top-down, y se hace dificil seguir el código para el programador).-
               Un cordial saludo.
                             Jukinch
         
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: MGLSOFT en 10 de Junio de 2010, 23:12:30
Si has conservado el archivo prueba agregar esta linea debajo del llamado a la libreria del PIC:

Código: C
  1. #device *=16                    // This allows auto variables over location 0xFF

En compiladores anteriores mejoraba el uso de memoria.

Yo recien compile tu programa y usando o sin usar esa linea me da 74% Rom y 34% RAM usadas.
Es bastante nuevo, puede ser eso... :lol: :lol:

Y ademas compilo perfecto sin dar mensajes Out of Rom... :mrgreen:

Por supuesto que hacer lo que te aconsejaron es lo mejor.

Si vas a programar en C, deberas pensar en C... :mrgreen: :mrgreen:
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: jukinch en 11 de Junio de 2010, 00:16:49
Mglsoft:
         Gracias por el dato. Lamentablemente no lo conservo.  :5]
         Subí a este link http://www.4shared.com/file/OncW6fcA/zorra_060110.html el proyecto como quedó ahora, usando un switch y funciones para el menú en pantalla. Por si alguien quiere ver como evolucionó el software de labels y gotos a funciones. De a poquito voy empezando a pensar en C. Como dijo Paky para que la hago fácil si la puedo complicar, no? JAJAJA  :mrgreen:
      El programa principal es zorra.c y este incluye a fechas.c y libreria_rtc.c
         Todavía estoy a media carrera ya que tengo que optimizar las funciones, porque igual repito mucho código.
          Tengo pensado hacer una única función general para establecer con las teclas los valores de la hora, fecha etc. etc.
         Pasándole como parámetro el valor mínimo y máximo permitido y con eso lo reduzco casi por completo.
         Como pude seguir trabajando luego de solucionar el problema de la memoria, seguí avanzando así como está para lograr que funcione el aparato, sinó no terminaba más. Ya lo optimizaré.
        Ahora estoy con el desarrollo del hardware en si. No sabía los problemas de las interferencias y las altas frecuencias.
        El pic controla un handdy de vhf y este lo enloquece.
        MarioGuillote me explicó las bondades de los planos de tierra (Uh!! casi digo masa!!!) por todo el pcb y
con eso espero rehacer la placa y que ya termine el proyecto de una vez. :-/
              Cuando esté al 99% lo posteo por si alguien se interesa.                                      
                           Un abrazo.
                                   Jukinch
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: MGLSOFT en 13 de Junio de 2010, 12:19:21
Ademas de lo que te aconseja el Maestro Mario, seguramente algo que puede ayudarte es meter tu placa en una peque;a caja metalica, haciendo una especie de jaula de faraday.
Es una de las mejores formas de controlar la EMI en equipos no tan preparados desde el disenio... :mrgreen: :mrgreen:

La radio va fuera de esa caja ehh!!!! :D :D :D
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: jukinch en 13 de Junio de 2010, 19:50:08
Gracias Mglsoft por la info. ;-) Guillote también me habló de ello y ya casi lo olvidaba. JAJA
Por si a alguien le pueda interesar paso un pdf que me sirvió mucho.
http://www.analog.com/static/imported-files/tech_docs/Hardware_Design_Techniques_Section9.pdf
      Voy a abrir un hilo con todo el desarrollo de la zorra así no queda desprolijo el foro.
               Un abrazo.
                         Jukinch
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Simon21 en 15 de Enero de 2013, 12:14:41
Hola a todos. Lo que no termino de entender es si es muy largo el programa en cantidad de lineas o si se refiere
al contenido del main, o de una funcion especifica ??
El mensaje que me aparece es

Out of ROM, a segment or the program is too large funcion_1

y si veo el contenido de funcion_1 son dos lineas dentro de una interrupcion, no creo que sea ese el problema
ya que me sale ese error cuando coloco en el main la llamada a otra funcion función, si la dejo comentada funciona
todo bien, es mas, solo usa un 41% de la ROM, es como que es medio raro porque no modifico nada en funcion_1..

Agradeceria que alguien explique bien el objetivo de este mensaje, a que hace referencia ??  :5]

Saludos y gracias por la colaboracion
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: jukinch en 16 de Enero de 2013, 01:15:17
Hola Simon21.
El problema es que una función (y main también lo es) no sea demasiado larga.
Podés subir tu código ?
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Simon21 en 16 de Enero de 2013, 09:04:33
La siguiente función es la que me está haciendo desbordar la ROM.

Lo que hace es lo siguiente:

Es el modo programación de parametros, lo cual al usuario le van apareciendo
pantallas con valores predefinidos, y mediante dos teclas (subir y bajar) modifica
el valor de dichos valores predefinidos. Luego al presionar otra tecla (ok) pasa
al siguiente parámetro, y asi sucesivamente hasta que programa todos los parámetros
y vuelve al programa principal.

Si ven, desde un punto en adelante está comentado el código, eso lo hice
ya que el comentario en ese punto hace que compile con un uso de la rom
de un 68%, pero cuando le saco el comentario se queda sin espacio.

Gracias por la ayuda de antemano.

Código: [Seleccionar]
void programar_parametros (){
       
         lcd_gotoxy(1,1);
         printf(lcd_putc, " MODO  PROGRAMACION ");
         lcd_gotoxy(1,2);
         printf(lcd_putc, "  INGRESE EL VALOR  ");
         delay_ms (500); //Para darle tiempo al usuario que suelte los 3 pulsadores que hicieron que entre en esta rutina
         
         lcd_gotoxy(1,3);
         printf(lcd_putc, "    tblin  [seg]    "); // Tiempo de baja linea
       
         while (input(PIN_D3)==0){  // Al presionar la tecla OK salgo de este parametro y voy al siguiente
         lcd_gotoxy(1,4);
         printf(lcd_putc, "        %d        ", variables_a_enviar [0]); // Tiempo de baja linea
         if (input(PIN_D1)==1){ // Pulsador sube valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [0]++; }
         if (input(PIN_D2)==1){ // Pulsador baja valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [0]--;}
         }
         
         lcd_gotoxy(1,3);
         printf(lcd_putc, "    talin  [seg]    "); // Tiempo de alta linea
         delay_ms (500); //Para darle tiempo al usuario que suelte el pulsador de ok
         while (input(PIN_D3)==0){  // Al presionar la tecla OK salgo de este parametro y voy al siguiente
         lcd_gotoxy(1,4);
         printf(lcd_putc, "        %d        ", variables_a_enviar [1]); // Tiempo de baja linea
         if (input(PIN_D1)==1){ // Pulsador sube valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [1]++; }
         if (input(PIN_D2)==1){ // Pulsador baja valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [1]--;}
         }
       
         lcd_gotoxy(1,3);
         printf(lcd_putc, "     tbuj [seg]     "); // Tiempo de funcionamiento bujia
         delay_ms (500); //Para darle tiempo al usuario que suelte el pulsador de ok
         while (input(PIN_D3)==0){  // Al presionar la tecla OK salgo de este parametro y voy al siguiente
         lcd_gotoxy(1,4);
         printf(lcd_putc, "        %d        ", variables_a_enviar [2]); // Tiempo de baja linea
         if (input(PIN_D1)==1){ // Pulsador sube valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [2]++; }
         if (input(PIN_D2)==1){ // Pulsador baja valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [2]--;}
         }
         
         
         lcd_gotoxy(1,3);
         printf(lcd_putc, "     tbur [seg]     "); // Tiempo de funcionamiento burro
         delay_ms (500); //Para darle tiempo al usuario que suelte el pulsador de ok         
         while (input(PIN_D3)==0){  // Al presionar la tecla OK salgo de este parametro y voy al siguiente
         lcd_gotoxy(1,4);
         printf(lcd_putc, "        %d        ", variables_a_enviar [3]); // Tiempo de baja linea
         if (input(PIN_D1)==1){ // Pulsador sube valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [3]++; }
         if (input(PIN_D2)==1){ // Pulsador baja valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [3]--;}
         }
       
/*           
         lcd_gotoxy(1,3);
         printf(lcd_putc, "     tcm  [seg]     "); // Tiempo de calentamiento motor
         while (input(PIN_D3)==0){  // Al presionar la tecla OK salgo de este parametro y voy al siguiente
         lcd_gotoxy(1,4);
         printf(lcd_putc, "        %d        ", variables_a_enviar [4]); // Tiempo de baja linea
         if (input(PIN_D1)==1){ // Pulsador sube valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [4]++; }
         if (input(PIN_D2)==1){ // Pulsador baja valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [4]--;}
         }
         
       
         lcd_gotoxy(1,3);
         printf(lcd_putc, "     tar  [seg]     "); // Tiempo arrancado cuando se arranque solo
         while (input(PIN_D3)==0){  // Al presionar la tecla OK salgo de este parametro y voy al siguiente
         lcd_gotoxy(1,4);
         printf(lcd_putc, "        %d        ", variables_a_enviar [5]); // Tiempo de baja linea
         if (input(PIN_D1)==1){ // Pulsador sube valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [5]++; }
         if (input(PIN_D2)==1){ // Pulsador baja valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [5]--;}
         }
         
       
         lcd_gotoxy(1,3);
         printf(lcd_putc, "    dpar  [dias]    "); // Cantidad de días para arranque automatico
         while (input(PIN_D3)==0){  // Al presionar la tecla OK salgo de este parametro y voy al siguiente
         lcd_gotoxy(1,4);
         printf(lcd_putc, "        %d        ", variables_a_enviar [6]); // Tiempo de baja linea
         if (input(PIN_D1)==1){ // Pulsador sube valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [6]++; }
         if (input(PIN_D2)==1){ // Pulsador baja valor
            delay_ms (500); //Anti rebote
            variables_a_enviar [6]--;}
         }
         
   */
   
delay_ms(300);
parametros_modificados=1;         

 }
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: MGLSOFT en 16 de Enero de 2013, 10:02:59
Creo que deberias hacer lo siguiente:
Descomentar la parte que comentaste para poder compilar.
A medida que te de el mensaje de error, ir comentando una linea Printf(), y volver a compilar.
Hacer esto hasta que compile bien, ademas ir observando cuanto consume la sentencia printf() que vas comentando.

Seguramente esto te dara solucion, ya que es esta sentencia la gran consumidora de recursos.

Para hacer menues, te conviene dejar una sola sentencia printf() por cada renglon del lcd, que muestre un string de 16 caracteres.

En cada opcion de menu, en vez de mandar a Printf(), el texto a mostrar lo cargas en el string que corresponda al renglon que corresponda.
Cada vez que sales de la seleccion del menu, la sentencia printf() unica se encarga de enviar el texto que formateaste al lcd.

Esto tiene dos ventajas:
La primera es lograr meter todo el menu en un micro.
La segunda es lograr una gran mejora el la lectura de tu programa futuro...

Recuerda que todos los programas seguramente funcionaran, pero solo pocos seran posibles de ser leidos e interpretados rapidamente (aun por su programador) cuando pasen los años... :mrgreen:
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Simon21 en 16 de Enero de 2013, 10:09:06
Con la siguiente línea, me sube un 4% la rom !!

Pasa de 53% a 57%


Código: [Seleccionar]
printf(lcd_putc, "        %d        ", variables_a_enviar [0]);
En cambio con la siguiente linea, no aumenta ni un 1%, cada 4 o 5 impresiones
recién aumenta un 1% el uso de la ROM.

Código: [Seleccionar]
printf(lcd_putc, "    dpar  [dias]    ");
Veo que ocupa mucho mas ROM cuando imprimo el valor de una variable.. Más si es un vector..

¿¿ Y ahora ??  :shock:

El problema es que tengo que ir indicandole al usuario los parametros a cambiar, no puedo hacer un solo
printf, ya que a medida que seleccione el parametro, le tengo que mostrar el valor de ese parametro...  :?
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: MGLSOFT en 16 de Enero de 2013, 10:27:29
Hay instrucciones que te permiten formatear los valores numéricos y textos (todo junto) a string, luego le pasas el string...

Aqui te pongo un ejemplo que corre en un PIC18F252.


Código: C
  1. ////////////////////////////////////////////////////
  2. //  Muestra el mensaje de Menu elegido.
  3.       if (ModoOPER == MODO_Seteos)
  4.          {
  5.             switch (MenuSeteos)
  6.             {
  7.                 case Max_Pres:
  8.                     strcpy (MiBuffer, "Alarma AP  "); break;
  9.  
  10.                 case Min_Pres:
  11.                     strcpy (MiBuffer, "Alarma BP  "); break;
  12.  
  13.                 case Max_Temp:
  14.                     strcpy (MiBuffer, "Al. Temp   "); break;
  15.  
  16.                 case Max_Humedad:
  17.                     strcpy (MiBuffer, "Al.Humedad "); break;
  18.  
  19.                 case T_Pulso:
  20.                     strcpy (MiBuffer, "Timer ON   "); break;
  21.  
  22.                 case T_Espera:
  23.                     strcpy (MiBuffer, "Timer OFF  "); break;
  24.  
  25.                 case Cant_Valv:
  26.                     strcpy (MiBuffer, "# Valvulas "); break;
  27.  
  28.                 case RondasFin:
  29.                     strcpy (MiBuffer, "# Rondas FS"); break;
  30.  
  31.                 case Filtrado:
  32.                     strcpy (MiBuffer, "Filtro CAD "); break;
  33.             } // END switch
  34.         }


y como se envia el valor al LCD, en este caso Mibuffer contiene los textos y Mibuffer2 los valores, de esa forma evito tener que concatenar todo en un solo String.

Código: C
  1. case Velocidad:
  2.                      {
  3.                         switch (NuevoValor)
  4.                         {
  5.                            case B9600_E_8_1:  strcpy (MiBuffer2, " 9600 8E1"); break;
  6.                            case B9600_N_8_1:  strcpy (MiBuffer2, " 9600 8N1"); break;
  7.                            case B9600_O_8_1:  strcpy (MiBuffer2, " 9600 8O1"); break;
  8.                            case B19200_E_8_1: strcpy (MiBuffer2, "19200 8E1"); break;
  9.                            case B19200_N_8_1: strcpy (MiBuffer2, "19200 8N1"); break;
  10.                            case B19200_O_8_1: strcpy (MiBuffer2, "19200 8O1"); break;
  11.                            case B38400_E_8_1: strcpy (MiBuffer2, "38400 8E1"); break;
  12.                            case B38400_N_8_1: strcpy (MiBuffer2, "38400 8N1"); break;
  13.                            case B38400_O_8_1: strcpy (MiBuffer2, "38400 8O1"); break;
  14.                            case B57600_E_8_1: strcpy (MiBuffer2, "57600 8E1"); break;
  15.                            case B57600_N_8_1: strcpy (MiBuffer2, "57600 8N1"); break;
  16.                            case B57600_O_8_1: strcpy (MiBuffer2, "57600 8O1"); break;
  17.                         }
  18.                         lcdText (8, 2, MiBuffer2);
  19.                      } break;
  20.  
  21.                } //end switch
  22.          } //end if

Y aqui la funcion lcdText (), ya que no la vas a encontrar en las librerias...

Código: C
  1. /**
  2.  *   Muestra < string > en el display LCD.
  3.  */
  4.    void lcdString(char *string)
  5.    {
  6.       while (*string != 0)
  7.       lcd_send_byte (1,*string++);
  8.    }
  9.  
  10.    void lcdText (unsigned int x, unsigned int y, char *text)
  11.    {
  12.       lcd_gotoxy (x, y);
  13.       lcdString (text);
  14.    }

Espero te sirva !! :mrgreen:
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Simon21 en 16 de Enero de 2013, 10:35:20
Que opinas si utilizo en vez de

Código: [Seleccionar]
printf(lcd_putc, "     Pantalla 01    ");
utilizo

Código: [Seleccionar]
lcd_putc, "     Pantalla 01    "; ??

Por ahi he leido que disminuye el uso de la ROM, pero no comprendo aun la diferencia
usando el printf.
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: MGLSOFT en 16 de Enero de 2013, 10:48:40
Lee de nuevo mi mensaje, acabo de agregarle info, hoy se me fue sin querer...

Printf le agrega todas las caracteristicas de formateo de numeros y variables a lcd_putc() que esta hecha solo para string.
lo que te comento saltea ambos problemas mejor.
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Simon21 en 16 de Enero de 2013, 11:08:20
Está buena la idea que me proponés, pero me parece que es complicado adaptarlo a mi caso en particular.

Te hago otra consulta, he probado simularlo al mismo código con el pic 18F452 y me ocupa un 25% de la ROM.

Tengo 2 de estos pics guardados, si reemplazo el 16F877A directamente por éste, quedará funcionando el resto
del código o tendré que hacer todo nuevamente ??

Gracias por tu ayuda MGLSOFT
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: MGLSOFT en 16 de Enero de 2013, 11:16:57
Casi todo el traslado de mi aplicación fue hecho (por falta de ROM aun después de optimizar el código) desde un PIC16F876 a un PIC18F252, y tuve que hacer solo algunos cambios menores.
No recuerdo cuales en este momento, pero creo que la eeprom y algunas otras cosas trabajan diferente, ademas que ya no tiene bancos de memoria sino que es lineal, es decir no tiene los típicos saltos entre bancos.
Pero eso es transparente en CCS.

Creo que debería funcionarte bien, por las dudas leete las instrucciones de Microchip para pasar de ese PIC al otro, que precisamente es el que suplanta en la nueva linea.

una vez uses un PIC18F ya no querrás volver a la linea 16F, eso te lo aseguro... :mrgreen:
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Simon21 en 16 de Enero de 2013, 11:18:20
jaja eso parece !! pregunto ya que nunca he usado un 18F...

Voy a probar primero en proteus, ya que el compilador CCS lo compila lo mas bien.

Si funciona en proteus, deberia funcionar en la placa !! jaja veremos..
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: MGLSOFT en 16 de Enero de 2013, 11:24:45
La diferencia mas grande esta en los fuses (ahora me acorde) , leete bien los fuses en ambos PIC, asi aprendes esas diferencias, ya que despues en la linea 18F vas a verlos repetidos nuevamente.
Y las opciones de oscilador tambien crecen mucho y hay que entenderlas bien...
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Simon21 en 16 de Enero de 2013, 11:32:46
Tienes algun link que me recomiendes sobre esto ?
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: MGLSOFT en 16 de Enero de 2013, 11:36:31
Las hojas de datos de Microchip, en excelente ingles !! :D :D
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Simon21 en 16 de Enero de 2013, 12:07:43
Veo en el #include <18f452.h> los siguientes FUSES:

//////// Fuses: LP,XT,HS,RC,EC,EC_IO,H4,RC_IO,PROTECT,NOPROTECT,OSCSEN
//////// Fuses: NOOSCSEN,NOBROWNOUT,BROWNOUT,WDT1,WDT2,WDT4,WDT8,WDT16,WDT32
//////// Fuses: WDT64,WDT128,WDT,NOWDT,BORV20,BORV27,BORV42,BORV45,PUT,NOPUT
//////// Fuses: CCP2C1,CCP2B3,NOSTVREN,STVREN,NODEBUG,DEBUG,NOLVP,LVP,WRT
//////// Fuses: NOWRT,NOWRTD,WRTD,NOWRTB,WRTB,WRTC,NOWRTC,CPD,NOCPD,CPB
//////// Fuses: NOCPB,EBTR,NOEBTR,EBTRB,NOEBTRB

Tengo que mencionarlos a todos al empezar el programa ??

En mi programa anterior tenía los siguientes, y me lo compila sin problemas en el 18F

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD, HS PARA 20 MHz
#FUSES NOPROTECT                //Código sin Protección para Lectura
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOCPD                    //No EE protection
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPUT                    //No Power Up Timer
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: MGLSOFT en 16 de Enero de 2013, 12:19:36
No, solo los que uses, por ejemplo, en las opciones de reloj tienes:

Citar
LP,XT,HS,RC,EC,EC_IO,H4,RC_IO

Si vas a usar un cristal de hasta 4 Mhz, solo activas XT (aunque si es 4 Mhz, tambien funciona con HS), pero aqui hay una opción mas que no tenias antes, puedes activar H4 y se multiplicara por 4 la velocidad del cristal externo, o sea que podrás trabajar internamente a 16 Mhz con un cristal de 4 Mhz.

Esa opcion en la otra linea no existe.

Repito, leete muy bien las diferencias, o estarás preguntando cientos de cosas por aqui pronto... :mrgreen: :mrgreen:
Título: Re: Memoria rom insuficiente - Out of ROM, A segment or the program is too large
Publicado por: Arsenic en 23 de Abril de 2015, 23:45:48
Hola! Estoy teniendo un problema similar con la siguiente función:

Código: [Seleccionar]
void main()

{

   set_tris_a(0b11001000);
   setup_timer_0(RTCC_INTERNAL);setup_wdt(WDT_2304MS);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   lcd_init();
   enable_interrupts(INT_TIMER1);
   disable_interrupts (GLOBAL);
   setup_oscillator(OSC_4MHZ);

   printf(lcd_putc,"Temporizador v.1\n");
   lcd_putc("Farias Ezequiel");
   LCD_DefineCaracter ();
   CargaConfiguracion();
   delay_ms(500);
   pitido(50);
   CARA_INFERIOR=0;
   CARA_SUPERIOR=0;
   menu();
   MuestraEstado();

   while(1){

//   pitido(50);
      restart_wdt();
      if (!SW_ARRIBA) {// sube en el menú
         pitido(20); // antirrebotes
         while (!SW_ARRIBA); // esperamos que suelte tecla
         if (EstadoEntradaTiempo)
            ConfiguraTiempo(ARRIBA);
          else {
            OpcionMenu--;
            if (!OpcionMenu)
               OpcionMenu=(3+Estado+EnPausa);
            if (OpcionMenu==3)
               HayMensaje=MUESTRACARAS;
              else
               HayMensaje=0;
            TicksMensaje=0;
            menu();
            MuestraEstado();
          }
      }

      if (!SW_ABAJO) {// baja en el menú
         pitido(20); // antirrebotes
         while (!SW_ABAJO); // esperamos que suelte tecla
         if (EstadoEntradaTiempo)
            ConfiguraTiempo(ABAJO);
          else {
            OpcionMenu++;
            if (OpcionMenu==(4+Estado+EnPausa))
               OpcionMenu=1;
            if (OpcionMenu==3)
               HayMensaje=MUESTRACARAS;
              else
               HayMensaje=0;
            TicksMensaje=0;
            menu();
            MuestraEstado();
          }
      }
      if (!SW_INTRO) {// acepta opción
         pitido(20); // antirrebotes
         while (!SW_INTRO); // esperamos que suelte tecla
         if (EstadoEntradaTiempo) {
            ConfiguraTiempo(INTRO);
           } else {
            HayMensaje=0;
            TicksMensaje=0;
            EjecutaOpcion();
           }
         menu();
         MuestraEstado();
      }

   }
}

La salida produce el siguiente mensaje:

"""Error 71 'programa.c' Line *****: Out of ROM. A segment of the program is too large. EjecutaOpcion