TODOPIC
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.
¿Perdiste tu email de activación?
03 de Septiembre de 2010, 05:29:02

Ingresar con nombre de usuario, contraseña y duración de la sesión
Buscar:     Búsqueda Avanzada
257111 Mensajes en 28437 Temas por 27916 Usuarios
Último usuario: zororyuzaki
* Inicio Ayuda Buscar Calendario Ingresar Registrarse
Buscar en TodoPIC
+  TODOPIC
|-+  Microcontroladores PIC
| |-+  * PROYECTOS * (Moderadores: J1M, jfh900, MGLSOFT, Modulay, Sasián, LABmouse)
| | |-+  Circuito y Driver C para 4 Memorias EEPROM 24AA1025 con un total de 512 Kbytes
0 Usuarios y 1 Visitante están viendo este tema. « anterior próximo »
Páginas: [1] 2 Marcar como favorito Imprimir
Autor Tema: Circuito y Driver C para 4 Memorias EEPROM 24AA1025 con un total de 512 Kbytes  (Leído 2987 veces)
RedPic
Administrador
DsPIC33
*******
Desconectado Desconectado

Sexo: Masculino
Tibet Tibet

Mensajes: 4876



WWW
« : 15 de Octubre de 2006, 12:55:42 »

 Mr. Green Circuito y Driver CCS C para 4 Memorias EEPROM I2C 1024 Kbits x 4 : 8 = 512 Kbytes con 4 chips 24AA1025 de Microchip
 
  
Descripción del Proyecto:
  
La finalidad de este proyecto es la de dotar de una cantidad suficiente de memoria no volátil a nuestra RRBOARD2. De los varios tipos de memorias no volátiles que podríamos utilizar vamos en este caso a usar una Array de EEPROMS serie externas, todas ellas accesibles mediante un único bus I2C.
 
La idea central es la de desarrollar una Driver en CCS C mediante el que podamos acceder a la totalidad de la memoria disponible "en línea". Desde el primer byte del primer chip hasta el último byte del último chip como si fuese un chip único que englobase la suma de todas las posiciones de memoria direccionables de forma continua.
 
Para este proyecto en concreto vamos a utilizar la EEPROM externa 24AA1025, desarrollada por la gente de Microchip y que han tenido la gentileza de enviarme tres unidades para realizar estos experimentos.
 
Por limitaciones de Hardware inherentes al diseño de las 24AA1025 solo podemos "apilar" un máximo de cuatro unidades de este tipo, por lo que nuestro proyecto va a ceñirse a esta limitación y vamos a diseñar todo en función de este número de elementos.
 
Así la conclusión del proyecto está en leer y/o escribir un byte, mediante las dos funciones correspondientes, en las posiciones de memoria desde 0x00000 hasta 0x7FFFF, ambas inclusive. Un total de 0x80000 posiciones diferentes, o lo que es lo mismo 524.288 posiciones direccionables directamente, lo que significan 524.288 / 1024 = 512 Kbytes.
 
  
Implementación y consideraciones Hardware:
  
Como hemos mas arriba vamos a utilizar para nuestro pequeño proyecto cuatro chips del modelo 24AA1025. Cada uno de ellos dispone de un total de 1024 Kbits lo que significan 1024/8 = 128 Kbytes de memoria, distribuidos en dos bancos de 64 Kbytes cada uno de ellos.
 
Estos chips son accesibles mediante un bus I2C, dos líneas son necesarias para ello: SDA y  SCL con sus correspondientes resistencias Pull-Up a Vcc, que corresponden a los Pines 5 y 6 del chip. Las resistencias Pull-Ups que vamos a utilizar son de 10 KOhmios cada una de ellas.
 
Para direccionar cada uno de los cuatro chips debemos usar las distintas configuraciones hardware que podemos implementar usando los terminales A0 y A1 de cada uno de los chips, Pines 1 y 2 respectivamente, nótese que A2, correspondiente al Pin 3 del chip, no es posible usarlo para este fin ya que ha de ser siempre conectado a Vcc. Estas direcciones hardware posibles combinando A0 y A1 conectándolos a VCC (1) y GND (0) según cada caso son: 00, 01, 10 y 11 y de ahí la limitación a cuatro chips de que hablábamos antes.
 
Podríamos usar el terminal WP, Pin 7 del Chip, para proteger contra escritura nuestra memoria EEPROM ya que éste deshabilita la posibilidad de modificar el contenido de la EEPROM si es conectado a Vcc, pero en este caso no vamos a hacerlo y vamos a conectarlo permanentemente a GND para habilitar siempre la posibilidad de modificación de su contenido.
 
Los Pines 4 y 8 del chip corresponden con la alimentación del mismo y han de ir conectados correspondientemente a GND y VCC.
 
Las distintas funciones de cada uno de los pines puede verse en la siguiente tabla extraída del Datasheet del 24AA1025:


 
La distribución física de los pines en el Chip es la siguiente:


  
Esquema:
  
Y este es el esquema definitivo que vamos a construir, en el que podemos destacar algunos detalles:
 
.- La comunicación con la RRBOARD2 la realizamos mediante nuestro viejo amigo el conector CON-ML10 para cable plano de 10 hilos (alimentación y un puerto completo de 8 bits)
 
.- JP1-PB y JP2-PC permiten seleccionar la conexión de los SDA y SCL del I2C a los pines 0..1 ó 3..4 del puerto al que estén conectados (recordad de la RRBOARD2 está diseñada para las familias 18F4550 y 16F877 y el I2C lo implementa la primera en los pines RB0 y RB1 y la segunda en los RC3 y RC4)  
 
.- Dependiendo de dónde conectemos nuestro circuito en la RRBOARD2 podemos necesitar o no las resistencias Pull-Up imprescindibles para el bus I2C. Si lo conectamos al PORTB tenemos disponibles la internas del PIC, en cualquier otro caso podemos hacer uso del jumper JP3-PU para conectar dichas resistencias Pull-Up a VCC.
 
.- Por oscuras razones de diseño que ni yo mismo soy capaz de explicarme del todo, a pesar de haber realizado personalmente el mismo, he optado por asignar las direcciones Hardware de cada uno de los chips en orden inverso al natural: Al chip número uno la dirección 11, al dos la 10, al tres la 01 y al cuatro la 00. La verdad es que es irrelevante a la hora de utilizarlos ya que muy fácilmente podremos cambiar la configuración del driver para usar cualquier combinación de direcciones que deseemos utilizar. (Este extremo se verá en detalle en la sección dedicada al driver)
  


 Circuito impreso:
  
El esquema anterior debidamente ruteado a un tamaño de QUARTER_EUROBOARD genera el siguiente PCB:



Recursos:
  
Datasheet del chip 24AA1025 (PDF 357 Kb)
  
Driver y Software:
  

 
Créditos: Todo lo aquí desarrollado se basa en dos trabajos que no he realizado yo mismo:
 
El programa de ejemplo EX_EXTEE.C de la gente de CCS C y
El Driver Microchip 24AA512 512k I2C EEPROM de UFAnders
 
Pero dejémonos de mas dilaciones innecesarias y entremos en faena con nuestro Driver I2C para memorias EEPROM de gran tamaño:


  
Según la tabla anterior en que se nos muestra el método I2C de asignar una dirección de memoria a las 24AA1025 para leer o escribir sobre ella, y siguiendo el modo y manera en que CCS C hace uso del bus I2C debemos implementar dos simples funciones que esquemáticamente van a ser como sigue:
 
.- Escribir un byte (data) en una dirección de memoria (memAddress):
Es este caso inicializamos el bus I2C con start(), enviamos con write() el Control Byte, que nosotros llamamos baseAddress, y a continuación los dos bytes de dirección de memoria a escribir, memAddress, empezando con el más significativo y después del menos significativo, seguido del byte, data, que deseamos guardar.
 
Código
GeSHi (c):
  1. void writeByte24AA1025(int32 memAddress, int8 data){
  2.  i2c_start();
  3.  i2c_write(baseAddress);
  4.  i2c_write(memAddress>>8);
  5.  i2c_write(memAddress);
  6.  i2c_write(data);
  7.  i2c_stop();
  8. }
  9.  
 
.- Leer un byte de una dirección de memoria (memAddress):
 
Para leer en una posición de memoria debemos realizar el mismo posicionamiento en una dirección de memoria tal como hicimos en la función de escritura seguido de una nueva función start() y una función write() con el bit Read del Control Byte activado. A continuación realizamos un read() del bus I2C y recibiremos el contenido de dicha dirección de memoria.
 
Código
GeSHi (c):
  1. int8 readByte24AA1025(int32 memAddress){
  2.  
  3.  int8 returnByte=0;
  4.  
  5.  i2c_start();
  6.  i2c_write(baseAddress);
  7.  i2c_write(memAddress>>8);
  8.  i2c_write(memAddress);
  9.  i2c_start();
  10.  i2c_write(baseAddress|1);
  11.  returnByte = i2c_read(0);
  12.  i2c_stop();
  13.  return returnByte;
  14. }
  15.  

Todo esto está muy bien en principio pero hay una serie de importantes detalles que no hemos tomado en cuenta aún y que son imprescindibles si deseamos llevar a buen puerto nuestro proyecto:
 

 
En primer lugar está el asunto que cómo configurar apropiadamente el Control Byte. Es un único Byte y en él debemos incluir:
 
El Control Code. Que siempre son los mismo Bits, 7..4, y que para estos chips es 1010.
 
El Block Select Bit. Que indica en que Banco de los dos de 65535 bytes que tiene cada chip es al que nos estamos refiriendo.
 
El Chip Select Bits. Que es la dirección por Hardware que le asignamos a cada uno de los cuatro chips con los que estamos trabajando.
 
El Read/Write bit. Donde indicamos si estamos leyendo o escribiendo una posición de memoria.
 
En segundo lugar debemos hacer una conversión de la dirección de memoria donde queremos escribir desde la absoluta que enviamos a nuestras funciones, entre 0x00000 y 0x7FFFF, a la relativa de Chip/Banco/0x0000 a 0x1FFFF que es la máxima dirección accesible dentro de un Banco dentro de un Chip en concreto.
 
O sea que en función de la dirección absoluta que enviemos a nuestras funciones debemos componer el Control Byte seleccionando el Chip al que nos referimos, el Banco dentro de ese chip y la dirección concreta por la que estamos preguntando.
 
Partimos de una Control Byte base de: int8 const baseAddress24AA1025 = 0b10100000;
 
Y le configuramos los distintos bits. Esto lo solventamos con las siguientes funciones auxiliares:
 
int8 memAbsoluteAddress2deviceOrder(int32 memAddress);
 
Que nos devuelve 1, 2, 3 ó 4 dependiendo de si memAddress es mayor 0x00000 y menor que 0x1FFFF, ó es mayor que 0x20000 y menor que 0x3FFFF ... etc. etc.

int8 memAbsoluteAddress2deviceAddress(int32 memAddress);
 
Que nos devuelve la dirección Hardware del Chip 1, 2, 3 ó 4 al que corresponde la dirección absoluta memAddress. Esta dirección hardware es la parte Chip Select Bits del Control Byte.
 
Estas deciveAddress las extraemos en función del anterior deviceOrder haciendo uso de la siguiente tabla de asignación de direcciones Hardware:
 
Código
GeSHi (c):
  1. // device hardware address
  2. int8 const deviceAddress1 = 0b00000011; // #3
  3. int8 const deviceAddress2 = 0b00000010; // #2
  4. int8 const deviceAddress3 = 0b00000001; // #1
  5. int8 const deviceAddress4 = 0b00000000; // #0
  6.  

int32 memAbsoluteAddress2menRelativeAddress(int8 deviceOrder,int32 memAddress);

Que nos va a ajustar memAddress a la dirección relativa dentro de cada uno de los Chip, haciendo que cada una de ellas comienze realmente en 0x00000.

int1 menRelative2BankSelect(int32 memRelativeAddress);

Y ésta que por último nos selecciona el Banco, alto o bajo, de cada uno de los Chips. Corresponde al Block Select Bit del Control Byte.
 
Con todo esto podemos ya completar nuestras funciones principales, añadiéndoles las cabeceras correspondientes para ajustar todos y cada uno de los parámetros:
 
Código
GeSHi (c):
  1.  int8 baseAddress;
  2.  int8 deviceAddress;
  3.  int8 deviceOrder=0;
  4.  int32 memRelativeAddress;
  5.  int8 bank=0;
  6.  
  7.  deviceAddress = memAbsoluteAddress2deviceAddress(memAddress);
  8.  deviceOrder = memAbsoluteAddress2deviceOrder(memAddress);
  9.  memRelativeAddress = memAbsoluteAddress2menRelativeAddress(deviceOrder, memAddress);
  10.  bank = menRelative2BankSelect(memRelativeAddress);
  11.  baseAddress = baseAddress24AA1025 + (bank<<3) + (deviceAddress<<1);
  12.  

El driver definitivo queda así:
 
Código
GeSHi (c):
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // 4 x EEPROM 24AA1025 Driver with absolute memory addressing
  4. //
  5. ///////////////////////////////////////////////////////////////////////////////
  6.  
  7. #define EEDEBUG
  8.  
  9. // device hardware address
  10.  
  11. int8 const deviceAddress1 = 0b00000011; // #3
  12. int8 const deviceAddress2 = 0b00000010; // #2
  13. int8 const deviceAddress3 = 0b00000001; // #1
  14. int8 const deviceAddress4 = 0b00000000; // #0
  15.  
  16. // baseAddress = 8 bits which mean ...
  17. //
  18. // Fixed (4 bits)            -> 1010
  19. // EE internal Block (1 bit) -> 0 for 0000/FFFF, 1 for 10000/1FFFF
  20. // Dev Hard Address (2 bits) -> 00 or 01 or 10 or 11
  21. // R/W (1 bit)               -> 0 -> Write / 1 -> Read
  22.  
  23. int8 const baseAddress24AA1025 = 0b10100000;
  24.  
  25. // Aux Functions //////////////////////////////////////////////////////////////
  26.  
  27. int1  menRelative2BankSelect(int32 memRelativeAddress){
  28.  
  29.   int1 returnBit=0;
  30.  
  31.   if(memRelativeAddress>(int32) 0xffff) returnBit = 1;
  32.  
  33.   return returnBit;
  34. }
  35.  
  36. int32 memAbsoluteAddress2menRelativeAddress(int8 deviceOrder, int32 memAddress){
  37.  
  38.   int32 returnInt32 = 0;
  39.  
  40.   switch(deviceOrder){
  41.      case 1: returnInt32 = memAddress;
  42.              break;
  43.      case 2: returnInt32 = memAddress - 0x20000;
  44.              break;
  45.      case 3: returnInt32 = memAddress - 0x40000;
  46.              break;
  47.      case 4: returnInt32 = memAddress - 0x60000;
  48.              break;
  49.   }
  50.   return returnInt32;
  51. }
  52.  
  53. int8 memAbsoluteAddress2deviceOrder(int32 memAddress){
  54.  
  55.   int8  returnByte=0;
  56.  
  57.   if((memAddress>0x05ffff)&&(memAddress<0x080000)) returnByte=4;
  58.   if((memAddress>0x03ffff)&&(memAddress<0x060000)) returnByte=3;
  59.   if((memAddress>0x01ffff)&&(memAddress<0x040000)) returnByte=2;
  60.   if(                       (memAddress<0x020000)) returnByte=1;
  61.  
  62.   return returnByte;
  63. }
  64.  
  65. int8 memAbsoluteAddress2deviceAddress(int32 memAddress){
  66.  
  67.   int8  deviceOrder=0, returnByte=0;
  68.  
  69.   deviceOrder = memAbsoluteAddress2deviceOrder(memAddress);
  70.  
  71.   switch(deviceOrder){
  72.      case 0: returnByte = 0xff;
  73.              break;
  74.      case 1: returnByte = deviceAddress1;
  75.              break;
  76.      case 2: returnByte = deviceAddress2;
  77.              break;
  78.      case 3: returnByte = deviceAddress3;
  79.              break;
  80.      case 4: returnByte = deviceAddress4;
  81.              break;
  82.   }
  83.   return returnByte;
  84. }
  85.  
  86. // Main Functions /////////////////////////////////////////////////////////////
  87.  
  88. void writeByte24AA1025(int32 memAddress, int8 data){
  89.  
  90.   int8  baseAddress;
  91.   int8  deviceAddress;
  92.   int8  deviceOrder=0;
  93.   int32 memRelativeAddress;
  94.   int8  bank=0;
  95.  
  96.   deviceAddress      = memAbsoluteAddress2deviceAddress(memAddress);
  97.   deviceOrder        = memAbsoluteAddress2deviceOrder(memAddress);
  98.   memRelativeAddress = memAbsoluteAddress2menRelativeAddress(deviceOrder, memAddress);
  99.   bank               = menRelative2BankSelect(memRelativeAddress);
  100.   baseAddress        = baseAddress24AA1025 + (bank<<3)  + (deviceAddress<<1);
  101.  
  102. #ifdef EEDEBUG
  103.   printf("\r\n\nAbsolute Address: %LX Relative Address: %Lx Device: %u Bank: %u\r\n",memAddress,memRelativeAddress,deviceOrder,bank);
  104. #endif
  105.  
  106.   i2c_start();
  107.   i2c_write(baseAddress);
  108.   i2c_write(memAddress>>8);
  109.   i2c_write(memAddress);
  110.   i2c_write(data);
  111.   i2c_stop();
  112.   delay_ms(5);
  113. }
  114.  
  115. int8 readByte24AA1025(int32 memAddress){
  116.  
  117.   int8  returnByte=0;
  118.   int8  baseAddress;
  119.   int8  deviceAddress;
  120.   int8  deviceOrder=0;
  121.   int32 memRelativeAddress;
  122.   int8  bank=0;
  123.  
  124.   deviceAddress      = memAbsoluteAddress2deviceAddress(memAddress);
  125.   deviceOrder        = memAbsoluteAddress2deviceOrder(memAddress);
  126.   memRelativeAddress = memAbsoluteAddress2menRelativeAddress(deviceOrder, memAddress);
  127.   bank               = menRelative2BankSelect(memRelativeAddress);
  128.   baseAddress        = baseAddress24AA1025 + (bank<<3)  + (deviceAddress<<1);
  129.  
  130. #ifdef EEDEBUG
  131.   printf("\r\n\nAbsolute Address: %LX Relative Address: %Lx Device: %u Bank: %u\r\n",memAddress,memRelativeAddress,deviceOrder,bank);
  132. #endif
  133.  
  134.   i2c_start();
  135.   i2c_write(baseAddress);
  136.   i2c_write(memRelativeAddress>>8);
  137.   i2c_write(memRelativeAddress);
  138.   i2c_start();
  139.   i2c_write(baseAddress|1);
  140.   returnByte = i2c_read(0);
  141.   i2c_stop();
  142.   return returnByte;
  143. }
  144. ///////////////////////////////////////////////////////////////////////////////
  145.  

Como os dije mas arriba el siguiente programa es una adaptación del programa de ejemplo EX_EXTEE.C de la gente de CCS C que podéis encontrar en el directorio examples de la instalación de dicho compilador.
  
Código
GeSHi (c):
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // EEPROM_24AA1025x1.C
  4. //
  5. // by RedPic from http://picmania.garcia-cuervo.net
  6. //
  7. // October 2006
  8. //
  9. ///////////////////////////////////////////////////////////////////////////////
  10.  
  11. #include <18F4550.h>
  12. #fuses HS,NOWDT,NOPROTECT,NOLVP
  13. #use delay(clock=20000000)
  14. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  15. #use i2c(master, sda=PIN_B0, scl=PIN_B1)
  16.  
  17. #include <input.c>
  18. #include <24AA1025x4.c>
  19.  
  20. const char Version[]="1.0.F\0";
  21.  
  22. ///////////////////////////////////////////////////////////////////////////////
  23. //
  24. // Main
  25. //
  26. ///////////////////////////////////////////////////////////////////////////////
  27.  
  28. void main() {
  29.  
  30.   BYTE value, cmd;
  31.   int32 address;
  32.   int8  device;
  33.  
  34.   delay_ms(300);
  35.   printf("\r\n\n");
  36.   printf("[RRBOARD2] EEPROM Total Commander %s\r\n",version);
  37.   printf("based on 24AA1025 Microchip Hardware\r\n");
  38.   printf("\xa9 10.2006 by RedPic\r\n\n");
  39.  
  40.   do {
  41.  
  42.      do {
  43.         printf("\r\nDo you Read or Write? : ");
  44.         cmd=getc();
  45.         cmd=toupper(cmd);
  46.         putc(cmd);
  47.      } while ( (cmd!='R') && (cmd!='W') );
  48.  
  49.      printf("\n\rGive me EEPROM internal absolute Address (24 bits) in hex : ");
  50.  
  51.      address = gethex();
  52.      address = (address<<8)+gethex();
  53.      address = (address<<8)+gethex();
  54.  
  55.      device  = memAbsoluteAddress2deviceAddress(address);
  56.  
  57.      if(cmd=='R')
  58.         printf("\r\nReturn Value (8 bits) in hex is : %X\r\n",readByte24AA1025(address));
  59.  
  60.      if(cmd=='W') {
  61.         printf("\r\nEnter new value (8 bits) in hex : ");
  62.         value = gethex();
  63.         printf("\n\r");
  64.         writeByte24AA1025(address, value );
  65.      }
  66.   } while (TRUE);
  67. }
  68.  

Funcionando:
  
Para realizar las primeras pruebas he realizado físicamente el siguiente esquema y PCB que implementa uno de estos chips 24AA1025:
 
 

 


  

 
Ea, ahí queda eso. Mañana más.   Mr. Green rebotando Mr. Green

Nota: El driver en CCS C definitivo está a partir de este post (Enero 2008)
« Última modificación: 26 de Junio de 2009, 06:15:10 por RedPic » En línea

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania
samshiel_pic
Colaborador
PIC18
*****
Desconectado Desconectado

Sexo: Masculino
España España

Mensajes: 431



« Respuesta #1 : 15 de Octubre de 2006, 03:21:25 »

Increible Diego  Shocked cada vez me sorprendes más, esta novela me viene como anillo al dedo  lol.

Yo estoy intentando implementar una serie de memorias para guardar la hora y la fecha en la que sucenden una serie de eventos. En principio seria que cada vez que pulse un boton o pulsador me guarde la la hora y la fecha en la que lo he pulsado y posteriormente poder ver en un lcd o en el hyperterminal todo lo guardado. Para ello utilizaria gran parte de tu otra novela DS1307 desatado jejeje. Una vez que esto este funcionando lo acoplaria a otro proyecto que tengo entre manos para monitorizar cuando y a que hora salta el dispositivo.
Pero todavia toy un poco pez. Tendre que estudiarlo muy detenidamente Razz
En línea

Ni duermo ni como en el foro, ni machaco teclados, ni soy un ser supremo, ni etc, etc...  (lol jejeje lol)pero aqui estoy para lo que pueda ayudar.  

ESPAÑA - ANDALUCIA - SEVILLA

Saludos CANDI.
samshiel_pic@todopic.zzn.com
RedPic
Administrador
DsPIC33
*******
Desconectado Desconectado

Sexo: Masculino
Tibet Tibet

Mensajes: 4876



WWW
« Respuesta #2 : 15 de Octubre de 2006, 03:34:38 »

Si amigo Samshiel_pic, para una cosa parecida lo necesito yo. Mr. Green

En línea

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania
samshiel_pic
Colaborador
PIC18
*****
Desconectado Desconectado

Sexo: Masculino
España España

Mensajes: 431



« Respuesta #3 : 15 de Octubre de 2006, 03:50:20 »

Espero noticias sobre ello amigo Razz
En línea

Ni duermo ni como en el foro, ni machaco teclados, ni soy un ser supremo, ni etc, etc...  (lol jejeje lol)pero aqui estoy para lo que pueda ayudar.  

ESPAÑA - ANDALUCIA - SEVILLA

Saludos CANDI.
samshiel_pic@todopic.zzn.com
vinny
PIC10
*
Desconectado Desconectado

Sexo: Masculino
Mensajes: 27


« Respuesta #4 : 18 de Diciembre de 2006, 02:01:27 »

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
En línea

Solo existen dos cosas infinitas, el universo y la estupidez humana, de lo primero no estoy seguro...
vinny
PIC10
*
Desconectado Desconectado

Sexo: Masculino
Mensajes: 27


« Respuesta #5 : 18 de Diciembre de 2006, 02:56:19 »

 Ola, creo que he encontrado un fallo en el código:

donde dice:
// device hardware address

int8 const deviceAddress1 = 0b00000011; // #3
int8 const deviceAddress2 = 0b00000010; // #2
int8 const deviceAddress3 = 0b00000001; // #1
int8 const deviceAddress4 = 0b00000000; // #0

// 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

el ultimo bit de las constantes deviceAddress debe ser 0, el ultimo bit es el bit R/W no es ninguna direccion, se te han recorrido los bits al escribir, deberia quedar así:
// device hardware address

int8 const deviceAddress1 = 0b00000110; // #3
int8 const deviceAddress2 = 0b00000100; // #2
int8 const deviceAddress3 = 0b00000010; // #1
int8 const deviceAddress4 = 0b00000000; // #0



En línea

Solo existen dos cosas infinitas, el universo y la estupidez humana, de lo primero no estoy seguro...
RedPic
Administrador
DsPIC33
*******
Desconectado Desconectado

Sexo: Masculino
Tibet Tibet

Mensajes: 4876



WWW
« Respuesta #6 : 18 de Diciembre de 2006, 07:07:10 »

No amigo vinny, no es un error, está expresando exactamente lo que dice que es: el DeviceAddress.

Las direcciones de los distintos chips solamente pueden ponerse con dos bits, en esta clase de memorias EEPROM, o sea que solo pueden ser 00, 01, 10 y 11.

Escritos como bytes deben ser completados con ceros por la izquierda. Tal como lo tengo en las constantes. Son las direcciones hard de cada uno de los chips, no el baseAddress.

El baseAddress es la palabra de selección de Descritor de Dispositivo + Block Select + Hard DeviceAddress + Function R/W para las funciones i2C y esta se compone cuando hago el

baseAddress  = baseAddress24AA1025 + (bank<love)  + (deviceAddress<<1);

fíjate que deviceAddress lo desplazo un bit a la izquierda para dejarle sitio al último bit que es el de R/W.






En línea

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

Sexo: Masculino
Mensajes: 27


« Respuesta #7 : 20 de Diciembre de 2006, 07:56:42 »

Tienes razón, no me habia dado cuenta de ese detalle Smile

Creo que podrias ahorrar mucho código si donde pones las deviceAddress escribieses las 8 posibles baseaddress que tienes y luego cuando vayas a escribir por I2C, haces un switch y le dices la baseaddress directamente. habria q hacer los if's de escoger la memoria y el banco por tamaño, y ya está.
En línea

Solo existen dos cosas infinitas, el universo y la estupidez humana, de lo primero no estoy seguro...
RedPic
Administrador
DsPIC33
*******
Desconectado Desconectado

Sexo: Masculino
Tibet Tibet

Mensajes: 4876



WWW
« Respuesta #8 : 20 de Diciembre de 2006, 11:23:07 »

Decía un militar USA que para montar un buen follón hace falta un buen ordenador ...  lol lol lol lol

Si para encender un Led escribo un output_high(Pin) entonces no tiene gracia ...
Tengo que hacer un #define del puerto, asignarle un nombre extraño, hacerle read del puerto completo y un AND lógico con el byte cuyo bit que corresponda al pin que deseo activar esté en alto y escribir con él directamente en el Latch de salida ...  lol lol lol lol

Perdon, pero es que me ofusco .... y yo solo me lio conmigo mismo y mis funciones de funciones de funciones (While true)  lol lol lol lol

« Última modificación: 21 de Diciembre de 2006, 02:10:51 por RedPic » En línea

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

Sexo: Masculino
Mensajes: 27


« Respuesta #9 : 20 de Diciembre de 2006, 08:55:39 »

 Sad perdon, cada uno lo hace como cree conveniente o como se lia menos...pero...es q yo soy catalán, y ahorro hasta en el código lol lol lol lol lol lol
En línea

Solo existen dos cosas infinitas, el universo y la estupidez humana, de lo primero no estoy seguro...
RedPic
Administrador
DsPIC33
*******
Desconectado Desconectado

Sexo: Masculino
Tibet Tibet

Mensajes: 4876



WWW
« Respuesta #10 : 21 de Diciembre de 2006, 02:10:03 »

muy buena, muy buena ja ja ja  lol lol lol lol lol lol lol lol lol lol lol
En línea

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania
Nocturno
Administrador
DsPIC33
*******
Desconectado Desconectado

Sexo: Masculino
España España

Mensajes: 12825



WWW
« Respuesta #11 : 21 de Diciembre de 2006, 03:26:04 »

Jeje, pues no eres el único catalán que conozco que es un maniático ahorrando código...  Mr. Green
En línea

Un saludo desde Sevilla, España.
Visita MicroPIC                                                                                        ɔ!doɹɔ!ɯ ɐʇ!s!ʌ
pikman
Moderadores
PIC24F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 656


Systemas MicroInformaticos


« Respuesta #12 : 03 de Enero de 2007, 10:52:05 »

Estimado Red ante todo gracias por compartir todo lo que conoces y haces, es un ejemplo de vida, estoy modificando el codigo para usar 8 24lc512 porque necesito 512K, pero no consigo aqui las 241025, de hecho no es muy complicado, pero en esta funcion creo que hay un error o tu me  diras si estoy equivocado.

int8 memAbsoluteAddress2deviceOrder(int32 memAddress){

   int8  returnByte=0;

   if((memAddress>0x05ffff)&&(memAddress<0x080000)) returnByte=4;
   if((memAddress>0x03ffff)&&(memAddress<0x060000)) returnByte=3;
   if((memAddress>0x01ffff)&&(memAddress<0x040000)) returnByte=2;
   if(                       (memAddress<0x020000)) returnByte=1;

   return returnByte;
}

Si la direccion absoluta es 0x3ffff o 0x60000, 0x01ffff o 0x040000 , o 0x020000, la funcion retorna 0, no deberia ser:

int8 memAbsoluteAddress2deviceOrder(int32 memAddress){

   int8  returnByte=0;

   if((memAddress>=0x05ffff)&&(memAddress<=0x080000)) returnByte=4;
   if((memAddress>=0x03ffff)&&(memAddress<=0x060000)) returnByte=3;
   if((memAddress>=0x01ffff)&&(memAddress<=0x040000)) returnByte=2;
   if(                       (memAddress<=0x020000)) returnByte=1;

   return returnByte;
}

Pues de la otra manera las direcciones que delimitan cada byte de retorno ( que no son muchas 7 bytes ) no son accesibles.
Para simplificar si apunto a la direccion 0x01ffff retorna el byte 1 pero si apunto la direccion 0x020000 retorna el byte en 0, pues 0x20000 no es menor ni mayor, por eso aguegue el operador de igualdad, entonces si memAddress es menor o igual a 0x20000 retorna 1.

ademas esta linea

   if((memAddress>=0x01ffff)&&(memAddress<=0x040000)) returnByte=2;

no deberia ser

   if((memAddress>=0x02ffff)&&(memAddress<=0x040000)) returnByte=2;


O no se donde estoy equivocado, desde ya gracias por responder.

« Última modificación: 03 de Enero de 2007, 11:00:14 por pikman » En línea

saludos
PikMan
LordLafebre
Giovanni Lafebre
Moderador Global
DsPIC30
*****
Desconectado Desconectado

Sexo: Masculino
Ecuador Ecuador

Mensajes: 3524


Micros y micros


WWW
« Respuesta #13 : 03 de Enero de 2007, 12:10:26 »

Hola:

Pues solamente felicitar a Diego por sus grandes aportes, sobretodo por la explicacion.

PD: Para cuando sacas el libro? ya solo debes recopilar tus temas posteados  Mr. Green
En línea

   -  

Nuevo local de venta de dispositivos electrónicos, soporte profesional y estudiantil, visítanos en Juan Jaramillo 1-150 y Manuel Vega. Telf: 4036038 - Cel 084278683 (Cuenca - Ecuador)

http://www.freewebs.com/glafebre
http://micros.mforos.com/
Sispic
Moderadores
PIC24H
*****
Desconectado Desconectado

Sexo: Masculino
España España

Mensajes: 1263



WWW
« Respuesta #14 : 03 de Enero de 2007, 01:59:38 »

Esto ahorraria un monton de codigo catalanes .
Hecha la ley ..hecha la trampa .

Ejemplo .

Código:
typedef struct  {
     int1 b0:1; int1 b1:1; int1 b2:1;  int1 b3:1;  int1 b4:1;  int1 b5:1;  int1 b6:1;  int1 b7:1;
} Los_bits_de_un_Byte;


typedef struct {
        int8 byte0;
        int8 byte1;
        int8 byte2;

} My_Address;

/**************************************************************/

void writeByte24AA1025(My_Address memAddress, int8 data){

   Los_bits_de_un_Byte temp , ControlByte;
   
   temp = memAddress.byte2 ;
     
   ControlByte = 0b10100000; // 0xA0 - bit0 Write = 0

   ControlByte.b3 = temp.b0 ; // Block Select Bit
   ControlByte.b1 = temp.b1;  // Chip Select Bit0
   ControlByte.b2 = temp.b2 ; // Chip Select Bit1

   i2c_start();
   i2c_write((int8)ControlByte);
   i2c_write(memAddress.byte1); // Address High Byte
   i2c_write(memAddress.byte0); // Address Low Byte
   i2c_write(data);
   i2c_stop();
   delay_ms(5);
}

Y para una 24AA512 , pocos cambios

Código:
void writeByte24AA512(My_Address memAddress, int8 data){

   Los_bits_de_un_Byte temp , ControlByte;
   
   temp = memAddress.byte2 ;
   
   ControlByte = 0b10100000; // 0xA0 - bit0 Write = 0

   ControlByte.b1 = temp.b0 ; // Chip Select Bit0
   ControlByte.b2 = temp.b1 ; // Chip Select Bit1
   ControlByte.b3 = temp.b2 ; // Chip Select Bit2

   i2c_start();
   i2c_write((int8)ControlByte);
   i2c_write(memAddress.byte1); // Address High Byte
   i2c_write(memAddress.byte0); // Address Low Byte
   i2c_write(data);
   i2c_stop();
   delay_ms(5);
}



No lo he provado , no me tireis a los leones si no va  lol
« Última modificación: 03 de Enero de 2007, 02:01:13 por Sispic » En línea

pikman
Moderadores
PIC24F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 656


Systemas MicroInformaticos


« Respuesta #15 : 03 de Enero de 2007, 03:38:05 »

Es increible, increible........ademas de ahorrar codigo ahorra RAM y ROM......a veces pienso que nunca voya terminar de aprender a usar la cabeza...!!!! Mr. Green Mr. Green
En línea

saludos
PikMan
pikman
Moderadores
PIC24F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 656


Systemas MicroInformaticos


« Respuesta #16 : 03 de Enero de 2007, 07:03:02 »

Bueno Sisco, ademas de darte las gracias por la ayuda te digo que el driver va como viento, funciona perfectamente, con las 24C512 y las 24C515 o 1025, muy economico por cierto lol lol
En línea

saludos
PikMan
RedPic
Administrador
DsPIC33
*******
Desconectado Desconectado

Sexo: Masculino
Tibet Tibet

Mensajes: 4876



WWW
« Respuesta #17 : 03 de Enero de 2007, 07:18:38 »

Ufff ... he llegado tarde a la solución de mis propios errores  Mr. Green

Pikman, ¿te importaría postear el código completo del driver tal como ha quedado?

Sisco, muchas gracias por tu aporte y tu interés en estos inventos.  lol

En línea

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania
pikman
Moderadores
PIC24F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 656


Systemas MicroInformaticos


« Respuesta #18 : 03 de Enero de 2007, 07:54:47 »

Hola, DIEGO, pues como no aca esta, no difiere mucho de lo posteado, yo agregue la lectura, y la inicializacion del bus y los puertos, de cualquier modo no se si miraste la duda que te deje en le codigo tuyo

Código:

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

void init_ext_eeprom()
{
   output_float(EEPROM_SCL);
   output_float(EEPROM_SDA);

}


typedef struct  {
     int1 b0:1; int1 b1:1; int1 b2:1;  int1 b3:1;  int1 b4:1;  int1 b5:1;  int1 b6:1;  int1 b7:1;
} Los_bits_de_un_Byte;


typedef struct {
        int8 byte0;
        int8 byte1;
        int8 byte2;

} My_Address;



void writeByte24512(My_Address memAddress, int8 data){

   short int status;

   Los_bits_de_un_Byte temp , ControlByte;

   temp = memAddress.byte2 ;

   ControlByte = 0b10100000; // 0xA0 - bit0 Write = 0

   ControlByte.b1 = temp.b0 ; // Chip Select Bit0
   ControlByte.b2 = temp.b1 ; // Chip Select Bit1
   ControlByte.b3 = temp.b2 ; // Chip Select Bit2

   i2c_start();
   i2c_write((int8)ControlByte);
   i2c_write(memAddress.byte1); // Address High Byte
   i2c_write(memAddress.byte0); // Address Low Byte
   i2c_write(data);
   i2c_stop();
   delay_ms(5);
}




int8 readByte24512(My_Address memAddress){

   int8 data;

   Los_bits_de_un_Byte temp,ControlByte;

   temp = memAddress.byte2 ;

   ControlByte = 0b10100000; // 0xA0 - bit0 Write = 0

   ControlByte.b1 = temp.b0 ; // Chip Select Bit0
   ControlByte.b2 = temp.b1 ; // Chip Select Bit1
   ControlByte.b3 = temp.b2 ; // Chip Select Bit2

   i2c_start();
   i2c_write((int8)ControlByte);
   i2c_write(memAddress.byte1); // Address High Byte
   i2c_write(memAddress.byte0); // Address Low Byte
   i2c_start();
   i2c_write((int8)ControlByte|1);
   data=i2c_read(0);
   i2c_stop();
   return data;

}

En línea

saludos
PikMan
RedPic
Administrador
DsPIC33
*******
Desconectado Desconectado

Sexo: Masculino
Tibet Tibet

Mensajes: 4876



WWW
« Respuesta #19 : 04 de Enero de 2007, 03:21:32 »

No, amigo pikman, aún no lo he mirado. Estoy de trabajo hasta las orejas y no he tenido tiempo de ponerme con él. (Pero lo haré, vive diós que lo haré ja ja ja  lol lol lol)

En línea

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

 En línea
Páginas: [1] 2 Imprimir 
« anterior próximo »
Ir a:  

Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.11 | SMF © 2006-2008, Simple Machines LLC XHTML 1.0 válido! CSS válido!
Página creada en 0.235 segundos con 22 consultas.