Forum: Mikrocontroller und Digitale Elektronik Mikrokontroller hängt sich nach I2C Kommunikation auf


von Matthias K. (bartimaeus)


Angehängte Dateien:

Lesenswert?

Hallo liebe Community
Ich hab da mal wieder ein Problem...

Zuerst meinen Sourcecode, den ich verwende:
http://pastebin.com/jLUTKng1

Und der I2C Treiber von Atmel für ATXmegas:
http://www.atmel.com/Images/AVR1308.zip

Datenblatt zum MPU-6050:
http://invensense.com/mems/gyro/documents/PS-MPU-6000A.pdf
http://invensense.com/mems/gyro/documents/RM-MPU-6000A.pdf

Ich versuche gerade aus einem Beschleunigungssensor MPU6050 mit einem 
ATXmega32A4U das WHO_AM_I Register über I2C auszulesen um zu testen ob 
die Kommunikation zwischen den Bausteinen funktioniert. Das WHO_AM_I 
Register enthält standardmäßig den Wert 0x68 und befindet sich an 
Adresse 0x75.

Um I2C benutzen zu können, verwende ich den originalen TWI-Treiber von 
Atmel (link am Anfang). Mit diesem Treiber ist es relativ einfach eine 
Kommunikation aufzubauen.

Dass die Kommunikation funktioniert, kann ich mit Gewissheit sagen, da 
ich einen Logic Analyzer ausgeliehen bekommen habe, der mir genau die 
gewünschten Werte aufzeichnet (siehe Anhang). Der Ablauf der Signale 
stimmt mit dem Protokoll überein, das der MPU-6050 benötigt (Datenblatt 
MPU6050). Man sieht auch, dass der MPU6050 antwortet und den Wert 0x68 
zurückgibt.

Allerdings kommt dieser Wert nicht beim Mikrokontroller an 
(softwaretechnisch meine ich). In der Zeile 73 meines Codes wird der 
gelesene Wert (0x68) der Variable "val1" übergeben. Lese ich dann aber 
die Variable "val1" mit einem Debugger aus, so steht in ihr nichts drin. 
Der Wert wurde also nicht korrekt der Software übergeben. Und 
seltsamerweise hängt sich mein Mikrokontroller in der Zeile 73 auf, 
nachfolgende Befehle werden nicht mehr ausgeführt.

Woran könnte es also liegen, dass ich den Wert in der Software nicht 
erhalte und dass sich der Mikrokontroller aufhängt?

Sind die TWIE-Ausgänge in der Zeile 49-50 richtig initialisiert, oder 
muss ich TWIE-Ausgänge "besonders" initialiseren?

Ich freue mich über eure Antworten!

Viele Grüße
Matthias

von Matthias K. (bartimaeus)


Lesenswert?

Ok kleiner Nachtrag:
Der Mikrokontroller hängt sich nicht auf, es hatte nur so den Anschein. 
Wenn ich folgende Zeilen noch nach der Variablenübergabe schreibe, 
werden diese auch noch ausgeführt. Allerdings liefert die Abfrage in der 
if-Anweisung kein true. "val1" hat also immer noch nicht den richtigen 
Wert gespeichert...
1
val1 = twiMaster.readData[0];
2
3
if (val1 == 0x68)
4
{
5
  PORTE.OUTSET |= (1<<PIN2);
6
}

von Matthias K. (bartimaeus)


Lesenswert?

Hat jemand eine Idee oder Erfahrungen mit dem I2C Treiber von Atmel?

von Tim (Gast)


Lesenswert?

>Hat jemand eine Idee oder Erfahrungen mit dem I2C Treiber von Atmel?

Erfahrung nicht (habe das was eigens Programmiert), aber eine Idee:
Der Treiber Arbeitet doch IRQ bassiert....
Ergo musst du warten bis er fertig ist.
Und genau das findet sich auch in der twi_example.c von atmel:
1
while (twiMaster.status != TWIM_STATUS_READY){
2
    /* Wait until transaction is complete.*/
3
};
Nur bei dir nicht.
Du hast das twiMaster.readData[0] einfach nur zu früh ausgelesen...

von Stefan F. (sfrings)


Lesenswert?

Lies lieber das Datenblatt und implementiere eine eigene Prozedur 
passend zu Deiner Anwendung. Von der Atmel Variante kann man im 
Zweifelsfall abgucken, wenn mal ein Detail aus dem Datenblatt unklar 
ist. Du könntest auch die von mir in der Codesammlung veröffentlichte 
I2C Prozedur ausprobieren. Sie ist minimalistisch, aber gerade deswegen 
einfach anzuwenden und leicht nachzuvollziehen.

Beitrag "universelle I2C Master Prozedur für AVR"

von Matthias K. (bartimaeus)


Lesenswert?

Tim schrieb:
>>Hat jemand eine Idee oder Erfahrungen mit dem I2C Treiber von Atmel?
>
> Erfahrung nicht (habe das was eigens Programmiert), aber eine Idee:
> Der Treiber Arbeitet doch IRQ bassiert....
> Ergo musst du warten bis er fertig ist.
> Und genau das findet sich auch in der twi_example.c von atmel:
>
1
> while (twiMaster.status != TWIM_STATUS_READY){
2
>     /* Wait until transaction is complete.*/
3
> };
4
>
> Nur bei dir nicht.
> Du hast das twiMaster.readData[0] einfach nur zu früh ausgelesen...

Super! Vielen Dank! Da hätte ich auch selbst draufkommen können! Jetzt 
funktioniert es :)

@Stefan Frings: Danke für die Antwort. Ich schau dein Code auch mal an 
und implementier ihn vielleicht.

Danke an euch alle!

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.