Hallo zusammen, im Rahmen eines kleinen Projektes muss ich mit einem Atmega8 einige I2C Sensoren auslesen. Als Bibliothek nutze ich "Peter Fleury's AVR I2C Library", welche ich über dieses Forum gefunden habe. Den Port habe ich entsprechend des Atmega8 von D auf C geändert. Verkabelung inkl. Pullup Widerstände sollten auch passen (Auslesen der gleichen Sensoren testweise mit dem Raspberry Pi hat funktioniert). Trotzdem bekomme ich bei dem Aufruf von "i2c_start(0x77+I2C_WRITE)" immer eine 1 zurück, die mir laut Doku sagen soll, dass etwas schief gelaufen ist. Der relevante Code-Teil: i2c_init(); ret = i2c_start(0x77+I2C_READ); if ( ret ) { i2c_stop(); LcdAusgabe("Sensor N/A", 1); _delay_ms(1000); } else{ i2c_stop(); LcdAusgabe("Sensor verfuegbar", 1); _delay_ms(1000); } Ich weiß leider absolut nicht weiter und habe auch mehrere meiner Sensoren probiert, immer wieder das gleiche. Kann mir hier jemand weiter helfen? Falls benötigt kann ich auch gerne den gesamten Code hochladen... Vielen Dank jetzt schon!
Hi
>im Rahmen eines kleinen Projektes muss ich mit einem Atmega8 einige I2C
Sensoren auslesen.
Und welche?
MfG Spess
Thomas F. schrieb: > "i2c_start(0x77+I2C_WRITE)" Kann nicht korrekt sein, das Low Bit ist in der Addresse gesetzt. Versuche es mal mit:
1 | i2c_start((0x77<<1)+I2C_WRITE); |
Man sollte sich daran erinnern, das I²C Addressen nur 7 Bit breit sind.
spess53 schrieb: > Hi > >>im Rahmen eines kleinen Projektes muss ich mit einem Atmega8 einige I2C > Sensoren auslesen. > > Und welche? > > MfG Spess Unter anderem der BMP180, TSL2561, SHT21... Jim M. schrieb: > ersuche es mal mit: > i2c_start((0x77<<1)+I2C_WRITE); > > Man sollte sich daran erinnern, das I²C Addressen nur 7 Bit breit sind. Wow, das ging jetzt schnell und war direkt richtig! Vielen vielen dank dafür! Daran hätte ich noch ewig gesucht, da ich den Aufruf aus den Beispieldaten übernommen habe (in dem es offensichtlich dann auch falsch ist). Allerdings komme ich jetzt mit meinem Verständnis nicht ganz hinterher... 0x77 ist die Addresse des Sensors. Aber was bewirkt "<<1"? und das "+I2C_WRITE" macht ja eigentlich nur "+1", somit könnte ich den Wert doch direkt um 1 erhöhen, oder sehe ich das falsch? Sorry für die vielen Fragen, aber natürlich versuche ich bei dem ganzen auch was zu lernen, anstatt nur abzuschreiben :-)
HI >Kann nicht korrekt sein, das Low Bit ist in der Addresse gesetzt. >Versuche es mal mit: >i2c_start((0x77<<1)+I2C_WRITE); Woher wißt du, das das die ensprechenden Bibliotheken nicht selbst machen? MfG Spess
spess53 schrieb: > Woher wißt du, das das die ensprechenden Bibliotheken nicht selbst > machen? > > MfG Spess Da die vorgeschlagene Lösung direkt funktioniert hat, gehe ich mal davon aus, dass es passt
Thomas F. schrieb: > 0x77 ist die Addresse des Sensors. Aber was bewirkt "<<1"? Nimm dir ein C-Buch > und das "+I2C_WRITE" macht ja eigentlich nur "+1", somit könnte ich den > Wert doch direkt um 1 erhöhen, oder sehe ich das falsch? <ironie>Magic Numbers im Quellcode sind etwas wunderbares.</ironie> Versuche solchen Code mal nach einer längeren Schaffenspause wieder zu verstehen bzw. darin zielgerichtet etwas zu ändern.
Hi Was man Dir zu sagen versucht: Die 0x77 in Deinem Code sind aktuell die 'normale' Adresse Deines Sensor. Diese wird um 1 Bit nach links geschoben (<<1), was gleichbedeutend ist mit 'Mal Zwei'. Anschließend wird noch 'I2C_WRITE' dazu addiert, was eine 1 ist. Hintergrund: Das kleinste Bit gibt beim I2C an, ob LESEND oder SCHREIBEND auf den Slave zugegriffen wird. Bei Lesend ist das Bit eine 0 (man muß also Nix addieren, die Adresse passt, sofern die 'normale' Adresse um 1 Bit nach Links geschoben wurde). Beim Schreiben muß dieses Bit eine 1 sein. Nun kann man da '+1' hinschreiben, oder direkt als Adresse '0xEF' schreiben (wäre 0x77 x 2 + 1) - was Du aber in drei Wochen selber nicht mehr verstehen wirst, warum nun gerade hier ein EF steht, wo doch des Sensor 77 wäre und was der ganze Müll eigentlich bewirken soll. An Deiner Stelle würde ich auch die Sensor-ID als Konstante definieren, aks 'BMP = 0x77 << 1' - wodurch Du die Basis-Adresse bereits fertig hast. Zum Schreiben wird noch 'I2X_WRITE' addiert (oder ver-oder-t) und Du hast die 'Schreib-ID' des Sensor. MfG
Patrick J. schrieb: > An Deiner Stelle würde ich auch die Sensor-ID als Konstante definieren, > aks 'BMP = 0x77 << 1' - wodurch Du die Basis-Adresse bereits fertig > hast. Welchen Vorteil bietet es, nicht die eigentliche I2C-Adresse des Sensors, sondern eine daraus berechnete Größe als Konstante zu spezifizieren und das Verrechnungsergebnis auch noch als Adresse zu benennen. Heutige Compiler bekommen es durchaus hin, zwei Konstanten mit einander zu verknüpfen, ohne dass es zur Laufzeit irgendeinen Nachteil gegenüber irgendwelchen vorverrechneten Größen gibt. Die I2C-Adresse ist in der I2C-Spezifikation von Philips nun mal als 7 Bit Wert definiert und wenn nicht immer wieder irgendwelche Schlaumeier meinten, das erste Byte der Übertragung als Adresse bezeichnen zu müssen, gäbe es dieses ewige Verwirrspiel nicht. http://i2c2p.twibright.com/spec/i2c.pdf
p.s. Das Verwirrspiel reicht inzwischen so weit, dass beispielsweise nicht einmal mehr die Verfasser des Datenblattes vom BMP180 bei Bosch Sensortec in der Lage sind, die Begriffe vernünftig zu verwenden. Im Datenblatt auf S.20 unter 5.2. wird die Adresse mit 8-Bit Werten angegeben ("...corresponding to address 0xEF (read) and 0xEE (write)."), während in der Abbildung 7 darunter der Aufbau einer I2C-Übertragen eine 7-Bit Adresse zeigt. https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP180-DS000-121.pdf
Wolfgang schrieb: > Die I2C-Adresse ist in der I2C-Spezifikation von Philips nun mal als 7 > Bit Wert definiert a) Philips ist nicht der einzige Hersteller b) Es sind zwar 7 bit, aber die oberen 7 bit. > und wenn nicht immer wieder irgendwelche Schlaumeier > meinten, das erste Byte der Übertragung als Adresse bezeichnen zu > müssen, gäbe es dieses ewige Verwirrspiel nicht. Genau. Warum reitest du und andere Schlaumeier immer wieder darauf rum ? Lass die Leute doch beide Varianten ausprobieren. P.S. Da es um ATMEL geht... ATMEL sagt folgendes:
1 | EEPROM requires an 8-bit device address word following a start condition to |
2 | enable the chip for a read or write operation |
Und noch:
1 | The eighth bit of the device address is the read/write operation select bit. |
2 | A read operation is initiated if this bit is high and a write operation is initiated if this bit is low. |
Ergo, lass es sein, es genügt vollkommen wenn man den Fragesteller ganz einfach fragt, ob er die Adresse nach links geschoben hat oder nicht, anstatt nutzlose Beiträge über Sinn oder Unsinn verschiedener Adressierungsarten und Bezeichnungen zu posten.
:
Bearbeitet durch User
Patrick J. schrieb: > Anschließend wird noch 'I2C_WRITE' dazu addiert, was eine 1 ist. nein, 0 read ist 1
Marc V. schrieb: > a) Philips ist nicht der einzige Hersteller Aber der Erfinder, der damit auch die Spezifikation als erster festgeschrieben hat. Bosch Sensortec könnte sich die aus der I2C-Spezifikation von Philips kopierte Fig.10 (S.13) vom I2C-Datentransfer (BMP180 DS Fig.7) wenigstens mal verinnerlichen, wenn sie schon keine Quelle angeben (Copy&Paste, ohne Verstand).
Marc V. schrieb: > Da es um ATMEL geht... > ATMEL sagt folgendes:EEPROM requires an 8-bit device address word > following a start condition to > enable the chip for a read or write operation Nur besitzen die EEPROMs von ATMEL keinen I2C-Bus - oder liest du davon irgendwo etwas im Datenblatt. Folglich hat die I2C-Spezifikation bzgl. der Definition der Adressen auch nichts mit deren Protokoll zu tun. Dass das Atmel-Protokoll "zufällig" genauso funkioniert, wie der I2C-Bus von Philips, ist ein anderes Thema.
Hi grundschüler schrieb: > Patrick J. schrieb: >> Anschließend wird noch 'I2C_WRITE' dazu addiert, was eine 1 ist. > > nein, 0 > read ist 1 Wo Du es schreibst - aber dann ergibt Das ja noch weniger Sinn :) - also extra hier eine Konstante addieren, da man ja schreiben will, wofür man ja aber Nichts ändern muß. Da muß dann aber auch die Konstante 'I2C_READ' auf 1 gesetzt sein. Sinniger wäre es dann hier, Read auf 1 zu belassen und die 'Basis-Adresse' damit zu ver-oder-n, und Write zu 0xFE, und die 'Basisadresse' zu ver-and-en. Alles aber nicht wirklich geradelinig. Wie schon geschrieben wurde und es auch in jedem Datenblatt steht: 7Bit Adresse, 1Bit Richtung, und jetzt noch schön auf's ACK warten ;) MfG
Hi >Nur besitzen die EEPROMs von ATMEL keinen I2C-Bus - oder liest du davon >irgendwo etwas im Datenblatt. Seit wann gibt es keine EEPROMs mit I2C von Atmel? MfG Spess
spess53 schrieb: > Seit wann gibt es keine EEPROMs mit I2C von Atmel? Die EEPROMs von Atmel besitzen ein "2-Wire Serial Interface" und kein "I2C Interface". Oder kennst du ein Datenblatt von denen, wo etwas von I2C steht? ;-) Marc spielte auf die unterschiedlichen Definitionen der Adresse in den "beiden" Protokollen an.
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.