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.
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.
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,......)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.