TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: jfmateos2 en 17 de Enero de 2008, 11:39:50
-
Lo que sigue es una simplificación de mi problema real.
Tengo definidos varios (muchos) arrays cuyo número de elementos no siempre es el mismo:
int medida0[3]={0,0,31};
int medida1[4]={31,0,31};
int medida2[6]={0,0,31};
... imaginen que esto continúa...
y quiero referirme, por ejemplo, al 2º elemento de cada uno de esos array mediante un bucle. ¿conocen alguna forma de hacerlo?
Premisa: Ando mal de memoria RAM y ROM
-
y quiero referirme, por ejemplo, al 2º elemento de cada uno de esos array mediante un bucle. ¿conocen alguna forma de hacerlo?
Si entendí bien tu quieres hacer medidan[2] , donde n vaya cambiando...
En C para microcontroladores no creo que haya forma, no que yo sepa al menos. Ahora si haces un array bidimensional, eso ya es otra cosa y tienen que ser todos sus elementos iguales.
Una sugerencia sería que hagas un solo array, largo y que sepas en el código donde comienza cada elemento, pero si me dices que andas mal de memoria rom... ¿tampoco tendrías lugar para guardar una tabla de constantes donde indiques el inicio de cada array dentro del array grande?
Para ahorrar "espacio en código" puedes hacer un macro pero ya no sería un bucle (siempre que tu compilador lo permita). Un macro que reemplace texto (donde solo escribirias medida(n) y le texto a continuación seria el que pasas como parámetro 0,1, 2... etc) , el macro pegaria medida1, medida2, etc , pero sería equivalente a tipear el nombre de los arrays a mano.
-
Muchas gracias Maunix. Se me olvidó comentar que uso CCS.
Actualmente lo tengo resuelto con un array de punteros, como indico a continuación, pero pensé que habría una forma mejor:
int medida0[3]={0,0,31};
int medida1[4]={31,0,31,34};
int medida2[6]={0,0,31,23,45,12};
...más declaraciones de arrays del tipo medida[b]x[/b]...
int *medidas[255]={medida0, medida1, medida2, ...};
for (i=0;i<256;i++){
segundoElementoDeMedida=*(medidas[i]+1);
}
Por cierto, ¿existe alguna limitación en cuanto al tamaño de los arrays en CCS C? En el libro de Nigel Gardner "PIC micro MCU C" he leído lo siguiente:
Due to the PICmicro MCU´s memory map, arrays of 100 or 10x10 are not possible. However, two of 50 arrays would fit.
-
Te comento algo, usar un arreglo de punteros no es la cosa más eficiente en memoria... un puntero a memoria ocupará un par de bytes de memoria RAM. Para eso te conviene usar constantes, digo, para ahorrar memoria RAM.
En cuanto al tamaño del array no es "culpa" el CCS sino del pic, su memoria no es contigua entonces no hay forma de crear un array grande por esa razón. Depende del pic que uses, en los 18F si podes armar arreglos más grandes porque tienen bancos contiguos pero en los 16F no.
Saludos
-
Hola maunix, ¿podrías explicarme un poco mejor cómo es eso de usar constantes en este caso concreto?
-
Hola Juanfe, es como lo menciona maunix, mientras mas largos quieras los array mas memoria ram deberas tener, eso dependera del pic y de cuan largo sea tu arreglo
en cambio si usas constantes no usas la RAM, usas la memoria de programa, y de ese generalmente hay bastante, por lo menos hay siempre muhco mas que en la RAM
eso lo haces asi:
int const data[208]={48,120,204,204,252,204,204,204,248,204,204,248,248,204,204,248,252,
192,192,192,192,192,192,252,240,200,204,204,204,204,200,240,252,192,192,240,240,192,192,252,252,
192,192,240,240,192,192,192,60,64,192,192,216,204,204,248,204,204,204,204,252,204,204,204,252,
48,48,48,48,48,48,252,252,48,48,48,48,48,176,224,196,200,208,224,208,204,204,204,192,
192,192,192,192,192,192,252,238,214,214,198,198,198,198,198,196,228,244,212,212,204,204,196,48,
204,204,204,204,204,204,48,248,204,204,204,248,192,192,192,56,196,196,196,196,212,200,52,248,
204,204,204,248,208,200,196,120,204,192,192,120,12,12,248,252,48,48,48,48,48,48,48,204,
204,204,204,204,204,204,120,204,204,204,204,204,204,72,48,198,198,198,198,198,214,214,238,132,
132,72,48,48,72,132,132,204,204,204,120,48,48,48,48,252,252,8,16,32,64,252,252};
cuando lo hice sin el const, me aparecia un error de dimension, y esto para un 16f88, que tiene nomas buena ram
y hasta puedes colocarle un unsigned mas, quedaria (no vi diferencia en usos de ROM y RAM, pero talvez ahorre unos bytes mas, nose, corrijanme si me equivoco):
unsigned int const data[208]{..,..,.,......}
-
El unsigned no cambia el tamaño de la variable, si no que define como se tratará el primer bit de la variable (0=positivo, 1=negativo) cuando se declara signed y cuando se declara como unsigned siempre será positiva la variable.
Un saludo
-
ok, entendido.
entonces si es signed, solo será hasta 128 valores posibles, ya que se esta comiendo un bit, pero 128 positivos y 128 negativos, y ahi estan los 256 valores para un INT de 8 bits, cierto?
-
Totalmente correcto, veo que lo has cogido a la primera.
Un saludo.
-
:mrgreen: es qeu con el teimpo se va aprendiendo un poquitin mas :-/
-
Gracias cryn y jfh, pero si declaro los arrays como constantes ya no podré utilizar punteros a ellos y, ¿cómo consigo entonces referirme a todos ellos mediante un bucle?
Cuando Maunix me hace esta recomendación:
Te comento algo, usar un arreglo de punteros no es la cosa más eficiente en memoria... un puntero a memoria ocupará un par de bytes de memoria RAM. Para eso te conviene usar constantes, digo, para ahorrar memoria RAM.
lo que no entiendo es cómo referirme a esas constantes mediante un bucle.
-
¿Y si haces?
int const medida[n,anchomax]=...;
Desperdiciarías espacio en la memoria de programa, porque tendrías que ajustar todas las filas al anchomax, pero si tienes espacio de programa de sobra...
-
Gracias Nocturno, eso es lo que primero pensé, pero tengo que exprimir hasta el último bit de RAM/ROM.
-
Ah, creí que tenías sitio para almacenar constantes.
Y a todo esto, ¿puedes explicar para qué lo necesitas?
-
No tengo sitio para nada de nada de nada, no me cabe ni un alfiler...
En unos días os lo presento en sociedad, pero adelanto que va en la línea de la lámpara RGB de azicuetano.
-
Pero jfmateos2, lo que no me queda claro es que si no tienes espacio para las constantes en rom, el código que te genera el uso de punteros a ram debe ser similar.
Si estas muy muy jugado de espacio solo me queda sugerirte que hagas algo del código en assembly o bien si usas un pic que pueda autoleer la flash, podrías ingeniartelas para almacenar como código la tabla de constantes lo cual te ahorrará mucho espacio.
En los 16F una instruccion de programa tiene 14bits, si con 14bits puedes almacenar nro de posición y numero de indice, entonces podrías leer una posición de la flash como si fuera 'dato'. claro que necesitaras espacio para la rutina de lectura de la flash pero si tienes muchos datos te aseguro que a fin de cuentas te ahorras espacio en memoria.
-
talvez te sirva la idea, mira yo use esa declaración para guardar los datos que mostraria por una matriz de leds 8x8
y entonces cada letra es 8 bytes, y se que cada 8 bytes viene una nueva letra, entonces con un for puedo ir mostrando cada byte para cada fila de la matriz, y si quiero otra letra, solo calculo su posición, en mi caso como era una prueba nada mas, las posiciones las defini solo al inicio y de ahi voy sumandod e ocho en ocho en el programa, espero se haya entendido, pero bueno te dejo el codigo para que veas como lo estaba haciendo
for(j=0;j<max;j++)
{
for(i=min;i<maxi;i++)
{
output_a(cont); // esta era la linea para activar un decodificador segun la fila en la qeu estabamos
output_b(data[i]); //data es la declaracion qeu de teje antes
delay_ms(1);
cont++;
}
}
output_b(0);
delay_ms(500);
min=maxi;
maxi=maxi+8;
cont=0;
if(maxi>208)
{
min=0;
maxi=8;
}
con ello logro ver todo el alfabeto que esta guardado en el array data, todo con referencia al indice i
-
Cryn voy a calcular si con tu método consigo ahorrar algo de memoria.
El problema es que mis datos no tienen todos el mismo número de elementos, los tengo con 1, 2, 3, 4, 5, 6, ... elementos, de modo que para aplicar tu método tendré que rellenar con elementos dummy para que todos midan lo mismo. Aún así, quizás consiga ahorrar algo de memoria, pues como me ha dicho maunix, con mi método ya estoy derrochando dos bytes más para el puntero de cada dato.
Haré unas cuentas y aplicaré el método que mejor me resulte.
Gracias.