TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: jeremylf en 04 de Junio de 2008, 00:37:59

Título: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jeremylf en 04 de Junio de 2008, 00:37:59
Hola foro. Veran, tengo un RTC (DS1307) y una memoia serial (24LC512). Ambos, cmo sabran se comunican por i2c. Tambien (y cmo maestro) tengo al 18F2550 usando su i2c por hardware para comunicarme con esos dispositivos esclavos.

Lo que sucede, es que el RTC, su velocidad de trabajo (su linea de clock), alcanza como maximo a 100khz; mientras que la de la memoria llega hasta los 400khz. Pues cmo necesito la mayor velocidad en la memoria y cmo el hardware i2c del pic solo puede generar en su pin SCL una sola frecuncia, termine haciendo dos buses i2c: uno por hardware (para la memoria) y el otro por software (para el RTC). Eso hasta que me dijieron que se puede setear la velocidad o baudaje y ver cmo habia ejemplos que usaban varios #use i2c o rs232, etc (Si, estoy usando el CCS xD (el 4.023 porsiak =D)).

Asique me decidi por probar y, viendo unos ejemplos de lo mismo pero con rs232, pense que podria lograr hacerlo funcionar, ocea: hacar trabajar dos dispositovos (en este caso un RTC y una memoria EEPROM) con diferentes velocidad de trabajo (100khz y 400khz respectivamente segun el parentesis anterior xD) en un solo bus i2c por el hardware de un pic (el 18F2550).

Haciendo este codigo:
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 I2C (Master, Force_HW, Slow, SDA = Pin_B0, SCL = Pin_B1, Stream = RTC)
#USE I2C (Master, Force_HW, Fast = 400000, SDA = Pin_B0, SCL = Pin_B1, Stream = ExtEEprom)


#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)
{     
   unsigned int8  DS1307DiaA, DS1307MesA, DS1307AnoA, DS1307DSA, DS1307HoraA, DS1307MinutoA, DS1307SegundoA;
   unsigned int8 Buffer[256];
   unsigned int16 cont, i;
   
   delay_ms(1500);
   printf("\r\n\n\n-----------jeremy-----------\r\n\n\n");

   ds1307_init();          //inicializamos el RTC (DS1307).
   //init_ext_eeprom();      //Inicializo la EEprom externa.

   ds1307_set_date_time(29, 5, 8, 4, 11, 8, 0);
   
   cont = 0;
   delay_ms(300);

   while (TRUE)
   {
      delay_ms(1000);
      /////////////////////////////
     
      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);
                 
      printf("     Direcion[%Lu] -> %03u", cont, read_ext_eeprom(cont));
      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]);
      }   
      ////////////////////////////////////
   }
}

Y el problema aqui viene:
(http://img146.imageshack.us/img146/4863/dibujoez7.jpg)


Como se ve, lo que es la fecha y hora, esta bien, perfecto. Pero lo que es la lectura secuencial echa a la memoria eeprom... Es una catrastrofe xD! Esos datos son erroneos. Ahora veran porque:
(http://img160.imageshack.us/img160/2269/dibujo2lj8.jpg)

Esta imagen corresponde a un cambio que hice en el codigo anterior y que, ahora si, la lectura a la eeprom (por el modo secuencial (ver datasheet xD)), es correcta, ocea que esos 256 datos leidos si son los que estan ahi. PERO! que esta mal? la fecha y la hora, enrealidad los segundos si avanzan y "el numero del dia" (1 - 7) esta bien tambien, pero en si, esta mal lo que se lee... se entiende?

...Y lo peor de todo... Que lo que cambie del codigo para que pase eso? Pues simplmente los #USE I2C. Ocea que si el "#USE I2C" del RTC esta primero, el es el que funciona bien y la lecuta secuencial de la memoria falla (imagen 1). Si es alraves, es la lectura secuancial de la memoria la que funciona bien y la lectura del dia, mes, año, minuto y segundo del RTC falla (imagen 2).

Algo que agregar esque cuando es "el RTC el que va primero" el modo de lectura secuencial de la memoria falla, PERO su lectura normal o random funciona bien. Que lo muestra un printf del codigo, justo despues de mostrar la fecha y hora del RTC: "Direcion[ x ] -> ABC".

Bueno, espero se entiendo bien todo =D Q dicen? Acaso tiene que ver quien va primero o quien va despues? O si esque eso se puede? Que falta? Q sucede? oO!


Gracias por la leida x)
Un saludo!


PD: Dejo tambien los .c del ds1307 y 24lc512 que cmo bien dicen algo sus nombres, estan algo modificados, aunq enrealidad e agregado solo al 24lc512 lo de lectua secuencial. Bueno, de eso no me preocupo porque eso si funciona bien. Es eso de los #use  :x xD!


Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: RICHI777 en 04 de Junio de 2008, 15:36:55
Perdon por mi ignorancia ( no conozco los Pics ) , pero no es posible cambiar la base de tiempo del reloj del SPI en run-time ?

Saludos !
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: MGLSOFT en 05 de Junio de 2008, 08:26:49
Yo utilize multivelocidad en RS232, con 4 declaraciones y el mismo patillaje, pero cada vez que estas cambiando debes definir la velocidad a la que trabajas...
Prueba poner la declaracion antes de utilizar cada chip... :mrgreen:
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: firepic en 05 de Junio de 2008, 16:36:27
Buena observación la que hace MGLSOFT, ayer quería comentar en este hilo pero justamente en ese momento la página murió  :D
La cosa Jeremy es que estás usando el mismo "patillaje" como dice MGLSOF, para ambos buffers... así que tienes dos opciones: o cambias los pines de uno de los buffers y así tienes dos buffers distintos sin problemas, o haces lo que dice el maestro MGLSOFT. Debería funcionarte sin problemas.
Ok saludos, nos leemos!  :mrgreen:
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jeremylf en 06 de Junio de 2008, 00:14:25
No entiendo. Con "patillaje" se refieren a la velocidad? Pero en cada "#use i2c" uno esta puesto a 100khz (slow) y otro a 400khz (fast)  :?

Lo de cambiar un chip a otro bus, pues asi antes lo tenia. Pero la idea esq los dos chips, con comunicacion i2c, esten en un mismo bus. O almenos es lo q quiero lograr (si ay la posibilidad claro  :lol:).


Gracias por responder.
Salu2.
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: MGLSOFT en 06 de Junio de 2008, 08:18:52
Nos referimos a que utilizes algo asi:
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 I2C (Master, Force_HW, Slow, SDA = Pin_B0, SCL = Pin_B1, Stream = RTC)
#USE I2C (Master, Force_HW, Fast = 400000, SDA = Pin_B0, SCL = Pin_B1, Stream = ExtEEprom)


#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)
{     
   unsigned int8  DS1307DiaA, DS1307MesA, DS1307AnoA, DS1307DSA, DS1307HoraA, DS1307MinutoA, DS1307SegundoA;
   unsigned int8 Buffer[256];
   unsigned int16 cont, i;
   
   delay_ms(1500);
   printf("\r\n\n\n-----------jeremy-----------\r\n\n\n");
#USE I2C (Master, Force_HW, Slow, SDA = Pin_B0, SCL = Pin_B1, Stream = RTC)

   ds1307_init();          //inicializamos el RTC (DS1307).
   //init_ext_eeprom();      //Inicializo la EEprom externa.

   ds1307_set_date_time(29, 5, 8, 4, 11, 8, 0);
   
   cont = 0;
   delay_ms(300);

   while (TRUE)
   {
      delay_ms(1000);
      /////////////////////////////
     
      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);
                 
      printf("     Direcion[%Lu] -> %03u", cont, read_ext_eeprom(cont));
      cont++;
      //////////////////////////////////

      printf("\r\n\nEmpezando lectura secuencial de 24LC512...");
#USE I2C (Master, Force_HW, Fast = 400000, SDA = Pin_B0, SCL = Pin_B1, Stream = ExtEEprom)
      read_ext_eeprom_seq(Buffer, 0, 255);
      printf(" Terminada:\r\n");
     
      for (i = 0; i <= 255; i++)
      {
         printf("%03u ", Buffer[i]);
      }   
      ////////////////////////////////////
   }
}

Luego en forma mas organizada podras hacerlo como recomienda CCS, buscando en las FAQ en su sitio o en su foro... :mrgreen:
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: firepic en 06 de Junio de 2008, 10:31:26
No entiendo. Con "patillaje" se refieren a la velocidad? Pero en cada "#use i2c" uno esta puesto a 100khz (slow) y otro a 400khz (fast)  :?
No. Se refiere a las "patillas" que usas para el bus (para SDA, SCL). Que son las mismas en cada caso y corresponden a las que el pic tiene apartadas para esas funciones (ya que estás implementándolo por hardware).
Ya el maestro MGLSOFT te explicó bastante ilustrada cuál es la idea.  :P
Saludos, nos leemos!  :mrgreen:
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jeremylf en 07 de Junio de 2008, 02:52:35
Que yo sepa esa directiva #Use i2c solo se puede usar al compilar, y no en tiempo de ejecucion... =/

Gracias igualmente por las respuestas.
Un saludo.
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: MGLSOFT en 07 de Junio de 2008, 08:43:13
Siquiera lo has probado?? :shock:
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: Nocturno en 07 de Junio de 2008, 11:51:43
Yo de ti lo probaría al menos.
En este otro hilo pude comprobar cómo el #use i2c también funciona en tiempo de ejecución.
http://www.todopic.com.ar/foros/index.php?topic=21967.msg172416#msg172416
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: firepic en 07 de Junio de 2008, 12:06:56
Jeremy muchas directivas #use, como la 232, la i2c, la spi (bueno esas son las que yo he probado al menos) se pueden probar en ejecución tranquilamente.
Lo que tienes que hacer es colocar la directiva antes de la función que usa la característica declarada en el #use (en tu caso el i2c correspondiente)... y listo.
Nocturno lo ha probado también y funciona de maravilla.
Así que, a probar pues!  :D
Verás que te sale perfecto.
Ok saludos, nos leemos!  :mrgreen:
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: pocher en 07 de Junio de 2008, 12:23:56
Sí funcionan perfectamente en tiempo de ejecución, yo también lo comprobé con algunos programas.
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jeremylf en 07 de Junio de 2008, 19:19:57
Hola. Acabo de probarlo y tengo el mismo resultado =(

Asi tengo el codigo ahora:

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 I2C (Master, Force_HW, Slow, SDA = Pin_B0, SCL = Pin_B1, Stream = RTC)
#USE I2C (Master, Force_HW, Fast = 400000, SDA = Pin_B0, SCL = Pin_B1, Stream = ExtEEprom)


#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)
{     
   unsigned int8  DS1307DiaA, DS1307MesA, DS1307AnoA, DS1307DSA, DS1307HoraA, DS1307MinutoA, DS1307SegundoA;
   unsigned int8 Buffer[256];
   unsigned int16 cont, i;
   
   delay_ms(1500);
   printf("\r\n\n\n-----------jeremy-----------\r\n\n\n");
#USE I2C (Master, Force_HW, Slow, SDA = Pin_B0, SCL = Pin_B1, Stream = RTC)
   ds1307_init();          //inicializamos el RTC (DS1307).
   //init_ext_eeprom();      //Inicializo la EEprom externa.

   ds1307_set_date_time(29, 5, 8, 4, 11, 8, 0);
   
   cont = 0;
   delay_ms(300);

   while (TRUE)
   {
      delay_ms(1000);
      /////////////////////////////
      #USE I2C (Master, Force_HW, Slow, SDA = Pin_B0, SCL = Pin_B1, Stream = RTC)
      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);
     
      #USE I2C (Master, Force_HW, Fast = 400000, SDA = Pin_B0, SCL = Pin_B1, Stream = ExtEEprom)
      printf("     Direcion[%Lu] -> %03u", cont, read_ext_eeprom(cont));
      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]);
      }   
      ////////////////////////////////////
   }
}

Que puede estar mal? Es acaso un bug del CCS? O es que no se puede hacer funcionar dos velocidades diferentes en el hardware I2C del PIC18F2550 ?   :?

Gracias por todo.
Salu2.
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: firepic en 07 de Junio de 2008, 21:36:55
Saludos jeremy!
Si colocas los #use i2c, no hace falta que agregues el STREAM=id.
Espero puedas solventar tu problema.
Sigue revisando el código, las dos i2c sí que funcionan.
Ok nos leemos!  :mrgreen:
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jfh900 en 08 de Junio de 2008, 08:59:07
Haber, no puedes poner los mismos pines para los dos buses. Declara cada bus en pines distintos.

Un saludo
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: pocher en 08 de Junio de 2008, 15:40:36
Solo tiene un bus al que tiene conectado un RTC y una MEM (más el PIC) y cuando usa el RTC lo quiere hacer correr a velocidad lenta y cuando usa la MEM a velocidad alta.

Debe de funcionar, será una tonteria.
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jeremylf en 08 de Junio de 2008, 22:16:33
Solo tiene un bus al que tiene conectado un RTC y una MEM (más el PIC) y cuando usa el RTC lo quiere hacer correr a velocidad lenta y cuando usa la MEM a velocidad alta.

Debe de funcionar, será una tonteria.
Exacto. Solo que no es que quiera sino que es lo que me queda, ya que el RTC DS1307 su maxima velocidad de trabajo es de 100khz y el de la memoria 24LC512 llega hasta 400khz y en la memoria tengo que usarlo a esa velocidad. Pero la idea es poner ambos en un solo bus.

No encuentro la solucion  :?
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jfh900 en 08 de Junio de 2008, 22:37:06
No se pueden poner en el mismo bus, se interfieren entre ellos.

Un saludo
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: pocher en 09 de Junio de 2008, 02:36:51
No entiendo Jesús, podrías explicar esto.

Si para activar uno lo direccionas por ejemplo con 0xA0 y para activar el otro lo direccionas con 0xA2 porqué tienen que interferir (caso de un pcf8583 y una MEM 24LC64 que son los que yo probé en su día).
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jfh900 en 09 de Junio de 2008, 06:31:45
Al ser distintas las velocidades uno de ellos funcionará bien, pero el otro recibirá basura (el de menor velocidad) ya que no es capaz de seguir al de mayor velocidad, pudiendo responder o incluso bloquear el bus.   ¿Tu los probastes a distintas velocidades?

Un saludo
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: pocher en 09 de Junio de 2008, 09:11:35
No yo los probé a la misma velocidad. Me gustaría probarlo para salir de dudas, ya que jeremylf está cambiando de dispositivo y velocidad en tiempo de ejecución y no le va.
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: firepic en 09 de Junio de 2008, 09:42:58
Jeremy he notado que estás forzando a hacer el i2c por hardware... estás usando la interrupción por i2c?
Si la respuesta es no, por qué no pruebas a hacerlo por software? Es, decir, quitar el Force_HW?
Bueno es una opción que se me ocurre en mi ignorancia...  :D
Qué te parece?
Si es una idea descabellada y ridícula pido a los más expertos en el foro que lo aclaren por favor...
Ok saludos, nos leemos!  :mrgreen:
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jeremylf en 09 de Junio de 2008, 12:25:42
Claro que fallaria si el bus se trabajara a una sola velocidad nada mas. Por eso, pense en que se podria setear o cambiar la velocidad de trabajo del hardware i2c del pic cada ves que necesito usar una funcion del RTC o la memoria; me dijieron que se podria, en RS232 se puede  :(

Firepic, creo haberlo probado tb por software solo por descartar, pero la idea es usar el hardware (almenos es lo que quiero) y hacerlo funcionar  :lol:


Gracias por las respuestas.
Salu2.
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: RICHI777 en 09 de Junio de 2008, 17:46:46
Hola, estube mirando las hojas de datos de los 2 chips y no le encuentro la vuelta, por la sencilla razon de que se tiene que trabajar a la máxima velocidad del más lento de los dispositivos, en este el DS1307, y como ninguno de los 2 tiene CS ( chip select ) si se te acabaron las posiblidades y te queda un port disponible porque no le reventas la tension de alimentación al DS1307. Por lo que estube mirando solo consume 1.5 mA en operacion normal ( 100 Khz en SCL ) suficiente para cualquier Port, entonces cuando necesitas "hablar" con la memoria le matas la VCC, este queda en stand-by, y trabajas  a 400 KHz. Cuando necesitas hablar con el DS le levantas la VCC. Es medio chancho pero deberia funcionar.
Saludos !
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: RICHI777 en 09 de Junio de 2008, 17:53:42
Citar
Si la respuesta es no, por qué no pruebas a hacerlo por software? Es, decir, quitar el Force_HW?
Bueno es una opción que se me ocurre en mi ignorancia... 
Qué te parece?
Si es una idea descabellada y ridícula pido a los más expertos en el foro que lo aclaren por favor...

Las 3 formas de implementar IIC en un micrito que yo conozco son estas:


Saludos !
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jfh900 en 09 de Junio de 2008, 19:15:27
Claro que fallaria si el bus se trabajara a una sola velocidad nada mas. Por eso, pense en que se podria setear o cambiar la velocidad de trabajo del hardware i2c del pic cada ves que necesito usar una funcion del RTC o la memoria; me dijieron que se podria, en RS232 se puede  :(

Creo que estas confundiendo las cosas. La comunicación RS232 funciona cuando se separan los dos canales de comunicación por dos puertos distintos. Poner juntos dos RS232 por las mismas patillas y a distintas velocidades nunca a funcionado ni funcionará.

Un saludo
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jeremylf en 09 de Junio de 2008, 23:18:29
jfh900 me refiero a cambiar la velocidad de trabajo, como la funcion set_uart_speed, algo similar pero que solo se entienda que es lo que intento lograr  :mrgreen:

Porcierto RICHI777 tu idea, la entiendo algo, pero el problema viene (creo yo) en el hex que me genera el ccs (v4.023) que, nose si sera un bug de dicho compilador, pero, a mi parecer, no esta setiando bien la velocidad para el clock (SCL) cuando quiero usar el DS1307 o la 24LC512 (dependiendo de cual de los dos #USE I2C (...) este primero o segundo, como lo he ilustrado, esa configuracion hace que uno funcione bien y el otro "no del todo").

Gracias.
Un saludo.
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: RICHI777 en 11 de Junio de 2008, 15:50:01
Hola Jeremy, lo que te quise decir, es una vez agotadas todas las instancias, de cambiar el RTC por uno más rápido, de manejarlo con otros ports, etc, etc, si no te queda mas vueltas, yo la alimentación del RTC ( VCC ) la manejaria por un PORT del micro, cuando quiero leer a altas velocidades del BUS solo le bajo el Port y en teoria el RTC deberia estar como desconectado, nose es chancho pero capaz que funciona.

Saludos !
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: pocher en 11 de Junio de 2008, 15:53:29
Hola jeremy.

Esta es la 2ª vez que escribo este mensaje, dita sea, la 1ª se ha quedado en el limbo.

Te lo he corregido y ahora sí que funcionan los 2 dispositivos a diferentes velocidades.

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

//#USE I2C (Master, SDA = Pin_B0, SCL = Pin_B1, Slow, Stream = RTC)
//#USE I2C (Master, SDA = Pin_B0, SCL = Pin_B1, Slow, Stream = ExtEEprom)

#USE I2C (Master, Force_HW, Slow, SDA = Pin_B0, SCL = Pin_B1, Stream = RTC)
#include "ds1307_modificado.c"      //Funciones para el uso del Real Time Clock del integrado DS1307.

#USE I2C (Master, Force_HW, Fast = 400000, SDA = Pin_B0, SCL = Pin_B1, Stream = ExtEEprom)
#include "24512_modificado.c"       //Funciones para el uso de la memoria volatil serial eeprom externa 24LC256.


void main(void)
{      
/*
   unsigned int8  DS1307DiaA, DS1307MesA, DS1307AnoA, DS1307DSA, DS1307HoraA, DS1307MinutoA, DS1307SegundoA;
   unsigned int8 Buffer[256];
   unsigned int16 cont, i;
*/  
   int8  DS1307DiaA, DS1307MesA, DS1307AnoA, DS1307DSA, DS1307HoraA, DS1307MinutoA, DS1307SegundoA;
   int8 Buffer[256];
   int16 cont, i;  
  
   //delay_ms(1500);
   //printf("\r\n\n\n-----------jeremy-----------\r\n\n\n");

   #USE I2C (Master, Force_HW, Fast = 400000, SDA = Pin_B0, SCL = Pin_B1, Stream = ExtEEprom)
   init_ext_eeprom();      //Inicializo la EEprom externa.
  
#USE I2C (Master, Force_HW, Slow, SDA = Pin_B0, SCL = Pin_B1, Stream = RTC)
   ds1307_init();          //inicializamos el RTC (DS1307).

   ds1307_set_date_time(11, 6, 8, 3, 13, 32, 0); //día-més-año-día semana-horas-minutos-segundos
  
   cont = 0;
   delay_ms(300);

   while (TRUE)
   {
      delay_ms(50);
      /////////////////////////////
      #USE I2C (Master, Force_HW, Slow, SDA = Pin_B0, SCL = Pin_B1, Stream = RTC)
      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);
                  
#USE I2C (Master, Force_HW, Fast = 400000, SDA = Pin_B0, SCL = Pin_B1, Stream = ExtEEprom)
      printf("     Direcion[%Lu] -> %03u", cont, read_ext_eeprom(cont));
      putc('\r');
      cont++;
      //////////////////////////////////
/*
      printf("\r\n\nEmpezando lectura secuencial de 24LC512...");
//#USE I2C (Master, Force_HW, Fast = 400000, SDA = Pin_B0, SCL = Pin_B1, Stream = ExtEEprom)
      read_ext_eeprom_seq(Buffer, 0, 255);
      //delay_ms(1000);
      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);
         printf("%03u ", Buffer[i]);
      }  
      
   }
}

El fallo principal estaba en la función read_ext_eeprom_seq(Buffer, 0, 255); Con esta función solo sacaba el primer elemento de la memoria.

He usado la otra: read_ext_eeprom(i) y con esta si que funcionan los 2 dispositivos bien.

Si lo pruebas físicamente me gustaria que me dijeras si te ha funcionado.

Un saludo
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jeremylf en 12 de Junio de 2008, 02:00:12
Hola Pocher. Antes que nada, agradesco el tiempo que te has dado por probar esto en proteus y todo  :mrgreen: Gracias.

Ahora, parece que no se me entendio del todo bien en mi 1er mensaje. Y es que esa funcion "read_ext_eeprom_seq" funciona perfectamente cuando esta sola la memoria (aunq nose cmo te habra ido en el proteus). Tambien, es preciso hacer uso de esta ya que necesito la mayor velocidad posible y, esa funcion, o mejor dicho, la funcion de lectura secuencial que tiene el 24LC512, me lo posibilita.

Ahora cuando dices que con esa funcion solo sacaba el 1er dato... Eso es cierto. Y para arreglarlo, basta con poner "su #USE I2C (...)" antes que el del RTC y sacara todos los primeros 256 datos correctamente (tal como se muestra en las imagenes que he colgado en mi 1er mensaje). Pero, asi, al leer el RTC, la lectura sera un tanto erronea por no decir completa.

No puedo asegurarte que todo esto suceda en el proteus pero en "la vida real" xD si que sucede =/

Tu codigo, el que propones, lo he probado, obteniendo los mismo resultados  :(

De todas maneras, nuevamente, gracias por el apoyo.
Un saludo  :P
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: pocher en 17 de Junio de 2008, 05:42:26
Supongo que esto que te voy a poner ya lo habrás probado, pero por si acaso te lo pongo:

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]);
      }   
*/
     
   }
}

Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: jeremylf en 17 de Junio de 2008, 11:13:34
Hola pocher! Eso que sugieres (hacer i2c por software) no lo probe por eso mismo: Por que la idea era lograrlo hacer con el hardware que tiene implementado el pic. Pero, ya que parece no haber solucion, me di por probar y q crees... Como bien pones en tu codigo, estando el RTC o la memoria arriba o abajo (entiendase la instrucion I2C en el software) funciona de maravilla!  :D

Ahora, la pregunta seria: ¿Porq ****** no funciona con el hardware del pic?  :? O si todo eso esta corriendo a puro software creado por el CCS?

Muchas gracias pocher!  :mrgreen:

Salu2.

PD: Se q me comentaron que haga esto de hacerlo por software pero por el mismo motivo que he descrito no lo hice y q aun intento hacerlo correr xP
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: AKENAFAB en 30 de Abril de 2009, 11:28:30
Hola a todos xD

HA pasado tiempo en este tema!

Ahora me ocurre el mimo problemilla-

Parece que se me bloquea el RTC con la MEMORIA!

Estoy probando programas separados y luego los combino.

Mas tarde probare las opciones propuestas xD aunque ya las hallan experimentado saber que pasa ahi,

Mi rtc tambien va a 100KHz, y la mwmoria a 400KHz.

Quiero aprovechar la maxima velocidad de la memoria porque de ahi saco el dato para la simagenes del GLCD.Asi que en Teoria , seria 4 veces mas rapido.

Bueno, un saludo.

YA estaremos ocntando que paso!
Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: AKENAFAB en 01 de Mayo de 2009, 00:03:54
Ya no se bloquea la memoria xD no estoy seguro el porque.

Primero lo tenia por Software , pero eso de nada me sirve si yo uso el bus HARd  ademas quiero aprovechar las ventajas de este y dejar al micro trabajar liviano , y tener un buen rendimiento.


Estoy seguro que se puede , pero hay que meterle mano al asm , y configurar directo cada vez que usemos determinado módulo.

Por ahora tengo esto para el DS1307 y la eeprom 24LC256

Código: [Seleccionar]
#ifndef RTC_SDA
#define RTC_SDA  PIN_C4
#define RTC_SCL  PIN_C3
#endif

#use i2c(i2c1,master,FORCE_HW)

  Extraido de las especificacion para el pic18F252

SSPADD register holds the slave device address
when the SSP is configured in I2C Slave mode. When
the SSP is configured in Master mode, the lower
seven bits of SSPADD act as the baud rate generator
reload value
.


(http://img7.imageshack.us/img7/1107/clocki2c.jpg)

La siguiente tabla xD no la entiendo.

(http://img6.imageshack.us/img6/1299/ablai2cp.jpg)

Voy a probar , aunque de Inicio ya tengo mal el circuito porque tengo resistencias de 10K ohms , y recordando el post de Cryn sobr eel valor y cálculo de ellas creo que hablaban de un maximo de 3.3K ohms. con el ds1307   :cry:

Y para la velocidad de 400Khz de la eeprom 24LC256 debo cambiar las resistencias tambien , estan muy altas. En ambos caso marca 10pf en las lineas como maximo.

Ahora una imagen de lo que me marcan las especificaciones de la memoria.  :( La regué feo al poner esas de 10K ohms . Con eso ya estoy limitando la velocidad.

(http://img8.imageshack.us/img8/4372/eepromresistor.jpg)


ahora para enmendar mi gran error , esta laborioso desoldar las resistencias :*(


(http://img8.imageshack.us/img8/1862/48172705.jpg) (http://img8.imageshack.us/img8/9756/pls2.jpg)
(http://img16.imageshack.us/img16/5958/pl25s.jpg)


Un saludo!

Título: Re: Dos velocidades distintas en un mismo bus i2c por hardware.
Publicado por: AKENAFAB en 01 de Mayo de 2009, 06:35:36

No tengo como revisar la frecuencia , pero segun yo , xD funciona.

Veo que la usar #use i2c(i2c1,master)   <--- Lo pone como Slow osea 100KHz , lo que dice el CSS

#use i2c(i2c1,master,FAST)    <--- Lo pone a 400KHz todo bien.


Pero si usamos 2 dispositivos , esto al hacer el init_eeprom e init_rtc.

Escribe el primer valor , luego al encontrar el segundo init. lo sobrescribe , y si pones la declaracion en otro lado antes de usar , no marca error , pero no lo toma en cuenta.

Asi que revise que registros afecta y lo modifico directamente.


Al usar la libreria del RTC , en cualquier función , Cargo el valor en el registro SSADD = 0x4F.

Asi que siguiendo la formula y teniendo un afreq de operacion de 32 MHz

32MHz/(4*SSADD+1) = 100Khz

y al llamar cualquier función de la eeprom , dentro de ella cargo el valor al registro SSADD=0x13

32MHz/(4*SSADD+1)=400KHz

Y con esto cambianmos de velocidad de acuerdo al dispositivo que usemos.

Lo estoy probando y no he tenido fallos.(por ahora).

En cada libreria defico el registro

Código: [Seleccionar]
#use i2c(I2C1,master,FORCE_HW)

#byte SSPADD  = 0xFC8        // <--- Direccion del Registro

#define EEPROM_ADDRESS long int
#define EEPROM_SIZE   32768

void init_ext_eeprom()
{
      SSPADD=19;              //    Fosc/(4*SSADD+1)  = 32MHz/(4*20)= 400 000 Hz
   output_float(EEPROM_SCL);
   output_float(EEPROM_SDA);

}

Y asi en cada funcion y libreria i2c.


Un saludo!

Y creo que por ahora xD no más problemas con las velocidades xD