Autor Tema: Lectura y escritura de string en eeprom extera  (Leído 10851 veces)

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

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Lectura y escritura de string en eeprom extera
« en: 27 de Junio de 2009, 03:51:37 »
Hola amigos, he intentado por todos los medios hacer estas dos funciones, escribir y leer una string en una memoria externa I2C mediante punteros, lo logré a medias solo pude escribir, tengo esto y no me da la lectura, espero puedan ayudarme a encontrar el error, esto de las cadenas ya me esta volviendo loco :x:

Código: C#
  1. void write_string_eeprom(int32 address,char *data){
  2.    do{
  3.       write_ext_eeprom(address++,*data);
  4.       data++;
  5.    }while(*data!=0);
  6.    write_ext_eeprom(address,0);
  7. }
  8.  
  9. char *read_string_eeprom(int32 address,char *s1){
  10.    do{
  11.       *s1=read_ext_eeprom(address++);
  12.       s1++;
  13.    }while(*s1!=0);
  14.    *s1=0;
  15.    return s1;
  16. }

y la llamada a mis funciones, para verlas en el puerto serie:
Código: C#
  1. void funcion(){
  2.    char *leido;
  3.    char dato[]="111112";
  4.  
  5.    write_string_eeprom(5000,dato[0]);
  6.    ...
  7.    leido=read_string_eeprom(5000,leido);
  8.    printf("%s",leido);
  9. }

no se fijen mucho en la variable dato, simplemete hay que considerarlo como un string, con su null al final.

cuando lo pongo así no aparece nada en la linea del puerto serie, pero si uso un for en vez de la función read, leyendo letra por letra hasta encontrar el null si lo lee, por tanto de esa manera deduje que mi escritura esta bien, pero la lectura con punteros es la que falla.

Espero su ayuda, muchas gracias.

un saludo a todos.

.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Lectura y escritura de string en eeprom extera
« Respuesta #1 en: 27 de Junio de 2009, 05:40:21 »
Cryn, muéstranos tu función write_ext_eeprom() y te digo algo.  :mrgreen:
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Lectura y escritura de string en eeprom extera
« Respuesta #2 en: 27 de Junio de 2009, 08:08:45 »
Hola Cryn:

Código: C#
  1. char *read_string_eeprom(int32 address,char *s1){
  2.    do{
  3.       *s1=read_ext_eeprom(address++);
  4.       s1++;
  5.    }while(*s1!=0);
  6.    *s1=0;
  7.    return s1;
  8. }

Dos cositas:

Primero; para que haces que esta función devuelva la posicion(el puntero) de donde se encontró el final de la cadena(el caracter ASCII=0x00)?. La lectura podría no devolver nada o bien otra cosa como si se logró leer sin problemas, pero no lo que me parece que quisiste hacer.

Segundo: El do{}while(condición) asegura que el bucle se ejecute al menos una vez antes de revisar la condición del while(). Ahora te hago la pregunta: que pasa si estás ante una cadena nula? es decir, su primer caracter, es su caracter de fin(ASCII=0x00)? Sucederían cosas sumamente indeseadas...El algorítmo no se detendría hasta encontrar el próximo ASCII=0x00 en todo el mapa de la RAM...Lo mísmo te digo para el do{} while() de la rutina de escritura...


Por otro lado,

Código: C#
  1. void funcion(){
  2.    char *leido;
  3.    char dato[]="111112";
  4.  
  5.    write_string_eeprom(5000,dato[0]);
  6.    ...
  7.    leido=read_string_eeprom(5000,leido);
  8.    printf("%s",leido);
  9. }

Acá se combina el problema que te mencione antes con lo que devuelve la función. Uno generalmente manda  a imprimir un puntero con el primer caracter de la cadena. Vos estás mandando a imprimir justo desde el caracter ASCI=0x00 que es la posición que devuelve la función de lectura...

Resumiendo, intentalo así:

Código: C#
  1. void write_string_eeprom(int32 address,char *data){
  2.    while(*data!=0){
  3.       write_ext_eeprom(address++,*data);
  4.       data++;
  5.    }
  6.    write_ext_eeprom(address,0);
  7. }

Código: C#
  1. void read_string_eeprom(int32 address,char *s1){
  2.    while(*s1!=0){
  3.       *s1=read_ext_eeprom(address++);
  4.       s1++;
  5.    }
  6.    *s1=0;
  7. }

Código: C#
  1. void funcion(){
  2.    char *leido;
  3.    char dato[]="111112";
  4.  
  5.    write_string_eeprom(5000,dato[0]);
  6.    ...
  7.    read_string_eeprom(5000,leido);
  8.    printf("%s",leido);
  9. }

Un saludo.
« Última modificación: 27 de Junio de 2009, 08:12:47 por BrunoF »
"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 Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Lectura y escritura de string en eeprom extera
« Respuesta #3 en: 27 de Junio de 2009, 10:16:22 »
Cryn, muéstranos tu función write_ext_eeprom() y te digo algo.  :mrgreen:
Hola RedPic, esa la tengo incluída de la librería 241025.c del CCS, quedá así:

Código: C#
  1. void write_ext_eeprom(int32 address, BYTE data)
  2. {
  3.    int1 status;
  4.    int  command;
  5.  
  6.    if (address>65535)command=0xa8; // Check if address is located in Block 0/1
  7.    else command=0xa0;
  8.  
  9.    i2c_start();
  10.    i2c_write(command);
  11.    i2c_write(address>>8);
  12.    i2c_write(address);
  13.    i2c_write(data);
  14.  
  15.    i2c_stop();
  16.    i2c_start();
  17.    status=i2c_write(command);
  18.    while(status==1)
  19.    {
  20.       i2c_start();
  21.       status=i2c_write(command);
  22.    }
  23. }

Bruno, tienes mucha razón, pense en eso de que si se pasaba la menos una vez por la rutina, y que podría escribir y/o leer basura, pero estaba casi seguro que siempre las strings estaría con al menos un caracter. Pero si, es mejor hacerlo de la manera que sugieres.

Y ahora me doy cuenta de lo que dices sobre devolver el puntero a quien sabe donde apunta desde la dirección que quedo, lo que pretendo es que me devuelva el puntero a la string que leyó.

Hice los cambios en escritura y da bien, los cambios en lectura también los hice, pero sigue sin dar :(

que dicen?

muchas gracias por las respuestas, un saludo.
.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Lectura y escritura de string en eeprom extera
« Respuesta #4 en: 27 de Junio de 2009, 10:44:48 »
Hola

- Variable leido
Esta variable la declaras sin un tamaño dentro de la función 'funcion'. Esto está mal porque al ir llenando los chars de la variable se irán depositando en posiciones talvez no existentes de la memoria ram. Dale un tamaño del máximo string que almacenarás, de lo contrario podrías estar escribiendo ram ajena.

Código: [Seleccionar]
char leido[30];
- La línea write_string_eeprom(5000,dato[0]); está mal.
Debes pasarle un char* a la función write y lo que estás pasando es un char normal. Cámbiala así o así:

Código: [Seleccionar]
write_string_eeprom(5000,dato);
Código: [Seleccionar]
write_string_eeprom(5000,&dato[0]);
Si sigues teniendo problemas ponnos tu código actual.  :mrgreen:

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Lectura y escritura de string en eeprom extera
« Respuesta #5 en: 27 de Junio de 2009, 13:05:37 »
hola mig,

me base en esto al declarar mi variable leido:


pero quizá no sea correcto hacerlo así en CCS, no? coloque entonces como me recomendaste, pero quisiera manejarlo como variable puntero, si es que hubiera forma, claro:
char leido[10]; y al pasar el parametro:

read_string_eeprom(5000,&leido[0]); ó
read_string_eeprom(5000,leido); y ambas compilan bien.

El funcionamiento todavía no va bien, creo que hay algo mal todavía con mi función read, porque solo lee los primeros 2 caracteres, seguire revisando.

La funcion write me compilaba y estaba funcionando, en realidad estoy usando una matriz, no lo coloque para no liar mucho, pero esta sería mi matriz:

char datos[10][10]={"111112","2222223","33333334","444444445"};

y creo que solo puedo hacerlo de esa manera:

write_string_eeprom(5000,datos[0]);
porque cuando pongo la & no compila.

Solamanete son funciones de prueba, imprimendolas por puerto serie, así que no hay más codigo que ese. Quiero estas funciones para después trabajar más detalladamente después

muchas gracias pro ayuda, saludos.
« Última modificación: 27 de Junio de 2009, 14:35:05 por Cryn »
.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Lectura y escritura de string en eeprom extera
« Respuesta #6 en: 27 de Junio de 2009, 14:34:42 »
la verdad que no entiendo que pasa con mi funcion con punteros, la cambié por un for y esta como mencioné antes da muy bien:

Código: C#
  1. void read_string_eeprom(int32 address,char *s1){
  2.    int i,a;
  3.  
  4.    for(i=0;i<10;i++){
  5.       a=read_ext_eeprom(address+i);
  6.       if(a==0)
  7.          break;
  8.       s1[i]=a;
  9.    }
  10. }

la dejare con el for, aunque no me gusta la idea, porque mejor se verá con punteros :mrgreen: pero ya debo pasar a seguir programando, he perdido mucho tiempo

saludos, muchas gracias y si logro solucionarlo les aviso, y si logran ver algun error lo revisaré
.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Lectura y escritura de string en eeprom extera
« Respuesta #7 en: 27 de Junio de 2009, 14:51:39 »
Cryn, hay una cosa que echo en falta y que yo tuve que poner porque si no no había forma de que escribiese bien ... y es un pequeño delay de unos 5 ms tras escribir cada byte en la memoria externa. Es como si requiriese ese tiempo para dejar "fijado" en byte recién escrito en la EEPROM

Al mandar escribir todo un string se agolpaban los bytes y unos se escribían y otros no ... dale un vistazo a esto: Circuito y Driver C para 4 Memorias EEPROM 24AA1025 con un total de 512 Kbytes donde decía:

"Lo de los 5 milisegundos tras cada escritura es crítico. Poniendo 4 milisegundos se produce un error de cada tres escrituras. Con 3 milisegundos falla el 50% de las escrituras. Con esos 5 milisegundos no he tenido ningún error en miles de escrituras."

Así que le puse directamente el delay_ms(5) al final de la escritura de un byte en la EEPROM externa, y así me aseguraba de que siempre se cumpliría dicho retardo.

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Lectura y escritura de string en eeprom extera
« Respuesta #8 en: 27 de Junio de 2009, 15:14:20 »
Cryn, si declaras:

Código: [Seleccionar]
char *pmessage="ya es el tiempo";

El compilador reserva los chars que contiene la cadena, pero el problema es que declaras leido sin tamaño:

Código: [Seleccionar]
char *leido;

Y así el compilador solo reserva los 2 bytes de la dirección pero ningún byte para la cadena que deseas recibir en ella.

Para lograr que lo siguiente compile debes poner dos índices:

Código: [Seleccionar]
write_string_eeprom(5000,&datos[0][0]);
Diego, sobre el tiempo de espera de escritura de la eeprom, creo que la rutina de CCS ya tiene implementada la rutina de espera a que el dato quede bien grabado:

Código: [Seleccionar]
  status=i2c_write(command);
  while(status==1)
  {
     i2c_start();
     status=i2c_write(command);
  }

Cuando la eeprom ya está lista para recibir otro dato ella enviará un ACK (nivel lógico 0) pero mientras está grabando el bus estará en nivel lógico 1, es por eso que los de CCS pusieron el while. Aunque creo que el delay de 5ms que propones es bueno mientras la aplicación de Cryn no esté justa en tiempo.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Lectura y escritura de string en eeprom extera
« Respuesta #9 en: 27 de Junio de 2009, 15:28:54 »
Cryn, hay una cosa que echo en falta y que yo tuve que poner porque si no no había forma de que escribiese bien ... y es un pequeño delay de unos 5 ms tras escribir cada byte en la memoria externa. Es como si requiriese ese tiempo para dejar "fijado" en byte recién escrito en la EEPROM

Al mandar escribir todo un string se agolpaban los bytes y unos se escribían y otros no ... dale un vistazo a esto: Circuito y Driver C para 4 Memorias EEPROM 24AA1025 con un total de 512 Kbytes donde decía:

"Lo de los 5 milisegundos tras cada escritura es crítico. Poniendo 4 milisegundos se produce un error de cada tres escrituras. Con 3 milisegundos falla el 50% de las escrituras. Con esos 5 milisegundos no he tenido ningún error en miles de escrituras."

Así que le puse directamente el delay_ms(5) al final de la escritura de un byte en la EEPROM externa, y así me aseguraba de que siempre se cumpliría dicho retardo.


La librería de CCS, después de escribir un byte queda en espera de que la memoria escriba lo que a guardado en su Buffer interno (Condición ACK). Y no es necesario la demora que indicas. Lo curioso de estas memorias, es que por ejemplo en una 24LC512 demora los mismo en escribir un byte o una página de 128 bytes :shock: (aprox. 3ms)
No contesto mensajes privados, las consultas en el foro

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Lectura y escritura de string en eeprom extera
« Respuesta #10 en: 27 de Junio de 2009, 15:41:07 »
Esto funciona...

Código: C
  1. void write_string_eeprom(int32 address,char *data){
  2.    while(*data!=0){
  3.       write_ext_eeprom(address++,*data);
  4.       data++;
  5.    }
  6.    write_ext_eeprom(address,0);
  7. }
  8.  
  9. void read_string_eeprom(int32 address,char *s1){
  10.      s1--;
  11.   do{
  12.      s1++;
  13.      *s1=read_ext_eeprom(address++);
  14.   }while(*s1!=0);
  15. }

Código: C
  1. void main()
  2. {
  3.   char dato[]="HOLA MUNDO";
  4.   char *leido=&dato[0];
  5.   //...
  6.  
  7.  
  8.   write_string_eeprom(5000,&dato[0]);
  9.   read_string_eeprom(5000,leido);
  10.  
  11.   printf("Valor: %s\r\n",leido);
  12.   //...
"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 BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Lectura y escritura de string en eeprom extera
« Respuesta #11 en: 27 de Junio de 2009, 15:48:22 »
O para que se note mejor podría ser:

Código: C
  1. void main()
  2.       {
  3.        char mystr[40];
  4.        char dato[]="Todopic";
  5.        char *leido=mystr;
  6.        //...
  7.  
  8.        write_string_eeprom(5000,dato);
  9.        read_string_eeprom(5000,leido);
  10.        printf("Valor: %s\r\n",leido);
  11.        //...
"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 Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Lectura y escritura de string en eeprom extera
« Respuesta #12 en: 27 de Junio de 2009, 20:25:02 »
muchimas gracias a todos, de verdad :-/ :-/

Redpic, si leí ese hilo, y hasta recordé que había posteado ahí :mrgreen: y tenía alguna duda con ello, pero la verda que me grabó hasta ahora todos los datos muy bien, ya llevo unos 3000 datos grabados y todos hasta ahora en buen estado, seguramente es como Suky dice, gracias por los datos Suky! Y sí, estoy con muchos datos, así que el tiempo es oro jeje.

Mig, fue una confusión mía lo de los punteros sin espacio reservado, creí haber visto algo como mencionába, m e equivoque, gracias por hacermelo notar y por los consejos, y quisiera poder ver una función tuya con esa idea, para este caso de la lectura.

Bruno, le diste en el clavo, ahora si funciona el código, como dijsite, ahora estoy contento con los punteros, esque lían mucho. Gracias mil Bruno!!!!
pero me quedó una duda, de si es necesario hacerlo en 2 lineas, se puede en una?:
char mystr[40];
char *leido=mystr;

Saben de un lugar, tutorial, u otro donde pueda aprender todo sobre punteros, más que todo como paso de parametros en funciones, tanto al recibir como de retorno, leo y leo y encuentro lo mismo de siempre, nada que me satisfaga y me sienta capaz de darle con confianza a las cadenas y funciones con punteros.

Son GENIALES!!! :-/ :-/ :-/
.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Lectura y escritura de string en eeprom extera
« Respuesta #13 en: 28 de Junio de 2009, 15:37:01 »
Saben de un lugar, tutorial, u otro donde pueda aprender todo sobre punteros, más que todo como paso de parametros en funciones, tanto al recibir como de retorno, leo y leo y encuentro lo mismo de siempre, nada que me satisfaga y me sienta capaz de darle con confianza a las cadenas y funciones con punteros.

Son GENIALES!!! :-/ :-/ :-/

¿No conoces el tutorial de Pedro Palitroquez?  :shock:

El tema de los punteros...
http://www.todopic.com.ar/foros/index.php?topic=16680.0

Edito: te escribo una función rápida para leer una cadena almacenada en una eeprom externa... escrita al vapor así que te tocará probarla.

Código: [Seleccionar]
//Recibe:
//direccion - dirección en donde empieza a leer la eeprom
//cadena - un arreglo de chars con ram apartada para volcar la cadena
//chars_max - un número máximo de chars a leer para evitar escritura de ram ajena
void lee_cadena_eeprom(int16 direccion, char *cadena, int8 chars_max)
{
while(chars_max-- != 0)
   {
   *cadena=read_ext_eeprom(direccion++);
   if(*cadena==NULL) return;
   ++cadena;
   }
*(--cadena)=NULL; //Por si rebasó los chars_max, asegura que la cadena tenga fin
}

...

//Ya dentro del main
char cadena_leida[30]; //Recibe hasta 29 chars y un NULL char
lee_cadena_eeprom(direccion, cadena_leida, 30);
« Última modificación: 28 de Junio de 2009, 16:03:48 por migsantiago »

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Lectura y escritura de string en eeprom extera
« Respuesta #14 en: 28 de Junio de 2009, 17:06:58 »
si, vi el temon de Pali, con ese tema me inicie aquella vez, pero Pali lo suspendió porque no hizo la parte de recibir cadenas y devolver cadenas, y las combinaciones más comunes, usuales y correctas, que me cuesta tenerlas.

muchas gracias mig, la pruebo y te aviso, un saludo.
.


 

anything