Forum: Mikrocontroller und Digitale Elektronik I2C-Kommunikation


von Florian K. (f-kae)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

mal wieder habe ich ein Problem mit der Kommunikation über I2C.

Ich möchte ein ID-Register eines Sensors auslesen.
Der Sensor (HMC5883) hat die Device-adresse: 0x3C
Das auszulesende Register liegt in: 0x0A

Ich habe mich bis jetzt sehr wenig mit der hardwarenahen Programmierung 
beschäftigen müssen, sondern habe die meisten Funktionen aus 
Bibliotheken benutzt. Daher fällt es mir nun schwer das Problem 
einzugrenzen.

Ich erwarte als Antwort den Wert 0x48 aus dem Register.

Ich bekomme allerdings 0x3D zurück. Das wird wohl die Deviceadresse + 
das Readbit sein. Entspricht das auch dem Oszi-Bild? Ich habe mal 
eingetragen, was ich daraus lese, leider weiß ich nicht was der letzte 
Teil soll (bzw wo der herkommt), oder ob dort eventuell sogar 0x48 drin 
steckt und ich nur die Antwort vom Sensor falsch entziffere...

Die Bitbreite beträgt 2,5us (400kHz).

Viele Grüße,
Florian
1
uint8_t device = 0x3C;
2
uint8_t addr = 0x0A; //id in Register is: 0x48
3
uint8_t id;
4
5
I2C1BUS::write_read(device, &addr, 1, &id, 1); // Erklärung:(uint8_t address, const uint8_t * writeBuffer, uint8_t writeSize, uint8_t * readBuffer, uint8_t readSize)
6
XPCC_LOG_DEBUG << "NACHER: " << (int)id << xpcc::endl;

von Lukas D. (lukas_d)


Lesenswert?

Hi,

Also nach 0x48 sieht das 4. Byte jedenfalls nicht aus, eher 0x91. Auf 
die Adresse antwortet der HMC schon mit einem Not Acknowlege. Er erkennt 
also die gesendete Adresse schon nicht.

Entweder...

dein Code ist nicht richtig. Werde aus dem obigen Code aber nicht 
wirklich schlau.

... oder

Im Datenblatt steht genauer beschrieben wie du ein Register auswählen 
musst um es anschließend auslesen zu können (S. 11). Wenn ich das 
richtig verstehe muss du die 7-Bitadresse 0x1E (S.7) zur Registerauswahl 
sowie zum lesen/ schreiben des Registers nehmen.

Würde dann so im Oszi aussehen:
Start 0x1E 0x0A Restart 0x1F .x.. Stop

Mit der 0x3C bzw 0x3D kannst du den Register-Pointer auf ein Register 
setzen aber zusätzlich kein Byte lesen/schreiben.

Würde dann so im Oszi aussehen:
Start 0x3C 0x0A Stop

Es wäre gut bei so einem I2C-Oszi Bild das Clock Signal zu sehen da es 
leichter ist die Bytes zu erkennen. Für die Kommunikation würde ich auch 
eine Geschwindigkeit von 100 kHz einstellen.

MfG

: Bearbeitet durch User
von Frank M. (frank_m35)


Lesenswert?

Ein voll funktionsfähiger Code:
Beitrag "Re: Problem mit Kompass Achsen (Mega644p + HMC5883L)"
Zwar nicht in deiner eigenartigen Sprache, sondern halt in normalem C.

Funktioniert denn ein anderes I2C Device? Schon Erfahrung mit I2C oder 
ist es das erste mal. Stimm deine Initialisierung?

von Florian K. (f-kae)


Angehängte Dateien:

Lesenswert?

Lukas D. schrieb:
> Es wäre gut bei so einem I2C-Oszi Bild das Clock Signal zu sehen da es
> leichter ist die Bytes zu erkennen. Für die Kommunikation würde ich auch
> eine Geschwindigkeit von 100 kHz einstellen.
>
> MfG

Entschuldigt meine lange Abwesenheit. Leider war ich die letzten Tage 
verhindert. Vielen Dank für die Antworten...
Ja, das Clock-Signal macht in der Tat Sinn!

Ich habe den gleichen Code wie nun vor einem halben Jahr schon 
funktionsfähig benutzt und nun ein Update der Bibliothek verwendet, die 
entscheidenden I2C-Funktionen haben sich aber "meiner Recherche nach" 
nicht verändert! Ausserdem habe ich eine neue Platine geroutet und 
herstellen lassen. Auch mein Barometer hat Probleme beim ID-Check.

Damals hat mein Code funktioniert. Interessanterweise kann ich, wenn ich 
den ID-Check am anfang überspringe das Magnetometer "normal" nutzen, das 
heißt eine Funktion zum suchen der Min und Max Werte laufen lassen und 
per Bluetooth an den PC zu senden. Also auslesen der x,y,z Register.

Frank M. schrieb:
> Ein voll funktionsfähiger Code:
> Beitrag "Re: Problem mit Kompass Achsen (Mega644p + HMC5883L)"
> Zwar nicht in deiner eigenartigen Sprache, sondern halt in normalem C.
>
> Funktioniert denn ein anderes I2C Device? Schon Erfahrung mit I2C oder
> ist es das erste mal. Stimm deine Initialisierung?

Danke für den Code ich habe mal drüber geschaut. Für mich wäre eine 
Auswertung des Signals wirklich sehr hilfreich, was genau passiert.

Wenn es hilft kann ich auch gerne meinen kompletten I2C-Code den ich 
nutze posten, ich hatte im Startpost versucht diesen, sogut wie möglich 
zu reduzieren...

EDIT: Ich habe mal noch eine Einteilung des Signals hochgeladen und die 
Stellen markiert in denen ich unsicher bin ob das eine normale 
I2C-Kommunikation ist. Vor allem vor und nach 0x3D.

Ach ja, also damals hat mein Code mit 0x3C als Device-Adresse zum Lesen 
und Schreiben funktioniert. Könnte hier wirklich das Problem liegen, 
dass ich 0x1E verwendet müsste?

: Bearbeitet durch User
von Lukas D. (lukas_d)


Lesenswert?

>Ich habe den gleichen Code wie nun vor einem halben Jahr schon
>funktionsfähig benutzt und nun ein Update der Bibliothek verwendet, die
>entscheidenden I2C-Funktionen haben sich aber "meiner Recherche nach"
>nicht verändert!

Welchen Prozessor verwendest du? Es kann durch aus sein, das sich in der 
neueren Bibliothek eine winzigkeit verändert hat. Zum Beispiel hatte ich 
mal das Problem das bei einem neueren Prozessor das Read-/Write-Bit "RW" 
oder "R_W" geschrieben werden konnte aber bei einer älteren Prozessor 
variante nur "RW" funktionierte.

>Für mich wäre eine Auswertung des Signals wirklich sehr hilfreich, was
>genau passiert.

Um es kurz an deiner Einteilung zu analysieren:

Startbedingung
Adresse (schreiben)
Notacknowlege       <--- komisch
Writedata
Acknowlege
Restartbedingung
Adresse (lesen)
Acknowlege
Readdata
Notacknowlege
Stopbedingung

Du solltest dir auf folgendem links mal die Basics zum I2C-Bus 
anschauen. Dann verstehst du ganz leicht was genau auf deinem 
Oszillogramm passiert.
http://www.rn-wissen.de/index.php/I2C

>Wenn es hilft kann ich auch gerne meinen kompletten I2C-Code den ich
>nutze posten

Ja gerne.

>Ach ja, also damals hat mein Code mit 0x3C als Device-Adresse zum Lesen
>und Schreiben funktioniert. Könnte hier wirklich das Problem liegen,
>dass ich 0x1E verwendet müsste?

Wie schon geschrieben habe ich das so zumindest im Datenblatt 
verstanden. Einfach nochmal nachprüfen oder ausprobieren.

von Wolfgang (Gast)


Lesenswert?

In IMHO wirklich jedem Datenblatt von Bauteilen mit I2C-Schnittstelle 
ist das Protokoll ausführlich dargestellt. Hast du dein Signal damit 
schon mal verglichen? Bei der Fehlersuche helfen kleine Widerstände 
zwischen dem SDA-Pullup und den I2C-Kommunikationspartnern, damit man 
sehen kann, wer die Leitung runter zieht.

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.