uControl
Mayo 19, 2013, 08:12:17 *
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.
¿Perdiste tu email de activación?

Ingresar con nombre de usuario, contraseña y duración de la sesión
 
   Inicio   Ayuda Buscar Ingresar Registrarse  
Páginas: [1]   Ir Abajo
  Imprimir  
Autor Tema: Diferencias en el manejo de eeprom 24c16 y 24c32 (duda de protocolo)  (Leído 1580 veces)
0 Usuarios y 1 Visitante están viendo este tema.
nestoriano
PIC10F
*
Desconectado Desconectado

Mensajes: 25


« : Abril 06, 2012, 12:40:40 »

Hola hace unos días empece a hacer mudanza de mis proyectos desde CCS C a Jalv2. El CCS me estaba dando problemas para seguir un proyecto empezado en una PC diferente y me encontré con Jalv2 y Picshell y me encanto! Empece a reescribir y simplificar librerías de registro de desplazamiento y EEPROM.
Jalv2 incluye librerías para 24c02 y 24c256. A partir de este momento empezó mi confusión sobre estas memorias.

La forma de grabar datos en las memorias 24c16 para abajo (a partir de ahora memorias problemáticas) y 24c32 para arriba son diferentes...

Para escribir en memorias 24c32 para arriba:
1) mandar 1010 000 0             <<<----- en escritura.
2) mandar 0~0xFF                  <<<----- dirección parte 1
3) mandar 0~0xFF                  <<<----- dirección parte 2
4) mandar dato
5) fin.


Para escribir en memorias problemáticas:
1) mandar 1010 000 0             <<<----- en escritura. Atención en los 3 ceros.
2) mandar 0~0xFF                  <<<----- dirección.
3) mandar dato
4) fin.


Y claro esperar el ACK por cada byte enviado.

Las memorias problemáticas no soportan dirección mayor de 1 byte. Para escribir por ejemplo en la posición 0xFF +1 tengo que cambiar los 3 ceros por 001 y en la dirección mandar 0 , que seria la dirección 0 de la 2da pagina. Cada pagina tiene 256 bytes.

Mi duda es, para escribir en toda la memoria de la eeprom problemática, hay que ir cambiando esos 3 ceros dependiendo de que parte quiero escribir?

Si es así tengo que armar una librería para el manejo de estas memorias o no se, quizás entendí mal y hay otras formas mas elegantes para hacer las cosas.


En línea
el_vpi
Moderador
PIC18F
*****
Desconectado Desconectado

Mensajes: 1122



« Respuesta #1 : Abril 06, 2012, 08:19:36 »

Hola Nestoriano, mirando la hoja de datos de la 24c16 seria asi como decis. Esos 3 bits corresponde a la parte mas significativa de la direccion.

The next 3 bits are used for memory block addressing and select one of the eight 256 x 8 memory blocks. These bits should be considered the three most significant bits of the data word address.

Saludos, Daniel.
En línea
nestoriano
PIC10F
*
Desconectado Desconectado

Mensajes: 25


« Respuesta #2 : Abril 06, 2012, 04:20:52 »

Gracias Daniel por responder, estaba confundido sobre estas memorias, había leído que se pueden colocar varias de estas en el mismo bus (cambiando las patas a0 a1 y a2 en circuito) como las 24c32 para arriba y pensaba que la forma de enviar los datos eran iguales.

En Proteus las patas a0 a1 y a2 no están implementadas así que seria imposible colocar mas de una de estas en el mismo bus.

Ahora estoy empezando a hacer la librería para estas memorias Si lo hago de la forma que yo se con if, restas y multiplicación, el código se me hace mas largo de lo necesario. 

Este trozo lo tome del CCS para el manejo de memorias 24c16,

Código:
#define EEPROM_ADDRESS unsigned int16
#define EEPROM_SIZE    1024

void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data) {
   while(!ext_eeprom_ready());
   i2c_start();
   i2c_write((0xa0|(BYTE)(address>>7))&0xfe);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
}

Mi duda es, como hace CCS para reemplazar mis cálculos avanzados con esto

Código:
   i2c_write((0xa0|(BYTE)(address>>7))&0xfe);

No logro entender, alguien podría explicarme que es lo que hace ese trozo? Ese 0xfe para que esta?

Gracias.
En línea
el_vpi
Moderador
PIC18F
*****
Desconectado Desconectado

Mensajes: 1122



« Respuesta #3 : Abril 06, 2012, 05:40:51 »

( (0xa0| (BYTE)(address>>7) ) & 0xfe )

0xa0, es el identificador (por asi llamarlo) de la memoria.
address >> 7, ahi te quedas con la parte mas alta de los datos. (deberian ser 8, despues explico)
0xfe, es la mascara que aplicas para dejar el ultimo bit en "0" indicando que es escritura de la memoria.

ahora, porque desplazo 7 en lugar de 8 posiciones ? porque en realidad en el byte que mandas a la memoria esta desplazado un bit hacia arriba, y asi puede quedar bien cuando haces el or (|)
Ahi te quedaria el LSB de tu dato con algo que no queres, y que debe ser "0" para escribir por lo tanto a todo esto le mandas la mascara 0xfe. En el caso de querer leerla a la memoria, deberias hacer un or (|) con 0x01 para dejar ese bit en "1" .

Espero haber aclarado el tema, 'ta ?

Saludos, Daniel.
En línea
nestoriano
PIC10F
*
Desconectado Desconectado

Mensajes: 25


« Respuesta #4 : Abril 06, 2012, 09:15:01 »

Desconocia la funcion OR y AND a nivel bits, todos los dias se aprende cosas nuevas jeje. Gracias por la explicacion!

Código:
  var byte ack_ok
   var word address=0x697
   var byte dato=0x99
 
   i2c_initialize()
   i2c_start()                           
   
   var byte address_bytes[2] at address
   var byte address_low
   var byte address_high
   
   address_high  = address_bytes[1]
   address_low = address_bytes[0]
   
   ack_ok = i2c_transmit_byte((0xFE & address_high<<1) | 0xA0)
   ack_ok = i2c_transmit_byte(address_low)
   ack_ok = i2c_transmit_byte(dato)
   
   i2c_stop()
                             
   
Lo que hice fue partir en 2 la direccion porque si le metia datos de 2 bytes dentro de la funcion i2c_transmit_byte() me daba un par de warning.
Con ese codigo funciona 10 puntos para escribir en memorias problematicas (ahora no tan problematica).
Hay algo para corregir para que funcione de una manera mas optima?
En línea
el_vpi
Moderador
PIC18F
*****
Desconectado Desconectado

Mensajes: 1122



« Respuesta #5 : Abril 06, 2012, 11:09:16 »

bueno me alegra que se aclaro.
Ahora yo cambiaria esta linea:

ack_ok = i2c_transmit_byte((0xFE & address_high<<1) | 0xA0)

por

ack_ok = i2c_transmit_byte(0x0E & (address_high<<1)) | 0xA0)

cambio el & con 0xfe por 0x0e, por que ? porque asi me aseguro de limpiar el nibble alto que es sobre el cual voy a hacer el OR. Nunca se sabe si en la variable address_high viene algun bit ahi arriba. Bah! mañas de puro desconfiado, pero es mas seguro.
Ademas agrego el () para asegurar que shiftea address_high y ella junto con en AND.


saludos, Daniel.
En línea
nestoriano
PIC10F
*
Desconectado Desconectado

Mensajes: 25


« Respuesta #6 : Abril 07, 2012, 12:32:41 »

Ya arme la librería para manejar estas memorias. Lo probé en Proteus y funciona, faltaría probarlo en la practica.

Por si a alguien le interesa:

Código:
procedure read_ext_eeprom(word in mem_address, byte out datadata) is
   var byte ack_ok
   var byte address_low
   var byte address_high
   
   var byte address_bytes[2] at mem_address
   address_high  = address_bytes[1]
   address_low = address_bytes[0]
   
   
   i2c_start()                                   
   ack_ok = i2c_transmit_byte(((address_high<<1) | 0xA0) & 0x0E )
   ack_ok = i2c_transmit_byte(address_low)       
   
   i2c_restart()                                   
   ack_ok = i2c_transmit_byte(((address_high<<1) | 0xA0) | 0x01 )
   datadata = i2c_receive_byte(0)                     
   i2c_stop()             
   
end procedure


procedure write_ext_eeprom(word in mem_address, byte in data) is
   var byte ack_ok
   var byte address_bytes[2] at mem_address
   var byte address_low
   var byte address_high
   
   address_high  = address_bytes[1]
   address_low = address_bytes[0]
   
   i2c_start()                             
   ack_ok = i2c_transmit_byte(((address_high<<1) | 0xA0) & 0x0E )
   ack_ok = i2c_transmit_byte(address_low)
   ack_ok = i2c_transmit_byte(data)
   i2c_stop()                             
   _usec_delay(10_000)                   
end procedure

Ejemplo: Al estilo CCS

Citar
i2c_initialize()
 
 write_ext_eeprom(0x13f,0b11001100)  ----- direccion 1~2 bytes, byte dato
 read_ext_eeprom(0x13f,dato)            ----- direccion 1~2 bytes, byte dato

portc=dato                                   ------portc=0b11001100

Teóricamente funciona con memorias que sean menor o igual a 24c16. Las patas 1,2,3 y 4 de la eeprom debe ir a negativo.

Ya se puede dar el tema por solucionado. Gracias Daniel! con esto ya puedo empezar con la mudanza de CCS a Jalv2.

En línea
el_vpi
Moderador
PIC18F
*****
Desconectado Desconectado

Mensajes: 1122



« Respuesta #7 : Abril 07, 2012, 09:29:07 »

Bueno, suerte en la mudanza.

Saludos, Daniel.
En línea
Páginas: [1]   Ir Arriba
  Imprimir  
 
Ir a:  

Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.18 | SMF © 2011, Simple Machines
SMFAds for Free Forums
XHTML 1.0 válido! CSS válido!
Página creada en 0.099 segundos con 29 consultas. (Pretty URLs adds 0.015s, 3q)
loggkey