Autor Tema: Alguien ha podido manejar memorias externas i2c con FORCE_HW? (solucionado)  (Leído 4970 veces)

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

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Qué tal gente todopic!
Pues aquí estoy nuevamente yo para hacerles una consulta...
Estoy manejando una memoria EEPROM externa 24LC256 para guardar variables de tipo float, el código que uso es este:

Código: C
  1. #include <16f877.h>
  2. #fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT
  3. #define RX                              PIN_C7
  4. #define Tx                              PIN_C6
  5. #define EEPROM_SDA      PIN_C4
  6. #define EEPROM_SCL      PIN_C3
  7. #use fast_io(A)
  8. #use fast_io(B)
  9. #use fast_io(C)
  10. #use fast_io(D)
  11. #use fast_io(E)
  12. #use delay (CLOCK=20000000)
  13. #use rs232 (BAUD=19200,XMIT=Tx,RCV=Rx)
  14. #use i2c (MASTER,SCL=EEPROM_SCL,SDA=EEPROM_SDA)
  15. #byte porta = 0x05
  16. #byte portb = 0x06
  17. #byte portc = 0x07
  18. #byte portd = 0x08
  19. #byte porte = 0x09
  20. #locate valor = 0x20
  21. #include <24256.c>
  22.  
  23. void envia_float_ext_eeprom (long int adress,float data)
  24. {
  25.         float *p,*q;
  26.         int k,buffer_out[4];
  27.         p=&data;
  28.         q=&buffer_out[0];
  29.         memcpy(q,p,4);
  30.         for(k=0;k<4;k++)write_ext_eeprom(adress+k,buffer_out[k]);
  31. }
  32.  
  33. float recibe_float_ext_eeprom (long int adress)
  34. {
  35.         float data,*r,*s;
  36.         int t,buffer_in[4];
  37.         r=&buffer_in[0];
  38.         s=&data;
  39.         for(t=0;t<4;t++)buffer_in[t]=read_ext_eeprom(adress+t);
  40.         memcpy(s,r,4);
  41.         return(data);          
  42. }
  43.  
  44. void main (void)
  45. {
  46.         float valor,valor_recibido;
  47.         PORTA = 0x00;  
  48.         PORTB = 0x00;
  49.         PORTC = 0x00;
  50.         PORTD = 0x00;
  51.         PORTE = 0x00;
  52.         set_tris_a(0b00000000);
  53.         set_tris_b(0b00000000);
  54.         set_tris_c(0b10010000);
  55.         set_tris_d(0b00000000);
  56.         set_tris_e(0b00000000);
  57.         init_ext_eeprom();
  58.         valor=-100.2;
  59.         while(TRUE)
  60.         {      
  61.                 envia_float_ext_eeprom (0,valor);
  62.                 valor_recibido=recibe_float_ext_eeprom(0);             
  63.                 printf("Valor en EEPROM 0x0000 = %f\n\r",valor_recibido);
  64.         }      
  65. }

Sencillamente estoy dándole diversos valores a la variable "valor" y viendo a ver qué tal va...
La cuestión está en que pruebo tal como está y funciona bien, pero cuando agrego en la opción "FORCE_HW" en el #use i2c, no me funciona tan bien la interfaz con la eeprom.
Fíjense, esto es lo que muestra la terminal del proteus (olvidé comentarlo, lo estoy probando con proteus, no en físico aún):

Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20

En cambio cuando le coloco el FORCE_HW, me sale esto:

Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = -100.20
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = -127.99
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00
Valor en EEPROM 0x0000 = 0.00

Como ven, los primeros cinco valores están perfectos, pero luego se echa a perder la cosa...
También he probado colocando FORCE_HW y SLOW, pero da lo mismo.

Qué creen ustedes? Alguien ha probado la interfaz i2c con FORCE_HW para manejar memorias externas exitosamente?
Será un error del proteus?

Bueno desde ya les agradezco grandemente sus comentarios.
Allí les dejo el archivo con la simulación en proteus y el .hex (ese .hex es de la última compilación, que incluye el FORCE_HW con SLOW)...

Ok saludos, nos leemos!  :mrgreen:
« Última modificación: 28 de Julio de 2008, 23:45:29 por firepic »
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #1 en: 20 de Junio de 2008, 14:17:46 »
Qué tal gente todopic!
Estoy consciente de que este posiblemente sea un tema trivial para muchos de ustedes, pero no logro resolverlo!  :(
Ví los ejemplos de redpic y no usa FORCE_HW.
Luego vi un hilo por alli donde alguien preguntó sobre el mismo problema, pero el lo logró solucionar de una forma que a mí no me da resultados.
He intentado cambiando la librería, me he leído el manual completico, pero nada, no logro conseguir que funcione correctamente con el FORCE_HW.
Sin el FORCE_HW va perfecto.
Nuevamente les agradezco sus respuestas de antemano.
Saludos, nos leemos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #2 en: 20 de Junio de 2008, 18:26:03 »
No, Firepic. Desde hace tiempo yo uso el FORCE_HW y va de lujo, y con menos código al usar el módulo hardware del PIC.  :mrgreen:

Código: C#
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Canales de Comunicación : i2c
  4. //
  5. ///////////////////////////////////////////////////////////////////////////////////////////////////
  6.  
  7. #define H1_CK_W1_SDA PIN_B0
  8. #define H1_DT_W0_SCL PIN_B1
  9.  
  10. #define SDA_CHANNEL  H1_CK_W1_SDA
  11. #define SCL_CHANNEL  H1_DT_W0_SCL
  12.  
  13. #use i2c(master, sda=SDA_CHANNEL, scl=SCL_CHANNEL, FORCE_HW)
  14.  
  15. ///////////////////////////////////////////////////////////////////////////////////////////////////
  16. //
  17. // End of _i2c.h
  18. //
  19. ///////////////////////////////////////////////////////////////////////////////////////////////////

Es absolutamente fundamental que los Pines utilizados sean exactamente los que el PIC tiene conectados al módulo hardware del I2C y que vienen marcados con las funciones SDA y SCL. De otra forma no puede funcionar con el  FORCE_HW.

En mi caso para un 18F4550 son B0 y B1.
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #3 en: 20 de Junio de 2008, 21:09:02 »
Gracias por tu respuesta, maestro Diego.
Pues si, los pines que estoy usando son los que proporciona el hardware del pic para el modulo i2c.
Ahora bien, una pregunta: usas las librerías para manejo de memorias externas que vienen con el ccs, como la 24256.C, o haces el código tú solito?
Podrías colgarme un código de ejemplo, por favor?
Yo estuve analizando el hilo que colgaste hace un tiempo, con comunicación a la PC y a la memoria externa, pero en ese no tienes el FORCE_HW.
De antemano te agradezco la ayuda que puedas darme...
Saludos, nos leemos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #4 en: 21 de Junio de 2008, 03:10:21 »
Este programa támpoco funciona bien con el FORCE_HW. Probado con PROTEUS y también físicamente por Jeremy ( http://www.todopic.com.ar/foros/index.php?topic=22021.0 )

Código: [Seleccionar]
#INCLUDE <18F2550.h>

#FUSES XTPLL      //Cristal mayor de 4Mhz y usando el PLL interno del pic para modificar aumentarlo/disminuirlo.
#FUSES NOWDT
#FUSES NOPROTECT  //No proteger el PIC contra lectura.
#FUSES PUT        //El Power Up Timer(PUT) espera unos nilisegundos antes de iniciarse el PIC.
#FUSES NOBROWNOUT //No uso reset automatico cuando se encuentra alguna baja tension especificada.
#FUSES NOLVP      //No usare programacion en bajo voltaje.
#FUSES PLL1       //Se divide entre 1 el oscilador(4Mhz) a la entrada del divisor porque el sistema necesita estos 4Mhz para generar 48Mhz para el usb.
#FUSES CPUDIV1    //Esto es para la velocidad conque el PIC trabajara. Esta dividido entre 1, entonces trabajara tambien a 48Mhz.


#USE Delay (Clock = 48 000 000)

//#USE RS232 (Baud = 115200, xmit = Pin_C6, rcv = Pin_C7)
#USE RS232 (Baud = 9600, xmit = Pin_C6, rcv = Pin_C7) //Pongo esta porque el PROTEUS no tiene 115200 baud


//¡¡¡Sin el Force_HW va bien!!!
#USE I2C (Master, SDA = Pin_B0, SCL = Pin_B1, Slow, Stream = RTC) //1º el RELOJ, 2º la EEPROM
#USE I2C (Master, SDA = Pin_B0, SCL = Pin_B1, Fast = 400000, Stream = ExtEEprom)


/*
//¡¡¡Sin el Force_HW va bien!!!
#USE I2C (Master, SDA = Pin_B0, SCL = Pin_B1, Fast = 400000, Stream = ExtEEprom) //1º la EEPROM, 2º el RELOJ
#USE I2C (Master, SDA = Pin_B0, SCL = Pin_B1, Slow, Stream = RTC)
*/

/*
//¡¡¡Con el Force_HW va mal!!! --> La EEPROM solo lee la primera posición
#USE I2C (Master, Force_HW,SDA = Pin_B0, SCL = Pin_B1, Slow, Stream = RTC) //1º el RELOJ, 2º la EEPROM
#USE I2C (Master, Force_HW,SDA = Pin_B0, SCL = Pin_B1, Fast = 400000, Stream = ExtEEprom)
*/

/*
//¡¡¡Con el Force_HW va mal!!! --> El reloj no va bien
#USE I2C (Master, Force_HW,SDA = Pin_B0, SCL = Pin_B1, Fast = 400000, Stream = ExtEEprom) //1º la EEPROM, 2º el RELOJ
#USE I2C (Master, Force_HW,SDA = Pin_B0, SCL = Pin_B1, Slow, Stream = RTC)
*/

#include "ds1307_modificado.c"      //Funciones para el uso del Real Time Clock del integrado DS1307.
#include "24512_modificado.c"       //Funciones para el uso de la memoria volatil serial eeprom externa 24LC256.


void main(void)
{     
   int8  DS1307DiaA, DS1307MesA, DS1307AnoA, DS1307DSA, DS1307HoraA, DS1307MinutoA, DS1307SegundoA;
   int8 Buffer[256];
   int16 cont, i;   
   
   init_ext_eeprom();      //Inicializo la EEprom externa.
   
   ds1307_init();          //inicializamos el RTC (DS1307).

   ds1307_set_date_time(17, 6, 8, 4, 9, 00, 00); //día-més-año-día semana-horas-minutos-segundos
   
   cont = 0;
   delay_ms(300);

   while (TRUE)
   {
      delay_ms(50);

      ds1307_get_date(DS1307DiaA, DS1307MesA, DS1307AnoA, DS1307DSA);
      ds1307_get_time(DS1307HoraA, DS1307MinutoA, DS1307SegundoA);
     
      printf("\n\r%02u/%02u/%02u  %u\n\r%02u:%02u:%02u", DS1307DiaA, DS1307MesA, DS1307AnoA, DS1307DSA, DS1307HoraA, DS1307MinutoA, DS1307SegundoA);

      delay_ms(1000);
                 
      printf("     Direcion[%Lu] -> %03u", cont, read_ext_eeprom(cont));
      putc('\r');
      cont++;

      printf("\r\n\nEmpezando lectura secuencial de 24LC512...");
      read_ext_eeprom_seq(Buffer, 0, 255);
      printf(" Terminada:\r\n");
     
      for (i = 0; i <= 255; i++)
         printf("%03u ", Buffer[i]);

/*
      for (i = 0; i <= 255; i++)
      {
      Buffer[i]=read_ext_eeprom(i); //Otra forma
         printf("%03u ", Buffer[i]);
      }   
*/
     
   }
}

« Última modificación: 21 de Junio de 2008, 03:39:02 por pocher »

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #5 en: 21 de Junio de 2008, 04:40:11 »
Sin embargo Firepic si quitas el reloj y dejas sola la memoria con el FORCE_HW sí que va bien.

¡Voy a probar tu programa!

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #6 en: 21 de Junio de 2008, 05:03:09 »
La librería que uso esta completa escrita por mí. La tienes en Circuito y Driver C para 4 Memorias EEPROM 24AA1025 con un total de 512 Kbytes
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #7 en: 21 de Junio de 2008, 05:53:15 »
Lo estoy probando ... huele a PROTEUS por todos lados. Que al principio salgan bien y luego mal no me cuadra.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #8 en: 21 de Junio de 2008, 06:18:31 »
¡¡¡ Vale ya está !!!. Sustituye las R=10K por PULLUPS y te funcionará.


Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #10 en: 21 de Junio de 2008, 10:44:39 »
Gracias maestros Redpic, Pocher!
Pues ese era el problema. Coloqué las Pullups y ahora funciona de lujo...  :-/
Ahora bien, cuando lo monte en físico, le coloco las R=10K? O qué valor me sugieren?
Saludos, nos leemos!  :mrgreen:
« Última modificación: 21 de Junio de 2008, 14:28:44 por firepic »
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #11 en: 21 de Junio de 2008, 12:05:22 »
Según data:

- Típica 10K para 100khz

- 2k para 400khz-1Mhz

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #12 en: 21 de Junio de 2008, 14:30:47 »
Gracias de nuevo, gran Pocher.
Ya tengo la memoria, ahora lo voy a montar en físico y a ver qué tal va...  :)
Saludos, nos leemos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado firepic

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1130
    • JC Servicios
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW? (solucionado)
« Respuesta #13 en: 29 de Junio de 2008, 12:59:05 »
Se me olvidó comentarles que lo monté en físico y también funciona de lujo!  :-/
Muchas gracias por sus comentarios, me han sido de gran ayuda!
Saludos, nos leemos!  :mrgreen:
"Por la presunción solo se ocasiona una lucha, pero con los que consultan juntos hay sabiduría" (Proverbios 13:10).
Visita Mi Sitio Web

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: Alguien ha podido manejar memorias externas i2c con FORCE_HW?
« Respuesta #14 en: 16 de Abril de 2009, 19:50:53 »
Según data:

- Típica 10K para 100khz

- 2k para 400khz-1Mhz

hola Amigos

El valor de la Resistencia según la frecuencia se refiere a la resistencias pullup del i2c pero el rango de frecuencia
a que se refiere, al que del cristal que se usa?

Si es de 4Mhz o de 20Mhz sera de 2k

¿Es eso?...pregunto

en algunos sitios recomiendan la de 4k7 pero en otros sitios dicen que se puede calcular.!

Puden sacarme de dudas?

un saludo.