TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: eleguez en 14 de Marzo de 2007, 09:46:49
-
hola a todos, estoy programando un pic 16f876A y necesito utilizar un vector de 100 valores y lo declaro asi: float vector[100]; pero me da problemas, parece que es por el tamaño. alguien me puede decir de que tipo de dato debo poner el vector?
Un saludo
-
hola a todos, estoy programando un pic 16f876A y necesito utilizar un vector de 100 valores y lo declaro asi: float vector[100]; pero me da problemas, parece que es por el tamaño.
Un 16F876A tiene 368 bytes de memoria.
Un float ocupa 4 bytes. Un vector de 100 floats, ocupará 400 bytes de memoria.
Es por eso que te da error.
alguien me puede decir de que tipo de dato debo poner el vector?
Antes nos desbes comentar qué pretendes hacer con ese vector :?
-
Tal como te dice Maunix, el micro te "queda chico" para ese vector.
Quizas debas utilizar alguna memoria externa, y hacer un par de rutinitas para alojar los valores y recuperarlos desde ahi.
Saludos!
-
lo que quiero es almacenar 100 valores de entrada al pic para ir haciendo una media de esos valores y mostrarlos en un lcd. lo de utilizar el vector es para no tener que esperar a recibir 100 entradas, lo que hago es quitar el primer valor e introducir el ultimo y asi hacer la media de nuevo.
intenté hacerlo con 50 valores y tambien me da error.
saludos.
-
Que lenguaje estas usando ?
Salud 8)
-
estoy programando en C, con el compilador ccs
un saludo
-
Hola eleguez
si colocas el código, podremos ver si hay algún fallo en la programación. Desde luego para el vector de 100 valores float, estoy conforme con maunix, y te quedaría chico el micro.
saludos!
Diego J.
-
Aqui os envio el codigo que utilizo ahora y que si funciona porque el vector es de 10, si le pongo de tamaño 50 o 100 me da error en la compilacion.
#include <16F876A.h>
#use delay(clock=20000000)
#define use_portb_lcd TRUE
#include <lcd.c>
#fuses HS, NOWDT, NOPROTECT, NOPUT, NOBROWNOUT, NOLVP
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
char cad1[7]="BARES";
char cad2[12]="ATMOSFERAS";
char cad3[5]="PSI";
char cad4[14]="KILOPASCALES";
float atm=0;
float bar=0;
float psi=0;
long int KPa=0;
float x=0;
int i=0;
float suma=0;
int num=0;
float vector[10];
void primera_medida()
{
set_tris_a(0xFF);
setup_adc_ports(AN0_AN1_VSS_VREF);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
suma=0;
for (i=0; i<10; i++)
{
suma = suma + vector;
}
x=suma/10;
}
void valor ()
{
set_tris_a(0xFF);
setup_adc_ports(AN0_AN1_VSS_VREF);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
for (i=0;i<10;i++)
{
vector=vector[i+1];
}
vector[9]=read_adc();
delay_ms(200);
suma=0;
for (i=0; i<10; i++)
{
suma = suma + vector;
}
x=suma/10;
atm=(1.28*x)-140;
bar=atm*1.013;
psi=atm*14.7;
KPa=atm*101.325;
}
void main()
{
set_tris_a(0xFF);
setup_adc_ports(AN0_AN1_VSS_VREF);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
lcd_init();
for (i=0;i<10;i++)
{
vector=read_adc();
delay_ms(200);
}
primera_medida();
do
{
if(num>4) num=0;
else num=num;
if (!input(PIN_C0))
num+=1;
else if (!input(PIN_C2))
num-=1;
else num=num;
Switch(num)
{
case 1:
if(!input(PIN_C1))
{
do
{
Valor();
lcd_putc("\f");
lcd_gotoxy(1,1);
lcd_putc("MEDIDOR PRESION");
lcd_putc("\n");
printf(lcd_putc,"%4.2f BAR",bar);
printf("\r \n %4.2f BAR",bar);
delay_ms(20);
}while(true);
}
else
{
lcd_putc("\f");
lcd_gotoxy(1,1);
lcd_putc("UNIDADES MEDIDA");
lcd_putc("\n");
printf(lcd_putc,"%s",cad1);
delay_ms(200);
}
break;
case 2:
if(!input(PIN_C1))
{
do
{
valor();
lcd_putc("\f");
lcd_gotoxy(1,1);
lcd_putc("MEDIDOR PRESION");
lcd_putc("\n");
printf(lcd_putc,"%4.2f ATM",atm);
printf("\r \n %4.2f ATM",atm);
delay_ms(20);
}while(true);
}
else
{
lcd_putc("\f");
lcd_gotoxy(1,1);
lcd_putc("UNIDADES MEDIDA");
lcd_putc("\n");
printf(lcd_putc,"%s",cad2);
delay_ms(200);
}
break;
case 3:
if(!input(PIN_C1))
{
do
{
valor();
lcd_putc("\f");
lcd_gotoxy(1,1);
lcd_putc("MEDIDOR PRESION");
lcd_putc("\n");
printf(lcd_putc,"%4.2f PSI",psi);
printf("\r \n %4.2f PSI",psi);
delay_ms(200);
}while(true);
}
else
{
lcd_putc("\f");
lcd_gotoxy(1,1);
lcd_putc("UNIDADES MEDIDA");
lcd_putc("\n");
printf(lcd_putc,"%s",cad3);
delay_ms(200);
} break;
case 4:
if(!input(PIN_C1))
{
do
{
valor();
lcd_putc("\f");
lcd_gotoxy(1,1);
lcd_putc("MEDIDOR PRESION");
lcd_putc("\n");
printf(lcd_putc,"%Lu KPa",KPa);
printf("\r \n %Lu KPa",KPa);
delay_ms(20);
}while(true);
}
else
{
lcd_putc("\f");
lcd_gotoxy(1,1);
lcd_putc("UNIDADES MEDIDA");
lcd_putc("\n");
printf(lcd_putc,"%s",cad4);
delay_ms(200);
} break;
default:
lcd_putc("\f");
lcd_gotoxy(1,1);
lcd_putc("MEDIDOR PRESION");
delay_ms(1000);
lcd_putc("\f");
lcd_gotoxy(1,1);
lcd_putc("MEDIDOR PRESION");
lcd_putc("\n");
lcd_putc("Elegir unidades");
delay_ms(1000);
break;
}
}while (true);
}
-
Aqui os envio el codigo que utilizo ahora y que si funciona porque el vector es de 10, si le pongo de tamaño 50 o 100 me da error en la compilacion.
eleguez, ¿qué parte de todos los posts donde te dicen que te queda chico el micro no has entendido?
Más allá de eso, ¿puedes poner el mensaje de error que te da al compilar?
-
lo he entendido todo, pero me han pedido que envie el codigo. de todas formas puede ser que me quede pequeño pero no creo que sea por eso ya que con valores como 50 que si me valdria tampoco me funciona. El error que me da es "subscript out of range".
Un saludo
-
Hola Eleguez!
Pensa que no es SOLO el vector el que te consume memoria. Todas las demas variables que usas lo hacen, y muy posiblemente (esto es solo una especulacion mia por que no conozco realmente la forma en que trabaja el compilador) cada vez que haces una demora o cosas similares se crean variables internas que tambien utilizan memoria.
Saludos!
-
Teniendo la duda en que creo que las variables de ámbito global no se crearían en la RAM, sino que se crearían en la Data EEPROM. El resto de variables de vida corta, como por ejemplo el crear una variable en cierta función, for, while, etc, que creo que su creación si seria en la RAM. Que me lo confirmen o me corrijan los maestros :)
Haciendo caso a lo expuesto obtenemos las siguientes variables globales, que se crearían en la Data EEPROM
char cad1[7]="BARES";
char cad2[12]="ATMOSFERAS";
char cad3[5]="PSI";
char cad4[14]="KILOPASCALES";
int i=0;
int num=0;
long int KPa=0;
float atm=0;
float bar=0;
float psi=0;
float x=0;
float suma=0;
float vector[10];
A ver eleguez si con un vector de 10 elementos compila, si le pones de 50, 100 o 1000 elementos tipo float te dirá que eso no compila. Y con razón, si llega a compila es han encontrado la gallina de los huevos de oro, creación de espacio no fisico :D :D
Lo he ordenado según tamaño en bytes de las variables.
char = 1 Byte
int = 1 Byte
long int = 2 Bytes
float = 4 bytes
Usas ( 7 + 12 + 5 + 14 ) char en las cadenas, es un total de 38Bytes
Usas 2 int, total 2Bytes
Usas 1 Long int, total 2Bytes
Usas 5 float (sin contar el vector) , total 20Bytes
----------------------------------------------------------------------------------------
TOTAL: 38 + 2 + 2 + 20 = 62 Bytes
Si la memoria EEPROM de un 16F876A es de 256 Bytes. Tendrías un espacio restante 194Bytes.
Podrías crear un vector como longitud máxima de 48 elementos tipo float, quedándote libre 2bytes en la EEPROM.
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1335&dDocName=en010240
Saludos!
Diego J.
-
Aparte al compilar el programa da errores en estas lineas.
for (i=0;i<10;i++)
{
vector=vector[i+1]; // Aquí el error
}
Si tu vector es de 10 elementos, solo podrás moverte entre 0 a 9, y según en el for llegarías como max. a vector[9+1], ERROR
for (i=0;i<10;i++)
{
vector=read_adc(); // En este caso aquí
delay_ms(200);
}
en este último caso como en el anterior, estás metiendo los valores en "vector=.....", no lo estás trabajando como un array. El compilador no admite tener varias variables de diferentes tipos con el mismo nombre, comento esto por si vector es una variable que no te refieras al array de 10 elementos tipo float que creaste en las variables globales.
Saludos!
Diego J.
-
Haciendo pruebas con el CCS no me deja declarar vectores en ram de mas de 96 bytes, para float serian vectores de máximo 24 datos.
En el caso del vector de 100 posiciones tocaría dividir en 5 vectores de 20 cada uno, eso si contando primero con un pic que tenga ram suficiente para esta aplicación, creo que al menos 512 bytes.
La prueba con el CCS fue rápida, no sabía de esta limitante del CCS o si se debe hacer de otra forma.
saludos,
-
Haciendo caso a lo expuesto obtenemos las siguientes variables globales, que se crearían en la Data EEPROM
La idea es buena pero en mi opinión es mejor colocar las constantes en FLASH y en EEPROM si las mismas varían con frecuencia durante la ejecución del código durante su "tiempo de vida". Es decir si las variables son fijas y cada vez que lo grabamos las cambiamos pero luego nunca más, entonces -> FLASH.
Haciendo pruebas con el CCS no me deja declarar vectores en ram de mas de 96 bytes, para float serian vectores de máximo 24 datos.
Esto tiene sentido pensando en que la memoria en los 16F no es continua y el compilador debiera controlar todo el tiempo si se quiere acceder a un vector que está en una página u otra y los saltos no serían proporcionales además que la matemática de punteros sería nefasta!. Una recomendación, prueba el mismo idéntico código con un 18F.
El C18 para los 18F si permite crear arrays grandes y se vale para ello del uso del direccionamiento indirecto que tiene 2 bytes en estos pics (FSRH y FSRL).
Saludos
-
Hola dhmejia , hace tiempo tuve un problema similar y descubri que cuando declaras variables, el ccs las crea en el banco 0, pero aun tienes el banco 1, 2 y 3, asi que podrias usar estos bancos para almacenar tus vectores, para eso estan pensados, el ccs tiene "funciones " para escribir en los bancos write_bank y read_bank, si no me equivoco, porque no pruebas con estas
Saludos
-
Haciendo pruebas con el CCS no me deja declarar vectores en ram de mas de 96 bytes, para float serian vectores de máximo 24 datos.
Esto tiene sentido pensando en que la memoria en los 16F no es continua y el compilador debiera controlar todo el tiempo si se quiere acceder a un vector que está en una página u otra y los saltos no serían proporcionales además que la matemática de punteros sería nefasta!. Una recomendación, prueba el mismo idéntico código con un 18F.
Como siempre tienes razón, hice la prueba con un PIC18F2520 (nunca he trabajado con los pic18 asi que elegí uno al azar de la lista), declaré un vector de 1430 datos enteros y el compilador no dio error,según el CCS el porcentaje de uso de la ram quedó en 100%.
Con todo esto, creo la mejor solución para eleguez es usar un pic18
Hola dhmejia , hace tiempo tuve un problema similar y descubri que cuando declaras variables, el ccs las crea en el banco 0, pero aun tienes el banco 1, 2 y 3, asi que podrias usar estos bancos para almacenar tus vectores, para eso estan pensados, el ccs tiene "funciones " para escribir en los bancos write_bank y read_bank, si no me equivoco, porque no pruebas con estas
Tienes razón, pero toca partir el dato en varios vectores.
saludos
-
Cambiaria el pic, pero ya tengo todo configurado para el 16f876A. tengo el dispositivo construido etc.. si al final no logro mejorarlo lo dejare con un vector de 10. Si averigua algo más os lo contare.
Un saludo.