Forum: Mikrocontroller und Digitale Elektronik PIC18 + MPU6050 funktionier nicht


von M.H. (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe einen Code für dem C18 Compiler geschrieben, um mit meinem 
PIC18F45k22 über I2C mit dem MPU6050 zu kommunizieren. Ich habe die 
Initialisierung geschrieben, und den MPU so konfiguriert, dass ich am 
Interrupt-Pin ein Signal erhalte, wenn die Daten bereit sind. Ich kann 
aber kein Signal messen, d.h. der Fehler müsste irgendwo in der 
Initialisierung oder der I2C-Kommunikation liegen, i finde aber keine. 
Kann sich bitte jemand von euch diesen Code ansehen.

Danke

von M.H. (Gast)


Lesenswert?

Ich habe mit dem Oszi gemessen und gesehen, dass der Fehler in der I0C 
Routine selbst liegen müsste.
Während der Befehl
1
  MPU6050_Write_Reg(MPU6050_RA_ACCEL_CONFIG,0b00011000);  // +/- 16 g
ausgeführt wird bleibt der SDA Pin dauerhaft auf 0, das Programm hängt 
sich auf.

Die I2C-Lib ist die, die bereits im C18 enthalten ist.

von M.H. (Gast)


Angehängte Dateien:

Lesenswert?

Jetzt habe ich mit derselben I2C Routine ein Programm für den HMC5883L 
geschrieben und es hat funktioniert.
Har irgendjemand eine Ahnung woran das liegen könnte?

von M.H. (Gast)


Lesenswert?

Hat jemand eine Ahnung woran das liegen konnte?

von Linüx (Gast)


Lesenswert?

M.H. schrieb:
> ausgeführt wird bleibt der SDA Pin dauerhaft auf 0, das Programm hängt
> sich auf.

Was sagt denn die externe Beschaltung deines I2C? Alles beachtet 
(pullups, spannungslevel und so)?

von M.H. (Gast)


Lesenswert?

Die Pull Up habe ich, die Spannungspegel passen, da die kommunikation am 
Anfang und die mit dem HCM5883L funktioniert. Ich versorge den PIC mit 
5V und den MPU6050 + HMC5883L mit 3.3V.

von Frank M. (frank_m35)


Lesenswert?

M.H. schrieb:
> Ich versorge den PIC mit
> 5V und den MPU6050 + HMC5883L mit 3.3V.
Warum?
Datenblatt des MPU6050:
VDD: max. 3.46V
VLogic: max. VDD, d.h. 3.46V
High Level an I2C: 0.7*VLOGIC to VLOGIC + 0.5V, d.h. max. 4V.

Hast du das beachtet? Hast du das geregelt? Warum überhaupt zwei 
Spannungsversorgungen und nicht einfach alles mit 3.3V?

Das selbe gilt übrigens für den HMC5883L, siehe Datenblatt Seite 7 
'SINGLE SUPPLY REFERENCE DESIGN', steht explizit bis 3.6V sowohl VDD als 
auch I/O des uC.

von M.H. (Gast)


Lesenswert?

Ich habe 2 Versorgunfsspannungen, da am PIC auch noch ein  5V LCD hängt. 
Die Spannung auf dem Bus kann nicht zu hoch werden, da die pull up die 
auf 3.3V sind. Der PIC erkennt die 3.3V als high, sonst würde es mit dem 
HMC5883L ja auch nicht funktionieren.

Die Lösung mit den 2 Spannungen ist nur vorübergehend mit meinem Test 
Board. Wenn alles funktioniert werde ich dann eine Platine machen, auf 
der alles mit 3.3V arbeitet.

von usuru (Gast)


Lesenswert?

> ausgeführt wird bleibt der SDA Pin dauerhaft auf 0, das Programm hängt
> sich auf.

Welchen Wert haben die Pullup-Widerstände? Die werden nämlich meist zu 
gross gemacht, dann kommen die Leitungen SDA und SCK (wie bei Dir) nicht 
hoch. Für 3.3 Volt sind meist 1k2 oder 1k5 nötig.

von M.H. (Gast)


Lesenswert?

Die Pull Up sind 4.7k. Das fürfte aber nicht das Problem sein, da das 
Signal auf dem Oszi gut ausschaut und die Kommunikation mit dem HCM5883L 
funktioniert. Das Sigak bleib auf >0.5V, es wird activ auf 0 gezogen.

von M.H. (Gast)


Lesenswert?

Ich wollte kleiner 0.5V und nicht größer schreiben.

von usuru (Gast)


Lesenswert?

Wenn es mit dem einen IC geht, ist kein Beweis dafür, dass es auch mit 
dem anderen gehen muss, HCM5883L und MPU6050 sind doch verschiedene ICs.

Mach die Widerstände mal kleiner, ist doch kein Problem.

von Frank M. (frank_m35)


Lesenswert?

Also wenn's mit dem einen IC funktioniert, sollte deine Implementierung 
passen (ich benutze auch PICs, habe aber die I2C Routinen selbst 
implementiert, daher weiß ich nicht ob man bestimmte Eigenarten bei den 
vorgefertigten beachten muss)

Deine Adressen stimmen hoffentlich so weit (konnte ich nicht überprüfen, 
da sie im Code-Ausschnitt fehlen).

Dann hast du im MPU Code so einen WHO_AM_I, schon mal ohne probiert? 
Vielleicht stimmt da etwas nicht und der MPU hängt danach. Zumal du den 
MPU in einer Dauerschleife non-stop initialisierst.
Probiere mal es so wie beim HCM zu machen, initialiesieren, ohne 
WHO_AM_I, und in einer Dauer-Schleife Werte auslesen.
Als WHO_AM_I hast du 0x68, d.h. 100 0100, genauso wie im Datenblatt, 
jedoch steht ein paar Zeilen weiter drunter 11 0100, d.h. 0x52, als 
Default Wert. Ich verstehe den Unterschied nicht, aber vielleicht 
einfach mal die ganze Überprüfung weg lassen.


Hast du die Möglichkeit das Programm zu debuggen? Pic-Kit 3, ICD 2, ICD 
3, ...
Oder hast du nur ein Programmiergerät?

Entweder über den Debugger oder durch ansteuern einer LED kannst du auch 
einmal überprüfen wo sich dein PIC aufhängt (was er vermutlich tut). 
D.h. ob die Initialisierungsroutine durchgeführt wird, oder an welcher 
Stelle er nicht weiter macht.


Hast du den IC selbst verlötet oder auf einem fertigen Board gekauft?


Ich hatte auch hin und wieder Probleme, als ich noch nicht alles richtig 
implementiert hatte, dass sich der PIC (in meinem Fall 24F) nach einem 
falschen Befehl jedes mal in der I2C Routine aufgehängt hat. Ich weiß 
bis heute nicht ob es am PIC oder am Beschleunigungsensor (ein anderer 
als deiner) lag, der nach dem falschen Befehl einfach nicht mehr 
reagierte. Erst nach einem Trennen der Stromversorgung hat es wieder 
ordnungsgemäß funktioniert.
Für dich heißt das: Trenne hin und wieder mal die Stromversorgung, nicht 
dass sich ein IC nach längerem rum probieren aufgehängt hat und den Bus 
blockiert.

von M.H. (Gast)


Angehängte Dateien:

Lesenswert?

Hier ist ein neuer Code, mit dem funktioniert es auch nicht.

Ich bin das Programm mit dem PICkit3 im einzelschritt durchgegangen. Ich 
habe die Zeile bei der sich das Programm blockiert mit einem Kommentar 
versehen. Es passiert bereits beim ersten Durchlauf der while-Schleife.

von M.H. (Gast)


Lesenswert?

Sobald sich das Programm blockiert ist die SDA-Leitung auf Masse.

In ASM-Listing werden diese beiden Zeilen in eine Endlosschleife 
ausgeführt.
1
  0D16    B0C7     BTFSC SSP1STAT, 0, ACCESS
2
  0D18    D7FE     BRA 0xd16

von M.H. (Gast)


Lesenswert?

Frank M. schrieb:
> Hast du den IC selbst verlötet oder auf einem fertigen Board gekauft?

Ich habe so eine kleine Platine mit diesem IC bei ebay gekauft.

von Frank M. (frank_m35)


Lesenswert?

Also bei der Intitialisierung schreibst du ja auch schon, und da hängt 
sich nichts auf, d.h. der IC könnte funktionieren. Daher würde ich 
einfach vor und nach dem Write Befehl, und auch sonst, auch mal noch ein 
IdleI2C1();  setzen, genauso wie in der MPU6050_Write_Reg Funktion du es 
gemacht hast, die ja anscheinend tadellos funktioniert.

Ebenso mach mal die Schleife ganz raus und setze eine leere Schleife an 
das Ende der Main() Routine. Dann starte das Programm und pausiere 
danach, dann ist es irgendwie 'übersichtlicher' und es besteht nicht die 
Gefahr dass die Schleife ein paar mal durchläuft und dann hängt.

Es ist noch ein kleiner Fehler drin:
Wenn du die Daten lesen willst:
1
IdleI2C1();
2
StartI2C1();
3
WriteI2C1(MPU6050_ADDRESS);          // Write Hier hängt sich das Programm auf  
4
WriteI2C1(MPU6050_RA_ACCEL_XOUT_H);
5
StopI2C1();
6
StartI2C1();    
7
WriteI2C1(MPU6050_ADDRESS+1);          // Read

Du stoppst und startest den Bus neu, was so nicht gehen sollte. 
(Datenblatt S.37 steht auch nicht Stop, sondern nur Start) Du musst 
stattdessen eine Repeated Start condition senden, wie genau der Befehl 
in der Microchip Library heist, weiß ich nicht, vermutlich
1
RestartI2C();
Vielleicht macht es einen Durchlauf und danach hängt er?

von M.H. (Gast)


Lesenswert?

Jetzt ohne schleife: Wenn ich die Zeile  MPU6050_Read_Acc_XYZ(&x,&y,&z); 
in Einzelschritt mit Step over überspringe hängt sich das Programm nicht 
auf, auf dem Display wird für x,y,z 0 ausgegeben. Wenn ich in die 
Funktion springe (step into) hängt sich das Programm beim ersten 
WriteI2C1(MPU6050_ADDRESS); auf.

von Frank M. (frank_m35)


Lesenswert?

Irgendwie komisch, da der Befehl ja bei den Command Bytes schreiben 
funktioniert. Hast du die Idle Routinen eingefügt?
Vielleicht schreibst du auch bei den Command Bytes irgendetwas falsches, 
probiere einmal die unnötigen auszukommentieren und nur die aller 
wichtigsten (d.h. damit der IC angeschalten wird) einzubauen. Vielleicht 
ist er auch schon standarmäßig an und du musst vorerst gar kein Command 
Byte senden.
Und mach sicher, dass du hin und wieder auch die gesamte Stromversorgung 
trennst, damit sich der uC sowie die MPU komplett neu initialisieren 
muss und nicht noch irgendwelche falsche Informationen weiter verwendet.

Sorry, aber momentan wüsste ich sonst nicht was schief geht.

von M.H. (Gast)


Lesenswert?

Ich werde mir in den kommenden Tagen meine eigene I2C bibliothek 
schreiben, dann weis ich genau, was der pic macht. Ich werde bericht 
erstatten wenn ich fertig bin...
Was würde ihr bei der bibliothek mache, wenn z.B. kein ACK vom slave 
kommt?

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.