Forum: Mikrocontroller und Digitale Elektronik Atmega8 - Sesnoren via I2C auslesen scheitert


von Thomas F. (thomas41587)


Lesenswert?

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!

von spess53 (Gast)


Lesenswert?

Hi

>im Rahmen eines kleinen Projektes muss ich mit einem Atmega8 einige I2C
Sensoren auslesen.

Und welche?

MfG Spess

von Jim M. (turboj)


Lesenswert?

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.

von Thomas F. (thomas41587)


Lesenswert?

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 :-)

von spess53 (Gast)


Lesenswert?

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

von Thomas F. (thomas41587)


Lesenswert?

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

von Wolfgang (Gast)


Lesenswert?

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.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

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

von Wolfgang (Gast)


Lesenswert?

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

von Wolfgang (Gast)


Angehängte Dateien:

Lesenswert?

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

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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
von grundschüler (Gast)


Lesenswert?

Patrick J. schrieb:
> Anschließend wird noch 'I2C_WRITE' dazu addiert, was eine 1 ist.

nein, 0
read ist 1

von Wolfgang (Gast)


Lesenswert?

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).

von Wolfgang (Gast)


Lesenswert?

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.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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

von Wolfgang (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.