Forum: Mikrocontroller und Digitale Elektronik dsPIC30F4013: I2C-Probleme


von Daniel (Gast)


Lesenswert?

Hallo!

Ich habe ein Problem mit der Verbindung dsPIC zu MPU6050 (Acc+Gyro) über 
I2C. Der MPU6050 ist am "GY-521 breakout board" und hat die 
Pullup-Widerstände bereits drauf (läuft auf 3,3V; dsPIC auf 5V) 
[http://playground.arduino.cc/Main/MPU-6050]

Das Programm funktioniert auf einem PIC18F4620 ohne Probleme, aber beim 
dsPIC treten mehrere Probleme auf.
Eine niedrigere I2C-Taktfrequenz (100kHz) bringt keine Änderung.

Leider habe ich kein Oszilloskop, mit dem ich die Pins überprüfen 
könnte.

Hier zunächst die Initialisierung (I2C: 400kHz, PIC: 120MHz (30MIPS)):
  TRISFbits.TRISF2=1;
  TRISFbits.TRISF3=1;

  //(1/400KHz-1/1111111)x30MIPs=48
  I2CBRG=48;


  I2CCONbits.I2CEN = 0;
  I2CCONbits.I2CSIDL = 0;
  I2CCONbits.SCLREL = 1;
  I2CCONbits.IPMIEN = 0;
  I2CCONbits.A10M = 0;
  I2CCONbits.DISSLW = 0;  //0: enabled; 1: disabled
  I2CCONbits.SMEN = 0;
  I2CCONbits.GCEN = 0;
  I2CCONbits.STREN = 0;
  I2CCONbits.ACKDT = 0;
  I2CCONbits.ACKEN = 0;
  I2CCONbits.RCEN = 0;
  I2CCONbits.PEN = 0;
  I2CCONbits.RSEN = 0;
  I2CCONbits.SEN = 0;

  I2CRCV = 0x0000;
  I2CTRN = 0x0000;
  I2CCONbits.I2CEN = 1;


1. Senden:
Problem: Hier erhalte ich das zweite Acknowledge vom Empfänger nicht 
mehr.

void WriteI2C(unsigned char ControlByte, unsigned char LowAdd, unsigned 
char data)
{
  unsigned int ErrorCode1,ErrorCode2;

  IdleI2C();      //Ensure Module is Idle
  StartI2C();      //Generate Start COndition
  MasterWriteI2C(ControlByte);  //Write Control byte
  IdleI2C();

  ErrorCode1 = ACKStatus();  //Return ACK Status

  MasterWriteI2C(LowAdd);    //Write Low Address
  IdleI2C();

  ErrorCode2 = ACKStatus();  //Return ACK Status

  MasterWriteI2C(data);    //Write Data
  IdleI2C();

  StopI2C();      //Initiate Stop Condition
  if(ErrorCode1 == 0) { printf("\nACK 1 not received"); }
  if(ErrorCode2 == 0) { printf("\nACK 2 not received"); }
}


2. Empfangen
Hier muss ich ein Delay einfügen (__delay_us(100)) [WARUM?], andernfalls 
steckt das Ding in der Endlosschleife in einer Subroutine (getI2C()) 
(while(!I2CSTATbits.RBF)) fest.

Bei einer nachfolgenden Testroutine mit Auslesen eines Registers erhalte 
ich als Rückgabewert nur den Wert 0xFF (falscher Wert).

void ReadI2C(unsigned char ControlByte, unsigned char Address, unsigned 
char *Data, unsigned char Length)
{
  IdleI2C();        //wait for bus Idle
  StartI2C();        //Generate Start Condition
  MasterWriteI2C(ControlByte);    //Write Control Byte
  IdleI2C();        //wait for bus Idle
  MasterWriteI2C(Address);    //Write start address
  IdleI2C();        //wait for bus Idle

  RestartI2C();        //Generate restart condition
  MasterWriteI2C(ControlByte | 0x01);  //Write control byte for read
  IdleI2C();      //wait for bus Idle
  __delay_us(100);
  getsI2C(Data, Length);    //read Length number of bytes
  NotAckI2C();      //Send Not Ack
  StopI2C();      //Generate Stop
}

unsigned int getI2C(void)
{
  I2CCONbits.RCEN = 1;    //Enable Master receive
  Nop();
  while(!I2CSTATbits.RBF);  //Wait for receive buffer to be full
  return(I2CRCV);      //Return data in buffer
}


Ich habe keine Ahnung, was da los ist.
Bitte um evtl. Hinweise, Ratschläge.

von Daniel (Gast)


Lesenswert?

Update:
Auch beim Austausch des dsPIC ändert sich nichts, an einem Defekt liegt 
es also nicht.

Nachdem der Sensor am anderen PIC (18F4620) mit diesem Programm 
funktioniert, muss das Problem am ehesten im I2C-Modul des dsPIC (ich 
habe das I2C-Steuerungsprogramm ursprünglich aus dem Internet übernommen 
- war für einen 33F-PIC programmiert) liegen. Konfigurationsmäßig sehe 
ich bis jetzt aber keinen Fehler.

Dass mit dem zusätzlichen Delay habe ich übrigens auch nach Google-Suche 
in einem anderen Forum vorgefunden, leider wurde der Beitrag nicht 
weiterverfolgt.

Das I2C-Modul muss wohl irgendwas machen oder nicht machen, was so nicht 
geplant ist.

von Chris B. (dekatz)


Lesenswert?

Es gibt für diesen PIC ein "Errata sheet" mit einigen Einträgen für das 
I2C Modul!
Google nach "dsPIC30F3014/4013 Rev. A1 Silicon Errata - Microchip"...
Vielleicht trifft ja etwas zu (z.B. LATF<2> vor den I2C-Enable auf LOW 
setzen,......)

von Daniel (Gast)


Lesenswert?

Danke für die Info!

Leider hat das nicht den gewünschten Erfolg gebracht.
(Die meisten anderen Dinge zu I2C beziehen sich auf die 
10-Bit-Adressierung, die bei mir nicht eingeschalten ist).

Nachdem ich auch UART verwende und ein UART-Modul dieselben Pins 
benutzen würde wie das I2C-Modul, habe ich die Alternativ-Option (andere 
I/O-Pins) in der Konfiguration für das UART verwendet. Das wird wohl 
damit hoffentlich nichts zu tun haben, ich sehe auch nichts im 
"Errata-Sheet".

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.