Autor Tema: Comunicación I2C entre raspberry PI y dsPIC33F con C30 y wiringPi  (Leído 1506 veces)

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

Desconectado daniel_82

  • PIC10
  • *
  • Mensajes: 12
Comunicación I2C entre raspberry PI y dsPIC33F con C30 y wiringPi
« en: 27 de Febrero de 2018, 10:36:06 »
Hola, tuve que implementar una comunicacion I2C entre una Raspberry Pi 3 y un dsPIC. Luego de buscar bastante lo he logrado, aca dejo un resumen:

Se definen 5 estados para la comunicación I2C, pero para la comunicación con la raspberry solo se usan los primeros 3.

La raspberry actuara como maestro y el dsPIC como esclavo a través de la interrupción del I2C como slave.

Del lado de la raspberry (yo utilizo QT que usa C++) para iniciar la comunicación I2C:


Código: [Seleccionar]
#include "wiringPi.h"
#include "wiringPiI2C.h"
.
.
.
wiringPiSetup();
Int fd=wiringPiI2CSetup (0x20);


0x20 es la dirección que le asigno al dsPIC.

Escritura:

Cuando se desea escribir un comando desde la raspberry se usa la función:
Código: [Seleccionar]
int wiringPiI2CWriteReg8 (int fd, int reg, int data);reg puede ser el parámetro que deseo escribir (Ej una temperatura de seteo) y data es el valor.

Del lado del dsPIC entrara primero en el estado1 y leera la dirección, luego entrara en el estado2 y leera reg y luego volverá a entrar en el estado2 y leera data.

Lectura:

Cuando se desea leer un valor desde el dsPIC a la raspberry se usa la función:
Código: [Seleccionar]
int wiringPiI2CReadReg8 (int fd, int reg);reg puede ser el parámetro que deseo leer y el retorno de la función el valor leido.

Codigo dsPIC

Código: [Seleccionar]
void I2C_Init(void)
{
unsigned int config1 = 0;
unsigned int config2 = 0;

    config1 = (I2C1_ON & I2C1_7BIT_ADD & I2C1_CLK_REL & I2C1_STR_EN & I2C1_GCALL_DIS & I2C1_IPMI_DIS);   
    config2 = 0; //La frecuancia la impone el maestro
    ConfigIntI2C1(SI2C1_INT_ON & SI2C1_INT_PRI_7 & MI2C1_INT_OFF);
    OpenI2C1(config1,config2);
    I2C1ADD = 0x0020;
}

void __attribute__ ((interrupt, no_auto_psv)) _SI2C1Interrupt(void)
{
static unsigned char state=0xFF;
static unsigned char addr=0;
static unsigned char reg=0;
static unsigned char read=0;
static unsigned char write;
static unsigned char aux;
   
   
    //wiringPiI2CWriteReg8  state1(addr) "read" -> stete2(reg) "read" -> stete2(data) "read")
    //wiringPiI2CReadReg8   state1(addr) "read" -> stete2(reg) "read" -> stete3(data) "write")
 
    //State 1: I2C write operation, last byte was an address byte.
    //I2CSTAT bits: S = 1, D_A = 0, R_W = 0, BF = 1
    if(I2C1STATbits.S && !I2C1STATbits.D_A && !I2C1STATbits.R_W && I2C1STATbits.RBF )
    {       
        addr = SlaveReadI2C1();
        I2C1CONbits.STREN = 0;
        state=0;       
    }

    //State 2: I2C write operation, last byte was a data byte.   
    //I2CSTAT bits: S = 1, D_A = 1, R_W = 0, BF = 1
    else if(I2C1STATbits.S && I2C1STATbits.D_A && !I2C1STATbits.R_W && I2C1STATbits.RBF )
    {
        aux = SlaveReadI2C1();
        if(state==0)   
        {
            reg=aux;
            state=1;
        }
        else if(state==1)
        {
            read=aux;
            state=0xFF;
        }       
        I2C1CONbits.STREN = 0;       
    }

    //State 3: I2C read operation, last byte was an address byte.
    //I2CSTAT bits: S = 1, D_A = 0, R_W = 1, BF = 0
    else if(I2C1STATbits.S && !I2C1STATbits.D_A && I2C1STATbits.R_W && !I2C1STATbits.TBF )
    {       
        while(I2C1STATbits.TBF);
        do
        {
            I2C1STATbits.IWCOL = 0;
            if(state==1)
            {               
                write=GetDato(reg);               
                SlaveWriteI2C1(write);     
                state=0xFF;
            }           
        }
        while(I2C1STATbits.IWCOL);                   
        I2C1CONbits.SCLREL = 1;       
    }

    //State 4: I2C read operation, last byte was a data byte.
    //I2CSTAT bits: S = 1, D_A = 1, R_W = 1, BF = 0
    else if(I2C1STATbits.S && I2C1STATbits.D_A && I2C1STATbits.R_W && !I2C1STATbits.TBF )
    {
        while(I2C1STATbits.TBF);
        do
        {
            I2C1STATbits.IWCOL = 0;           
            SlaveWriteI2C1(0x00/*data*/);
        }while(I2C1STATbits.IWCOL);               
        I2C1CONbits.SCLREL = 1;       
    }

    //State 5: Slave I2C logic reset by NACK from master.
    //I2CSTAT bits: S = 1, D_A = 1, R_W = 0, BF = 0
    else if(I2C1STATbits.S && I2C1STATbits.D_A && !I2C1STATbits.R_W && !I2C1STATbits.RBF )
    {       
        I2C1CONbits.SCLREL = 1;
    }

    //Check for I2C Buffer overun state
    else if (I2C1STATbits.RBF || I2C1STATbits.I2COV)
    {       
        I2C1STATbits.I2COV = 0;
        aux = SlaveReadI2C1();
        I2C1CONbits.SCLREL = 1;             
    }

    else;
    IFS1bits.SI2C1IF=0;
}
« Última modificación: 27 de Febrero de 2018, 15:17:31 por daniel_82 »


 

anything