Autor Tema: PIC18f452: memoria para variables  (Leído 7697 veces)

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

Desconectado mikiruni

  • PIC10
  • *
  • Mensajes: 5
PIC18f452: memoria para variables
« en: 11 de Octubre de 2008, 07:20:05 »
Hola a todos!
Soy nuevo en este mundo de los PIC y en este foro. Escribo porque me ha surgido un problemilla en un "proyecto" en el que estoy metido. Mi intención es hacer un robot que recorra un laberinto y vaya memorizando el recorrido y los obstáculos. Mi idea era ir almacenando los datos de distancia dados por un SRF04 de ultrasonidos en una matriz, para crear una especie de plano. Para ello estoy usando un PIC18f452. El problema me ha surgido al intentar compilar el programa: no puedo utilizar más de 256 bytes en variables (si utilizo más me sale un mensaje de error al compilar tipo "can not fit the section"), por lo que -sin usar ninguna variable más- el tamaño máximo de matriz tipo char (no he encontrado un tipo de dato más pequeño en C) es 16x16. El compilador que uso es MPLAB, programando en C.
No se si el problema es que el PIC no tiene más memoria para almacenar variables, o que estoy haciendo algo mal al programar. Viendo el datasheet del pic he visto que tiene una EEPROM de 256 bytes pero lo normal sería que guardase las variables en la RAM, ¿no?
Ya os digo, no tengo demasiada idea de todo esto así que si teneis alguna explicación/solución, agredecería infinito que la compartieseis.

Muchas gracias.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re: PIC18f452: memoria para variables
« Respuesta #1 en: 11 de Octubre de 2008, 08:36:30 »
Ese micro tiene 1,5KB de memoria así que no debe ser ese el problema.
Pega tu código aquí por si lo descubrimos.

Desconectado mikiruni

  • PIC10
  • *
  • Mensajes: 5
Re: PIC18f452: memoria para variables
« Respuesta #2 en: 11 de Octubre de 2008, 08:59:22 »
El programa de momento no tiene ningún secreto. Simplemente he empezado a escribir la parte que moverá el servo sobre el que irá montado el srf04 a modo de radar (la mayoría está copiado de un ejemplo de control de servos que encontré por ahí) Se me ocurrió probar qué tamaño de matriz máximo me dejaba usar y lo que encontré es lo que he dicho en el primer post. Este es el código:

Código: C
  1. #include <p18f452.h>
  2. #include <timers.h>
  3. #include <delays.h>
  4.  
  5. #pragma config WDT=OFF, LVP=OFF, OSC=HS
  6.  
  7. void inter (void);                                      // declaracion de la funcion
  8.  
  9. #pragma code high_vector=0x08            //para que coloque este codigo en la
  10.                                                                 //direccion a la que apunta el vector de interrupcion
  11. void interrupt_at_high_vector(void)
  12. {
  13. _asm GOTO inter _endasm
  14. }
  15. #pragma code                                            // vuelvo a colocar el codigo en el sitio normal
  16.  
  17. #define servo1 PORTDbits.RD0
  18.  
  19. #define servo_max 2186
  20. #define servo_min 474
  21. #define servo_centro 1330
  22.  
  23. unsigned int duty1=servo_centro;
  24.  
  25. enum {D1, NO_D1, RESTO} estado;
  26.  
  27. #pragma interrupt inter
  28. void inter(void)
  29. {
  30.         INTCONbits.TMR0IF=0;            //bajo el flag de la interrupcion
  31.        
  32.         switch (estado)
  33.         {
  34.                 case RESTO:
  35.                                 servo1=1;
  36.                                 WriteTimer0(0xffff-duty1);
  37.                                 estado=D1;
  38.                                 break;
  39.                 case D1:
  40.                                 servo1=0;
  41.                                 WriteTimer0(0xffff-20000+duty1);
  42.                                 estado=RESTO;
  43.         }
  44. }
  45.  
  46. void main(void)
  47. {      
  48.         char matriz [16][16];
  49.        
  50.         OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_1 );
  51.                 // inicializo el timer0 como timer de 16 bits, preesc 1:1 y
  52.                 // habilitando la interrupción
  53.  
  54.         INTCONbits.PEIE=1;                      // habilito interrupcion de perifericos
  55.         INTCONbits.GIE=1;                       // habilito interrupciones globales
  56.        
  57.         TRISD = 0b11111100;             // pongo RD0 y RD1 como salidas
  58.         servo1=1;                                       // inicializo las salidas
  59.         estado=D1;                              // inicializo el estado
  60.         WriteTimer0(0xffff-duty1);
  61.  
  62.         while (1)                               // bucle infinito
  63.         {
  64.                
  65.         }
  66. }

Gracias.


Desconectado mikiruni

  • PIC10
  • *
  • Mensajes: 5
Re: PIC18f452: memoria para variables
« Respuesta #4 en: 11 de Octubre de 2008, 14:12:15 »
He leido esperanzado el hilo que me has pasado, pero he comprobado que por mucho que fraccione los arrays, cuando supero los 256 bytes me da el error. Lo pongo entero, que antes sólo he escrito una parte:

Error - section 'servos.o:main' can not fit the section. Section 'servos.o:main' length=0x00000126

Lo de servos es porque el .c se llama servos y el length del final simplemente indica el tamaño de las variables que declaro (si pasa de 0x0100, 256 bytes, ya no compila).

He descubierto otra cosa curiosa que no se si aportará algo: puedo declarar antes del main hasta 256 bytes más independientemente de los que declare dentro del main.

El máximo, sin declarar ninguna variable más es este:

char matriz1 [16][16];

void main(void)
{   
   char matriz [16][16];
}

Muchas gracias.

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: PIC18f452: memoria para variables
« Respuesta #5 en: 11 de Octubre de 2008, 19:08:00 »
Hola mikiruni

Deberias mirar el manual de tu compilador y ver cuales son las limitaciones de los arrays.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado mikiruni

  • PIC10
  • *
  • Mensajes: 5
Re: PIC18f452: memoria para variables
« Respuesta #6 en: 13 de Octubre de 2008, 11:47:26 »
Hola PalitroqueZ,

He estado mirando el manual de MPLAB-C18 y aunque no he encontrado nada (o no he sido lo suficientemente hábil para encontrarlo) sobre las limitaciones de los arrays, he encontrado algo que puede ser útil. Si pones rom en la declaración de la variable, se guarda en la memoria de programa y no en la memoria de datos. El 18f452 tiene 32kB dedicada a este fin. Dejando suficiente para que almacene el programa, podría tener una cantidad de memoria importante para guardar la matriz que quiero. ¿Habría algún problema con guardar variables en esta memoria y no en la dedicada a datos?

Otra solución que se me había ocurrido era poner una EEPROM externa (tipo 24xx), comunicada mediante I2C con el PIC. ¿Es práctico usar una memoria de este tipo para guardar datos que me da igual que se borren al apagar? ¿o es matar moscas a cañonazos?

Gracias por vuestro tiempo

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: PIC18f452: memoria para variables
« Respuesta #7 en: 13 de Octubre de 2008, 17:08:38 »
Hola mikiruni

no, no serviría, ya que el arrays es una variable que cambia constantemente y al guardarla en la ROM, la estarias declarando como constante.

Me extraña que no te permita crearla en RAM, lamentablemente no conozco el C18, pero seguro que debe faltar configurar algo por allí.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: PIC18f452: memoria para variables
« Respuesta #8 en: 21 de Octubre de 2008, 17:30:44 »
mikiruni tu problema es que la variable que quieres declarar es muy grande para ser ubicada en el stack.  Te sugiero que para variables así tan grandes las declares como global, no locales a la función.

La otra pregunta es , si justo ocuparas 256 bytes podrias ocupar un banco entero de memoria sin que por ello se vea afectado tu programa, estás al limite pero si la página solamente la usas para esa variable no habría problema.

Tienes ram suficiente para hacer lo que necesitas, no te la compliques con una eeprom externa o la directiva rom que sirve para declarar variables en memoria de programa.

Haz lo siguiente, saca el arreglo de la función main y declaralo como


#pragma udata MiArray=0x0100
char matriz [16][16];


Esto ubicará tus variables en el banco1 de memoria.

Ahora si quieres variables más grandes, ya debieramos estar pensando en editar el archivo .lkr y las opciones del compilador.

Es por ello que te sugiero comiences por esto, a ver si te funciona bien y luego ir avanzandoen complejidad.

- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado mikiruni

  • PIC10
  • *
  • Mensajes: 5
Re: PIC18f452: memoria para variables
« Respuesta #9 en: 22 de Octubre de 2008, 10:01:57 »
Gracias maunix, comprendo un poco mejor dónde estaba el fallo. Con tus indicaciones soy capaz de declarar como globales 4 arrays 16x16 de esta forma:

#pragma udata MiArray=0x0100
char matriz1 [16][16];

#pragma udata MiArray2=0x0200
char matriz2 [16][16];

#pragma udata MiArray3=0x0300
char matriz3 [16][16];

#pragma udata MiArray4=0x0400
char matriz4 [16][16];

La memoria del 18f452 no da para más, creo. Si uso esas 4 matrices puestas en cuadrado, tendría una matriz 32x32. Pero para el robot que había pensado sigue siendo insuficiente. Aunque es probable que haya formas más eficientes de mapear un laberinto, a mí me apetece hacerlo así  8).

El laberinto que recorrería tendría unas dimensiones de 3x3 metros aprox. Si quiero que cada elemento de la matriz sea un "pixel" de 1x1 cm necesito una matriz 300x300 minimo. Y eso creo que no cabe en la memoria del PIC, de ahí la idea de la EEPROM. ¿Es muy engorroso trabajar con una memoria externa?

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: PIC18f452: memoria para variables
« Respuesta #10 en: 22 de Octubre de 2008, 12:04:15 »
Aja, bien, estas asumiendo lo correcto al pensar en que tal vez el PIC18F452 no tenga memoria suficiente, de todas formas, te animo a que si quieres seguir en los pics, tal vez puedas buscar algún 18F más grande con más memoria  :)

Me parece bien que hagas 4 matrices si no quieres complicartela por ahora con una única matriz más grande , teniendo que trabajar con el linker y con algunas opciones del compilador.  De todas formas si te interesa, hay un link muy interesante en las FAQ (Preguntas Frecuentes) de Microchip) que explica como es el proceso.  La verdad no he tenido tiempo aún de traducirlo pero si te interesa y entiendes el inglés he aquí el link MPLAB C18 FAQs

En cuanto al uso de una memoria EEPROM externa no son difíciles de usar pero todo depende de cuanto tiempo dispongas para codificar la comunicación :) .  Básicamente las hay i2c y spi.  Personalmente creo que las SPI son más simples de controlar, asi que si consigues una de este tipo, bienvenido sea.

Si los datos cambiarán con mucha frecuencia, debes pensar en que tal vez una eeprom no sea lo mejor.  Hay unas memorias ferro magnéticas que podrian ser justo lo que necesitas, son como eeprom pero se graban muy rápido. 

También hay memorias ram estáticas y si no necesitas persistencia al apagar el micro te servirían.  El tema es que suelen ser paralelas y por lo general son caras aunque yo he averiguado por bastante RAM, 32 MegaBytes o similar.  Supongo que por poca memoria tal vez también hay, sería cuestión de buscar


- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)


 

anything