Autor Tema: Pic esclavo I2C  (Leído 3490 veces)

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

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3206
Pic esclavo I2C
« en: 14 de Julio de 2006, 07:34:38 »
Hola, necesito conectar dos pic por medio del bus I2C, y en el maestro, creo que el codigo seria este:

MAESTRO-EMISOR:

i2c_start();
i2c_write(0xA0);
i2c_write(dato1);
i2c_write(dato2);
i2c_stop();

MAESTRO-RECEPTOR:

i2c_start();
i2c_write(0xA1);
dato1=i2c_read();
dato2=i2c_read();
i2c_stop();

Pero no se como tendria que ser el codigo del pic esclavo, el ejemplo que viene en el CCS no lo entiendo.

Además tengo otra duda, en caso de que el Maestro-Receptor solicite un dato al Esclavo-Emisor, y este ultimo no tenga nada que enviar, ¿El Maestro-Receptor se queda esperando continuamente hasta que reciba algo?

Saludos y gracias.
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado piriots

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 609
Re: Pic esclavo I2C
« Respuesta #1 en: 14 de Julio de 2006, 07:43:48 »
En el ccs hay un ejemplo que simula una eeprom controlada por i2c, yo uso este ejemplo para poder guardar la informacion que el master manda al slave en un buffer. El codigo del slave seria este.
Código: [Seleccionar]
typedef enum {NOTHING,CONTROL_READ,ADDRESS_READ, READ_COMAND_READ} I2C_STATE;
I2C_STATE fState;
byte address, buffer [0x10];

#INT_SSP
void inter_i2c()
{
   byte incoming;/////es donde recibo el byte que me manda
   if (i2c_poll() == FALSE) {
      if (fState == ADDRESS_READ) {  //i2c_poll() returns false on the
         i2c_write (buffer[address]);//interupt receiving the second
         fState = NOTHING;           //command byte for random read operation
      }
   }
   else {
      incoming = i2c_read();
      if (fState == NOTHING){

         fState = CONTROL_READ;
               }
      else if (fState == CONTROL_READ) {
         address = incoming;
         fState = ADDRESS_READ;
}
      else if (fState == ADDRESS_READ) {
         buffer[address] = incoming;
         fState = NOTHING;

      }
   }
}

Ahora solo falta activar la interrupcion dentro de la funcion principal y inicializar el buffer a 0
enable_interrupts(INT_SSP);               
enable_interrupts(GLOBAL);                 
fState = NOTHING;
address = 0x00;                           
for(i=0;i<0x10;i++)buffer=0;     // borramos el bufer

En la funcion que has puesto tu de maestro emisor, dato 1 seria la posicion del buffer donde quieres guardar el dato y dato 2 es el dato a enviar.

Espero ser de ayuda salu2

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3206
Re: Pic esclavo I2C
« Respuesta #2 en: 14 de Julio de 2006, 12:39:38 »
A ver si entiendo el ejemplo, los datos recibidos se guardan en el buffer llamado "buffer", que puede almacenar hasta 16 bytes.

Por otro lado, el master si quiere enviar dos datos, ¿tendria que hacer lo siguiente?:

i2c_start();
i2c_write(0xA0);
i2c_write(0);   //posicion 0 del buffer
i2c_write(dato1);
i2c_write(1);   //posicion 1 del buffer
i2c_write(dato2);
i2c_stop();

Y tengo otra pregunta, el ejemplo que me has puesto ¿Sirve para enviar datos al master?

Saludos y gracias.
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado piriots

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 609
Re: Pic esclavo I2C
« Respuesta #3 en: 14 de Julio de 2006, 13:53:59 »
El buffer puede almacenar tantos bytes como quieras, solo has de definir el tamaño del array buffer para modificarlo. Esta
secuencia que propones es correcta y deberia funcionar sin problemas. En caso que falle pruba de poner un delay_ms(10) entre escrituras.

Para que el master lea los valores del slave utiliza esta secuencia.

Código: [Seleccionar]
   i2c_start();
   i2c_write(direccion);                 // direccion del slave
   i2c_write(poosicion); // posicion dentro del buffer
   i2c_start();
   i2c_write(direccion+1);
   i2c_read(0);
   i2c_stop();


Salu2