TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: vinny en 17 de Diciembre de 2006, 14:59:36

Título: Direccionar varias EEPROM externas usando I2C
Publicado por: vinny en 17 de Diciembre de 2006, 14:59:36
Estoy diseñando con un PIC18F4455 mediante CCS, quiero direccionar varias EEPROM externas tipo 24256, el mismo CCS contiene el driver para esas memoria, pero mi duda es la siguiente:
En los drivers de estos disposotivos da por defecto la siguiente rutina para la lectura:

void write_ext_eeprom(long int address, BYTE data)
{
   short int status;
   i2c_start();
   i2c_write(0xa0);
   i2c_write(address>>8);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
   i2c_start();
   status=i2c_write(0xa0);
   while(status==1)
   {
   i2c_start();
   status=i2c_write(0xa0);
   }
}

Estas memorias tienen externamente unos PINS llamados A0, A1 y A2 para poder poner mas de una en serie y aumentar la capacidad de almacenamiento, por lo que he podido ver  la instrucción    i2c_write(0xa0); significa que A0, A1 y A2 estan todos a GND, pero, si pongo varias, tendré que direccionarlas como i2c_write(0xa1); i2c_write(0xa2);... NO???? si esto es así? que me recomendais, que edite el driver y haga dentro de la rutina un SWITCH con los casos que puedo tener, o bien haga el SWITCH en el programa principal y edite los nombres de las rutinas dependiendo de la EEPROM que quiera escribir?...o  :? bien otra solución si veis que voy totalmente desencaminado

gracias por adelanatado :-)
Título: Re: Direccionar varias EEPROM externas usando I2C
Publicado por: aitopes en 17 de Diciembre de 2006, 15:03:37
¿No es que A0,A1 y A2 son para poder elegir cual de las 8 EEPROM posibles (2 al cubo)? Una ves seleccionada cual es la que quieres acceder, lo haces como si fuera la unica fisicamente conectada al bus...

Yo nunca use mas de una, pero me parece que lo haria de esa manera.... mediante pines del pic (o algun multiplexor) seleccionaria la memoria correcta mediante A0, A1 y A2, y luego....me olvido de las otras!

Puede ser?
Título: Re: Direccionar varias EEPROM externas usando I2C
Publicado por: RedPic en 17 de Diciembre de 2006, 15:47:43
En el foro Proyectos tengo esto que creo que es lo mismo que estas buscando:

Circuito y Driver C para 4 Memorias EEPROM 24AA1025 con un total de 512 Kbytes (http://www.todopic.com.ar/foros/index.php?topic=14328.0)

Un saludo.
Título: Re: Direccionar varias EEPROM externas usando I2C
Publicado por: LABmouse en 17 de Diciembre de 2006, 15:55:52
vinny lo que debes hacer es darle una direccion fija para cada memoria con los pines A0,A1,A2.

Cada una debe tener una direccion diferente.

A2  A1  A0
0    0    0   Memoria 1
0    0    1   Memoria 2
0    1    0   Memoria 3
0    1    1   Memoria 4
1    0    0   Memoria 5
1    0    1   Memoria 6
1    1    0   Memoria 7
1    1    1   Memoria 8

El 1 y 0 los das enviando a vcc o a tierra al que corresponda.
Luego para direccionarla, al mirar como es el protocolo I2C observa que el formato es el siguiente:

(http://img106.imageshack.us/img106/3452/nuevo1yj6.gif)

Observa el paquete slave address en ese lugar debe ir la direccion de la memoria que tu le diste.

 


Título: Re: Direccionar varias EEPROM externas usando I2C
Publicado por: RedPic en 17 de Diciembre de 2006, 16:11:35
Algunos modelos como el 24AA1025 solo tiene dos pines para poder configurar por hardware la dirección en el bus I2C. Disponen del tercer pin Address solo para compatibilidad hardware con otras memorias EEPROM:

(http://picmania.garcia-cuervo.com/images/Quad-EEPROM-I2C-Pin-Functions.GIF)

Título: Re: Direccionar varias EEPROM externas usando I2C
Publicado por: vinny en 17 de Diciembre de 2006, 18:34:46
Gracias RedPic, el proyecto que me has enviado es practicamente lo que tenia pensado, pero bien hecho jajaja, muchas gracias
a seguir programado
Título: Re: Direccionar varias EEPROM externas usando I2C
Publicado por: RedPic en 18 de Diciembre de 2006, 02:20:59
Vinny, me alegra que te sirva. En cuanto a lo de bien hecho, la historia lo dirá. ja ja ja  :D :D :D
Título: Re: Direccionar varias EEPROM externas usando I2C
Publicado por: vinny en 18 de Diciembre de 2006, 14:34:04
Hola , me he estado mirando el código de RedPic y creo qua falta inicializar la eeprom, tal y como sale en los drivers originales para las eeproms externas, no? deberia ser algo así:

ifndef EEPROM_SDA

#define EEPROM_SDA  PIN_B1
#define EEPROM_SCL  PIN_B0

#endif

#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)

#define EEPROM_ADDRESS long int
#define EEPROM_SIZE   32768

/// y dentro del main poner
void init_ext_eeprom()
{
   output_float(EEPROM_SCL);
   output_float(EEPROM_SDA);

}

el resto dejarlo tal cual, vamos, esa me parece a mi, no se
Título: Re: Direccionar varias EEPROM externas usando I2C
Publicado por: RedPic en 18 de Diciembre de 2006, 18:01:20
Pues yo no lo tengo así y me funciona perfectamente (con el 18F4550). Y el código está recreado sobre un original para una sola EEPROM de 256 Kbits y tampoco lo tenía ...  :shock:

Título: Re: Direccionar varias EEPROM externas usando I2C
Publicado por: vinny en 18 de Diciembre de 2006, 18:27:55
 :? pues... no se, todos los drivers que hay en lacarpeta drivers del CCs lo llevan escrito así. Pero no digo que no funcione
Título: Re: Direccionar varias EEPROM externas usando I2C
Publicado por: RedPic en 18 de Diciembre de 2006, 18:44:49
No hay drama, si los que saben lo tienen puesto será por algo ...  :mrgreen:

Con output_float(pin) se conmuta el pin a modo entrada y se deja flotante para poder leer un HIGH en un pin open-collector ... no sé realmente qué función tiene colocar los pines en este modo antes de empezar a trabajar con el I2C, será cuestión de investigar.

Pero ya te digo, amigo vinny, que no lo utilizo y me lanzo directamente a leer o escribir y me función perfectamente, no simulando sino en el hard.  :mrgreen:

Título: Re: Direccionar varias EEPROM externas usando I2C
Publicado por: vinny en 18 de Diciembre de 2006, 18:46:13
Bueno, aquí voy a colgar el codigo que me ha salido, es un poco mas escueto que el de RedPic porque he pasado de hacer tantas subrutinas y he puesto ya las variables a valores que no tuviese que tocar. Mañana lo probaré a ver que tal va.

código:


#ifndef EEPROM_SDA

#define EEPROM_SDA  PIN_B1
#define EEPROM_SCL  PIN_B0

#endif

#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)

#define EEPROM_ADDRESS long int
#define EEPROM_SIZE   32768


// device hardware address

int8 const deviceAddress1 = 0xa2; // #1
int8 const deviceAddress2 = 0xa4; // #2
int8 const deviceAddress4 = 0xa6; // #4 segons hardware les tinc intercambiades
int8 const deviceAddress3 = 0xa8; // #3

// baseAddress = 8 bits which mean ...
//
// Fixed (4 bits)            -> 1010
// Dev Hard Address (3 bits) -> 000,001,010,011,100,101,110,111
// R/W (1 bit)               -> 0 -> Write / 1 -> Read



////////////////////////////////////////////////////////////////////////////////
/*    funcions per l'adreçament del chip de memòria corresponent              */
////////////////////////////////////////////////////////////////////////////////

int8 BuscarAdrecaAdequada(int32 Address){

   int8  DevAddress=0;

   if(Address<0x8000)
      DevAdress=deviceAddress1;
   if((Address=>0x8000)&&(Address<0x16000))
      DevAdress=deviceAddress2;
   if((Address=>0x16000)&&(Address<0x240000))
      DevAdress=deviceAddress3;
   if((Address=>0x24000)&&(Address<0x320000))
      DevAdress=deviceAddress4;
  
  
   return DevAddress;
}
////////////////////////////////////////////////////////////////////////////////
/*                      PROGRAMA PRINCIPAL                                    */
////////////////////////////////////////////////////////////////////////////////
void init_ext_eeprom()
{
   output_float(EEPROM_SCL);
   output_float(EEPROM_SDA);

}


void write_ext_eeprom(long int address, BYTE data)
{
   short int status;
   int8 BaseAddress;
  
   BaseAdress = BuscarAdrecaAdequada(int32 Address);
  
   i2c_start();
   i2c_write(BaseAdress);
   i2c_write(address>>8);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
   i2c_start();
   status=i2c_write(0xa0);
   while(status==1)
   {
   i2c_start();
   status=i2c_write(0xa0);
   }
}


BYTE read_ext_eeprom(long int address) {

   BYTE data;
   BaseAdress = BuscarAdrecaAdequada(int32 Address);

   i2c_start();
   i2c_write(BaseAddress);
   i2c_write(address>>8);
   i2c_write(address);
   i2c_start();
   i2c_write(BaseAddress|1);
   data=i2c_read(0);
   i2c_stop();
   return(data);
}