Hallo ihr schlauen Köpfe, Ich kämpfe gerade mit der Ansteuerung von 3 i2c slaves am Raspberry Pi. Vorab, das verwendete OS ist raspbmc, die i2c slaves hängen via ca. 12cm Leitung am PI, alle zusammen auf einer Platine. Pullups sind die des Pis an 3.3v. Folgende Problematik ergibt sich: Die slaves werden teilweise mit falschen Adressen detektiert. Folgende Adressen erhalte ich, in Klammern die Sollwerte: A) TDA8444 - 0x20 (0x40) B) TEA6420 - 0x4d (0x9a) C) RDA5807m - 0x10, 0x11, 0x60 (Korrekt) Dabei zeigt sich folgendes Verhalten der slaves: A) Ansteuerbar mit falscher Adresse, nur erkennbar bei 32kHz i2c frequenz B) Reagiert nicht auf i2C Kommandos C) übernimmt falsche Werte in seine Register (fehlerhafte Daten erhalten?) Wenn ich die Adresse nun binär betrachte, erscheint das Problem sichtbar zu sein: 01001101 4d 10011010 9a 00100000 20 01000000 40 Jeweils die letzte Stelle der Adresse fehlt, wobei sich mir die Frage stellt, ob das dann auch bei den zu übertragenden Daten stattfindet. Hat jemand eine grobe Idee was hier von Statten geht? Bin leicht irritiert von der Geschichte. Dank im Voraus, Phil
Die gefundenen Adressen sind schon richtig, wenn man Bit0(R/W Flag) nicht mitzählt. http://de.wikipedia.org/wiki/I2c
Wieder was gelernt, passt auch. Da IC A&B auch nur write only sind. Danke soweit. Gilt noch die Daten Problematik zu klären.
>Die gefundenen Adressen sind schon richtig, wenn man Bit0(R/W Flag) >nicht mitzählt. Ja, nur geben einige Hersteller die I2C Adresse inklusive R/W als 8Bit Wert an und andere ohne R/W als 7 Bit Adresse. Das Thema verfolgt wohl jeden der mal mit I2C zu tun hatte. Da konnte man sich wohl nicht einig werden. Aus meiner Sicht sollte man die, die die I2C Adresse als 7Bit Wert angeben eine Woche an den Pranger stellen und mit Scheisse bewerfen. Ich kenne keine Hardware wo man die I2C Adresse ohne R/W Bit reinschreiben kann. Dann kommen noch die Deppenprogrammierer bei denen man diese 7Bit Adresse als Parameter übergeben muss. In der Funktion wird dann Rechenzeit vergeudet um diese Adresse noch mal 1 nach links zu schieben und das RW einzufügen. Pranger, eine Woche lang mit Scheisse bewerfen;)
holger schrieb: > Aus meiner Sicht sollte man die, die die I2C Adresse als > 7Bit Wert angeben eine Woche an den Pranger stellen > und mit Scheisse bewerfen. Dann fang mal mit den I2C Erfindern an MfG Klaus
Wieso Deppenprogrammierer? Sorry, aber die I2C Adressen sind 7 Bit groß, also Werte von 0-127 (abzüglich der reservierten). Eine Funktion, die diese Adresse als Argument verwendet, soll also meiner Meinung nach mit Werten von 0-127 aufgerufen werden. Dabei spielt es überhaupt keine Rolle, wie breit die Variablen oder Register sind. Angenommen eine Ampel kann die Zustände 0 - 3 und ich stelle Dir eine Funktion zur Verfügung, mit der du den Zustand setzen kannst:
1 | #define GELB 1 |
2 | #define ROT 2 |
3 | #define ROTGELB 3 |
4 | #define GRUEN 0 |
5 | |
6 | void setze(int zustand) |
Würdest Du dann nicht ebenfalls davon ausgehen, dass die Funktion mit Werten von 0-3 aufgerufen werden muss? Un nun verrate ich Dir ein Hardware-Detail: Port B3 = gelb Port B4 = rot Grün = NOR gatter an Port B3 und B4. Würdest Du jetzt die Funktion lieber mit den Werten 8, 16, 24 und 0 aufrufen? Falls ja, was passiert, wenn ich mir eine andere Pinbelegung ausdenke? Beim Versuch, möglichst kompakten Code zu erzeugen leidet sehr schnell die Lesbarkeit oder die Erweiterbarkeit. Denke mal darüber nach!
> In der Funktion wird dann Rechenzeit vergeudet um > diese Adresse noch mal 1 nach links zu schieben und das RW einzufügen. Das ist Unsinn. Denn du musst in den allermeisten Fällen zeurst die Adresse mit R/W=Low senden. Um dieses Low sicherzustellen kannst Du schieben oder das Bit löschen - in beiden Fällen brauchst Du einen Befehl. Und selbst wenn du auf das Löschen verzichtest: Es ist nur ein Befehl! Wen interessiert es, ob das Programm einen Befehl mehr oder weniger enthält? Falls es Dich interessiert, warum verwendest Du dann überhaupt I2C? Es gibt effiientere Protokolle, die weniger Code erfordern.
>> In der Funktion wird dann Rechenzeit vergeudet um >> diese Adresse noch mal 1 nach links zu schieben und das RW einzufügen. >Das ist Unsinn. Denn du musst in den allermeisten Fällen zeurst die >Adresse mit R/W=Low senden. Um dieses Low sicherzustellen kannst Du >schieben oder das Bit löschen - in beiden Fällen brauchst Du einen >Befehl. Was ist daran Unsinn? Du hast nicht verstanden was ich geschrieben habe. >Dann kommen noch die Deppenprogrammierer bei denen >man diese 7Bit Adresse als Parameter übergeben muss. Der TO schrieb oben: >Folgende Adressen erhalte ich, in Klammern >die Sollwerte: >A) TDA8444 - 0x20 (0x40) In seinem Datenblatt steht 0x40 als I2C Adresse. Also der 8Bit Wert den man auf dem Bus sieht. Für lesen oder schreiben ist es dann halt 0x40 und 0x41 oder umgekehrt. Übergeben muss er aber 0x20. Nehm ich dann mal einen PIC muss man diese 0x20 eins nach links schieben und das R/W an D0 einfügen. Dann kann ich das in SSPBUF schreiben. Beim AVR und TWDR genau das gleiche. Eine völlig überflüssige Schieberei wenn man die I2C Adresse gleich als 8Bit inklusive R/W Bit betrachtet.
Hallo Philipp, mal die Adressgeschichte beiseite, die Probleme mit der Datenübertragung sind natürlich viel gravierender. Bei Raspberry Pi und I2C solltest du http://www.raspberrypi.org/phpBB3/viewtopic.php?f=44&t=13771 beachten. Ursprünglich war Gert der Meinung, der Fehler trete nur in bestimmten Situationen auf und sei umgehbar. Nach meinem (und anderen, siehe auch http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html) Berichten ist aber klar, dass es keinen einfachen Workaround gibt. Könnte das die Ursache auch deiner Probleme sein? Bei mir ist der Fall nur relativ selten (alle 5 Sekunden oder so bei Übertragungen alle 10ms) aufgetreten ... LG, Sebastian
Hallochen, das Clockstretchingproblem ist mir auch bereits zu Ohren gekommen, deswegen habe ich gerade mal versucht mit meinen beschränkten Mitteln (RFT EO213 Analog-oszi) die Clockleitung zu untersuchen. Das ging mittels Dauersendung von write Befehlen ausgezeichnet. Mit dem Ergebnis: Die Clock-Leitung ist beim Adressieren des TEA6420 und beim RDA5807m komplett normal, gute Flanken und keine verkürzten Taktzyklen. Also muss das Problem scheinbar anderswo zu suchen sein. Vielleicht interpretiere ich auch das Datenblatt falsch. Laut der dem Auszug aus dem Datenblatt oben, würde ich wie folgt vorgehen: Derzeitig liegt am Ausgang-1 Eingang-5 an (Standard nach Power-Up-Reset) mitsamt Testsignal. Ich möchte Ausgang-1 zum Test mit 0dB Verstärkung auf Mute setzen. Aus der Tabelle interpretiere ich hierfür den Binärwert 00000101. Hexadezimal also 5. Mein Kommando sieht dann demnach so aus: i2cset -y 1 0x4d 0x05 Leider tut sich dabei gar nichts, der Ausgang bleibt immernoch auf Eingang 5. Habe ich hier irgendeinen Denkfehler? Grüße, Phil
Philipp M. schrieb: > Ich möchte Ausgang-1 zum Test mit 0dB Verstärkung auf Mute setzen. Aus > der Tabelle interpretiere ich hierfür den Binärwert 00000101. > Hexadezimal also 5. Da sind aber 6dB gain mit drin, oder? Ich komme bei 0dB gain auf 0 00 11 101, als 0x1D. Philipp M. schrieb: > i2cset -y 1 0x4d 0x05 Paasiert auf Adresse 0x4C ebenfalls nichts? Was sagt denn i2cdetect? LG, Sebastian
I2cdetect screenshot im Anhang, Adresse 0x4c gibt einen Write-error. Ja, ich habe mich oben vertan, hatte versehentlich 6db genommen. Spiegelverkehrtes auf die Anschlussbelegung lässt grüßen. Tatsächlich hing der Verstärker für das Signal auf Ausgang 4. Funktioniert jetzt :) Vielen Dank dennoch für die hilfreichen Informationen und Hilfe :)
:
Bearbeitet durch User
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.