I2C Raspberry Pi a PIC24F

2

Soy nuevo en la programación de PIC y PIC, pero estoy trabajando en un pequeño proyecto para intentar que un PIC24F32KA301 se comunique con una Raspberry Pi utilizando I2C. La Raspberry Pi es el maestro y el PIC es el esclavo. He creado un pequeño programa Python en la Raspberry Pi y he probado que funciona comunicándome exitosamente con un Arduino, lo que quiero hacer ahora es reemplazar el Arduino con un PIC.

Sólo para estar completo, he incluido el siguiente programa de python:

import smbus
import time

bus = smbus.SMBus(1)
address = 0x22

def writeNumber(value):
    bus.write_byte(address, value)
    return -1

def readNumber():
    number = bus.read_byte(address)
    return number

while True:
    var = input("Enter 1 - 9: ")
    if not var:
        continue
    writeNumber(var)
    print "RPI: Hi Arduino, I sent you ", var

    time.sleep(1)
    number = readNumber()
    print "Arduino: Hey RPI, I received a digit ", number
    print

Estoy bastante seguro de que he conectado el PIC y la Raspberry Pi correctamente:

GND < --- > Vss (pin 19)
SCL < --- > SCL1 (pin 12)
SDA < --- > SDA1 (pin 13)

La Raspberry Pi se alimenta a través de USB (creo que es de 5V, pero podría ser de 3V) y el PIC se alimenta por separado con una batería de 3V. El Arduino no tenía ninguna resistencia de activación, así que asumo que está bien no tener ninguna en el PIC (¿quizás esto esté mal?).

Estoy usando C con el compilador XC16 y la biblioteca i2c.h para programar el PIC, pero no estoy muy seguro de lo que estoy haciendo, he hecho todo lo posible para juntar las cosas con ejemplos de I2C y poco bits que he leído en varios foros, etc:

#define USE_AND_OR    // not sure what this is!
#include <p24Fxxxx.h>
#include <i2c.h>

unsigned char I2C_RECV[1]

void main(void) {
    unsigned int temp, i;
    for(i=0; i<1; i++)
        I2C_RECV[i]=0;

    TRISA = 0b0000000000000000;
    PORTA = 0b0000000000000001;

    /* INITIALISE I2C MODULE  */
    CloseI2C1();                            // close i2c if it was operating earlier

    while(1) {
        OpenI2C1((I2C_ON | I2C_7BIT_ADD | I2C_CLK_REL | I2C_STR_EN), 0);
        I2C1ADD = 0x22;                     // initialze slave address to 1E

        // receive data from master
        while(DataRdyI2C1() == 0);          // wait until data is transmitted from master
        temp = SlaveReadI2C1();             // read address to empty buffer

        SlavegetsI2C1(I2C_RECV, 1);         // receive data

        if(I2C_RECV[0] == 9) {
            PORTA = 0b0000000000000011;
        }

        CloseI2C1();
    }
}

El código es bastante simple (pero probablemente incorrecto). Básicamente, inicializo el módulo I2C y enciendo un LED, luego entro en un bucle, abro la conexión I2C con la dirección 0x22 y espero que el maestro envíe algunos datos. Cuando se reciben los datos, verifico su valor, si es 9 enciendo otro LED.

En la Raspberry Pi puedo confirmar que se puede acceder al PIC ejecutando i2cdetect -y 1 . ¡Puedo ver el PIC en la dirección 0x22, lo que me da cierta confianza de que al menos voy en la dirección correcta! Sin embargo, cuando ejecuto el programa python recibo un error de E / S, el número de error es 5. He mirado a mi alrededor para averiguar qué significa eso, pero es un error muy vago, ¡básicamente cualquier cosa podría haber salido mal!

No estoy seguro de si mi circuito sea incorrecto (es decir, ¿necesito resistir las resistencias, si es así, ¿cómo calculo qué resistencia necesitan ser?) o mi programa PIC. Si alguien puede comprobar que el programa tiene sentido o tiene algún consejo, le estaría muy agradecido.

Gracias.

    
pregunta The Sockmonster

1 respuesta

-2

Prueba esto:

unsigned char I2C_RECV[1]

void main(void) {
  unsigned int temp=0,temp2=0, i;
  for(i=0; i<1; i++)
     I2C_RECV[i]=0;

  TRISA = 0b0000000000000000;
  PORTA = 0b0000000000000001;

  /* INITIALISE I2C MODULE  */
  CloseI2C1();        // close i2c if it was operating earlier

  while(1){

   config1 = (I2C_ON | I2C_7BIT_ADD | I2C_CLK_REL | I2C_STR_EN  );
   config2 = 0;                //This defines I2C to be slave
   OpenI2C1(config1,config2);  //configure I2C1
   I2C1ADD = 0x22;             //I2C address set to 1E  

    I2C1CONbits.I2CEN = 1;     // ENABLE I2C!!
    I2C1CONbits.DISSLW = 1;    // Disable slew rate control
    I2C1CONbits.GCEN = 1;      // Enable interrupt when a general call address is received (enable for reception)

    while(IFS1bits.SI2C1IF==0){asm ("clrwdt");}; //wait untill the data is transmitted from master

    temp = SlaveReadI2C1();     //Read address to empty buffer
    temp2 = SlaveReadI2C1();    //Read data to empty buffer

    SlavegetsI2C1(I2C_RECV,1);

    if(temp2 == 0x09) PORTA = 0b0000000000000011;
    else PORTA = 0b0000000000000000;        
    CloseI2C1();      //Disable I2C
  }  
}
    
respondido por el Eteif

Lea otras preguntas en las etiquetas