Autor Tema: i2c entre dos PICs  (Leído 2607 veces)

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

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
i2c entre dos PICs
« en: 24 de Julio de 2007, 15:43:58 »
saludos estoy intentando hacer una cominucación I2C entre un 16f648a y un 16f84a, lo que qero hacer es enviar dos bytes de datos (si quisiera enviar mas como haria en el master y en el slave?), como que asemejando con una eeprom externa mando un dato como la direccion (sentido) en la que queria escribir y el dato (vueltas), y el slave debe leer eso y hacer diferentes cosas segun lo que lea. aca dejo mis codigos:

del master:
Código: [Seleccionar]
#include <16f648a.h>
#use delay(clock=4MHZ)
#include <teklado-ban.c>   // libreria qeu contiene a: kbd_getc() para explorar el teclado
#fuses XT,NOWDT,PUT,MCLR,NOBROWNOUT,NOLVP,NOCPD,NOPROTECT
#use fast_io(a)
#use fast_io(b)
#define Dev_SDA PIN_A0 // Pin defines
#define Dev_SCL PIN_A1
#use i2c(master, sda=Dev_SDA, scl=Dev_SCL,fast)

int sentido,vueltas;
char c,c2;

void enviar(direccion,dato)
{
   i2c_start();
   i2c_write((0xa0|(BYTE)(direccion>>7))&0xfe);
   i2c_write(direccion);
   i2c_write(dato);
   i2c_stop();
}

void main()
{
   set_tris_a(0xfc);
   set_tris_b(0xf0);
   //output_a(0);
   //output_b(0);
   output_float(Dev_SDA);         //I2C pin float
   output_float(Dev_SCL);         //I2C pin float
   while(true)
   {
      do
      {
         c=kbd_getc();
      }while(c==0);            // si no se ha presionado ninguna tecla la función devuelve 0 (cero)
      do
      {
         c2=kbd_getc();       // ya que si usas c de nuevo perderías el valor de la tecla
      }while(c2!=0);          // de acá no sale hasta que no sueltes la tecla
      vueltas=c;
      do
      {
         c=kbd_getc();
      }while(c==0);
      do
      {
         c2=kbd_getc();       // ya que si usas c de nuevo perderías el valor de la tecla
      }while(c2!=0);          // de acá no sale hasta que no sueltes la tecla
      sentido=c;
      enviar(sentido,vueltas);
   }
}

la del slave todavia no lo tengo claro, en la parte de recepcion, como lo hago, porque ya de ahí es mas sencillo una vez recibdo los datos, por ahora tengo el encabezado:

Código: [Seleccionar]
#include <16f84a.h>
#fuses XT,NOWDT,NOPROTECT,PUT
#use fast_io(a)
#use fast_io(b)
#use delay(clock=4MHZ)
#define Dev_SDA PIN_A0 // Pin defines
#define Dev_SCL PIN_A1
#use i2c(master, sda=Dev_SDA, scl=Dev_SCL,fast,address=0xa0)

void main()
{
   set_tris_a(0xff);
   set_tris_b(0);
   output_float(Dev_SDA);         //I2C pin float
   output_float(Dev_SCL);         //I2C pin float
   while(true)
   {
     
   }
}
.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: i2c entre dos PICs
« Respuesta #1 en: 28 de Julio de 2007, 23:29:30 »
se puede realizar la comunicacion i2c entre pic que no tengan interrupcion por ssp???
.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: i2c entre dos PICs
« Respuesta #2 en: 01 de Agosto de 2007, 16:01:57 »
al parecer no se peude realizar i2c como slave si el micro no lleva interrupcion por ssp, o bueno es lo qeu mayormente he logrado ver. Ahora, nocturno he visto tu emulador del saa1064 hxxp://www.micropic.es/descargas/emulador%20saa1064.c con el 16f876 y logre entender un 40% del codigo o talvez un poco mas, pero weno ahora qeuisiera que me ayudes a comprenderlo mejor, hice esto (viendo tb la libreria del saa1064):

para mi master:
Código: [Seleccionar]
#include <16f648a.h>
#use delay(clock=20000000)
#include <teklado-ban.c>
#fuses HS,NOWDT,PUT,MCLR,NOBROWNOUT,NOLVP,NOCPD,NOPROTECT
#use fast_io(a)
#use fast_io(b)
#define Dev_SDA PIN_A0 // Pin defines
#define Dev_SCL PIN_A1
#use i2c(master, sda=Dev_SDA, scl=Dev_SCL,fast)
#define ADR 0x76
int sentido,vueltas;
char c,c2;

void enviar(int D1,int D2)
{
   //control=(control & 0b01111110);   //me aseguro modo estatico
      i2c_start();
      i2c_write(ADR);      //direccion esclavo
//      i2c_write(0x00);   //instruction byte -> registro de control
//      i2c_write(control);   //control byte
      i2c_write(D1);      //escribe digito 1
//      i2c_write(0);      //libre
      i2c_write(D2);      //escribe digito 2
//      i2c_write(0);      //libre
      i2c_stop();
}

void main()
{
   set_tris_a(0xfc);
   set_tris_b(0xf0);
   //output_a(0);
   //output_b(0);
   port_b_pullups(TRUE);         // activa pull up del puerto b, no hará falta conectar resistencias
   output_float(Dev_SDA);         //I2C pin float
   output_float(Dev_SCL);         //I2C pin float
   while(true)
   {
      do
      {
         c=kbd_getc();
      }while(c==0);
      do
      {
         c2=kbd_getc();       // ya que si usas c de nuevo perderías el valor de la tecla
      }while(c2!=0);          // de acá no sale hasta que no sueltes la tecla
      vueltas=c-'0';
      do
      {
         c=kbd_getc();
      }while(c==0);
      do
      {
         c2=kbd_getc();       // ya que si usas c de nuevo perderías el valor de la tecla
      }while(c2!=0);          // de acá no sale hasta que no sueltes la tecla
      sentido=c-'0';
      enviar(sentido,vueltas);
   }
}
con pequeños cambios al anterior master que postee.

y en mi slave coloque:
Código: [Seleccionar]
#include <16f88.h>
#fuses HS,NOWDT,NOPROTECT,PUT
//#use fast_io(a)
//#use fast_io(b)
#use delay(clock=20000000)
#define Dev_SDA PIN_A0 // Pin defines
#define Dev_SCL PIN_A1
#use i2c(slave, sda=Dev_SDA, scl=Dev_SCL,fast,address=0x76)

int sentido,vueltas;
BYTE address, buffer[0x10];

#INT_SSP
void ssp_interupt ()
{
   BYTE incoming,state;
   output_toggle(PIN_A2);
   state=i2c_isr_state();
   if(state<0x80)
   {
      incoming=i2c_read();
      if(state>0)
         if(state==1)
            address=incoming;
         else
         {
            buffer[address]=incoming;
            address++;
         }
   }
}

void main()
{
   set_tris_a(0xfb);
   set_tris_b(0);
   SETUP_ADC_PORTS(NO_ANALOGS);
   setup_adc(ADC_OFF);
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   output_float(Dev_SDA);         //I2C pin float
   output_float(Dev_SCL);         //I2C pin float
   while(true)
   {
      output_b(buffer[1]);
   }
}

en realidad lo que quisiera es mandar solo 2 datos, dos numeros, uno que me diga cuantas vueltas girará un motor paso a paso y otro en que sentido lo hará, solo necesito saber como guardo esos datos recibidos en buffer[0]y[1]

hice esos codigos y el la simulacion en proteus no se interrumpe el slave, ya que puse un  output_toggle(PIN_A2); cuando ocurra interrupcion y nunca se interrumpe, les dejo adjunto el archivo de proteus y los codigos

Espero vuestra ayuda, del que pueda ver donde cometo el error, coloque en mi respuesta a Nocturno pues en codigos que el escribio me base.

muchas gracias a todos, un saludo
.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: i2c entre dos PICs
« Respuesta #3 en: 02 de Agosto de 2007, 12:56:00 »
 :cry:
.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: i2c entre dos PICs
« Respuesta #4 en: 04 de Agosto de 2007, 22:37:24 »


   nadie?? 




                                                                  :cry:
.


 

anything