Hallo Zusammen, ich schreibe diesen neuen Beitrag nicht leichtfertig und habe bereits ausgiebig hier im Forum und via Google nach ähnlichem gesucht und einiges probiert: Ich versuche (vergeblich) über einen "nackten" ATMega88PA (1 Mhz getaktet) einen Feuchtigkeitssensor via TWI/I2C auszulesen. Vorweg: jegliche Probleme mit dem Sensor/Spannung oder den Leitungen kann ich ausschließen da ich probeweise mit einem Arduino UNO die Ansteuerung über dieselben Kabel erfolgreich hinbekomme (Ebenfalls mit 5V versorgt). Er bleibt bei folgendem Code immer in der letzten Zeile (wohl in einer Endlosschleife stecken: ... #define F_CPU 1000000UL #include <avr/io.h> #include "util/delay.h" #include "i2cmaster.h" ... PORTC |= (1 << 4); //pullups PORTC |= (1 << 5); while(1) { _delay_ms(500); i2c_init(); _delay_ms(50); i2c_stop(); _delay_ms(50); i2c_init(); _delay_ms(50); i2c_start_wait(0x51+I2C_WRITE); // <-- hier kommt er nicht mehr hin.... anstatt "0x51+I2C_WRITE" habe ich auch nur "0x51" oder dezimal ausprobiert. Ebenfalls habe ich etliche andere Code-Beispiele und Bibliotheken ausprobiert sogar eine simple eigene geschrieben. Immer ohne Erfolg. Die Delays und das 2malige i2c_init() habe ich zuletzt hinzugefügt weil hier im Forum jemand meinte, dass man auf diese Weise I2C Probleme umgehen könnte. Auch eine andere Adresse und einen Arduino als Slave habe ich probiert. Hier der Code der mit dem Arduino funktioniert bzw. den Sensor erfolgreich auslesen kann: ... delay(10); Wire.beginTransmission(0x51); Wire.write(0x0A); Wire.endTransmission(); Wire.requestFrom(0x51, 4); Serial.println("Lese Daten - sens:"); byte bytes[4]; for(byte i = 0; i <= sizeof(bytes); i++) if(Wire.available()) bytes[i]=Wire.read(); unsigned int Sensitivity = bytes[1] + (bytes[0] << 8); unsigned int Offset = bytes[3] + (bytes[2] << 8); ... Ich habe auch schon probiert den Code der von Arduino produziert wird möglichst 1:1 zu adaptieren und auf dem ATmega8 auszuführen (nat. ohne Erfolg) Hier mal der Assembler-Code in dem wohl bei der grade verwendeten Bibliothek die Endlosschleife steckt. (Wenn ich eine C-Bibliothek verwende steckt er dann nat. in der jew. anderen C-Bibliothek fest); .global i2c_start_wait .func i2c_start_wait i2c_start_wait: mov _tmp_reg_,r24 i2c_start_wait1: sbi SDA_DDR,SDA ;force SDA low rcall i2c_delay_T2 ;delay T/2 mov r24,__tmp_reg__ rcall i2c_write ;write address tst r24 ;if device not busy -> done breq i2c_start_wait_done rcall i2c_stop ;terminate write operation rjmp i2c_start_wait1 ;device busy, poll ack again i2c_start_wait_done: ret .endfunc ... Wenn ich das richtig verstehe (Vermutung), ist der Bus wohl andauernd Busy weshalb diese ewige Warterei passiert. Am Bus hängt sonst nichts. Also der Sensor ist mit 2 kurzen Drähten direkt verbunden. Bei anderen Bibliotheken habe ich zudem mit der Datenrate herum gespielt. Diese hier ist von Peter Fleury und scheint die Datenrate in Abhängigkeit der eingestellten Prozessortaktung selbst einzustellen (F_CPU steht bei mir auf 1 Mhz was überprüfterweise korrekt ist). Generell handelt es sich also nicht um ein sporadisches Problem (wie bei Anderen hier im Forum) sondern um etwas ganz grundsätzliches / immer auftretendes. Über Anregungen / Hinweise was ich noch machen könnte wäre ich seeehr Dankbar. Danke auch für das Durchlesen bis hierher ;-)
Vermuten kannst Du gerne was du willst, aber das bringt Dich nicht wweiter. Messe nach, ob der Bus in Ruhelage High Pegel auf beiden Leitungen führt. Das wäre mal der erste Schritt, um das Problem einzukreisen. Ich bezweifle, dass die internen Pull-Ups im I2C Betrieb wirksam sind. Denn im Datenblatt des mC steht: "The only external hard-ware needed to implement the bus is a single pull-up resistor for each of the TWI bus lines." Hast Du externe Pull-Up Widerstände in der Schaltung?
Hi >Ich bezweifle, dass die internen Pull-Ups im I2C Betrieb wirksam sind. >Denn im Datenblatt des mC steht: "The only external hard-ware needed to >implement the bus is a single pull-up resistor for each of the TWI bus >lines." Sind sie schon. Aber um einen Faktor >10 zu hochohmig. MfG Spess
Vielen Dank für die Anregung. Der SCL liegt bei 3,9V Der SDA liegt ebenfalls bei 3,9V Dies wird in Bezug zur Referenzspannung von 4,5V als HIGH gewertet. Dies gilt sowohl im Ruhezustand als auch wenn der obige Code abläuft in seiner Endlosschleife. Die Pullup-Setzung habe ich mir nicht ausgedacht sondern von anderen als funktionierend titulierten Beispielen abgekupfert. Zudem hatte der Arduino auch ohne extra Pullups keine Probleme. Dennoch werde ich das gleich noch ausprobieren (verspreche mir aber nix davon) Ist evtl. noch eine andere Idee vorhanden?
Hallo, hier die Beschreibung der Arduino Wire-Bibliothek: Es gibt sowohl 7-Bit als auch 8-Bit Versionen der I2C-Adressen. 7 Bit bezeichen die Geräteadresseund 8 Bit bestimmen, ob gelesen geschrieben wird. Die Wire-Library benutzt durchweg 7-Bit-Adressen. Wenn in einem Datenblatt oder einem Beispielcode 8-Bit-Adressen verwendet werden, kann man das niederwertigste Bit einfach löschen (z.B. durch Verschieben um ein Bit nach rechts), mit dem Ziel eine Adresse zwischen 0 und 127 zu erhalten. Die I2C-Bibliothek verlangt 8-bit Adressen d.h. 0x51 wird zu 0xA2 (1 Bit nach links geschoben). Diese muss verwendet werden.
Das mit der Adresse probier ich gleich noch aus vielen Dank. Ich hatte nun zudem die beiden I2C pins anlässlich des obigen Hinweises nochmal jeweils am Sensor und am ATMega8 mal separat vermessen (ohne angeschlossenen Kabel) dabei habe ich gesehen, dass der Sensor lediglich 1,2V liefert und der ATMega 4,8V. Kann/darf das überhaupt sein? Der Arduino läuft ja mit 5V und hatte damit ja scheinbar auch kein Problem. Der Sensort läuft generell mit 3,2 V Versorgung. Ist hier noch eine Verstärkerschaltung nötig? (Auch wenn ich mir nicht erklären kann wieso es dann am Arduino geklappt hat)
Hi >Die Pullup-Setzung habe ich mir nicht ausgedacht sondern von anderen als >funktionierend titulierten Beispielen abgekupfert. Zudem hatte der >Arduino auch ohne extra Pullups keine Probleme. Man sollte nicht jeden Dünnschiss aus dem Web glauben. Such mal nach UM10204. Das ist die I2C Spezifikation. MfG Dpess
Kannst du in deinen I2C Dateien mal nach deinem "ATMega88PA" suchen ? Glaube das der dort nirgendwo auftauchen wird.
ATMega88PA schrieb: > Kannst du in deinen I2C Dateien mal nach deinem "ATMega88PA" suchen ? > Glaube das der dort nirgendwo auftauchen wird. Ich verwende die neueste Version des Atmel Studios und konnte den korrekten Typ beim Anlegen des Projektes auswählen. Welche Dateien soll ich da nun konkret durchsuchen? Den Programm-Ordner des Atmel Studios?
Hab jetzt die Vorgeschlagenen Pullup-Widerstände dran. Hatte leider nur noch 18k Ohm (anstatt 4,7k) aber das sollte ja eig. dennoch ausreichen. ...immer noch ohne Veränderung / in Endlosschleife weil Leitung angeblich "Busy" (so war ja meine ursprüngliche Vermutung).
> dabei habe ich gesehen, dass der Sensor lediglich > 1,2V liefert und der ATMega 4,8V. Kann/darf das überhaupt sein? Ja das kann richtig sein. Es wäre auch richtig, wenn der Sensor gar keine Spannung liefert, denn das sollten eigentlich Open-Drain Ausgänge sein. Der High pegel ergibt sich durch die Pull-Up Widerstände, dier laut Deiner Meissung (3,9V statt 4,5V) eindeutig zu hochohmig sind. Wenn die Spannung schon in Ruhelage nicht ideal ist, dann wird sie es bei einigen hundert khz erst recht nicht sein. > immer noch ohne Veränderung / in Endlosschleife weil Leitung > angeblich "Busy" Welchen Pegel (bitte in Volt) haben die beiden Bus-Leitungen in diesem "Busy" Zustand?
> Der Sensor läuft generell mit 3,2 V Versorgung
Hat er denn 5V tolerante I/O Leitungen am Bus? Wenn nicht, dann kann es
so nicht funktionieren, dann brauchst Du Pegelweandler. Dazu gibt's in
diesem Forum einen eigenen Artikel).
Ich habe die Spannungsversorgung nun generell auf 3,3 V geändert. Also sowohl Sensor als auch ATMega8. Bei verbundenen I2C Leitungen Messe ich saubere 3,3 V. Pullupwiederstand ist auch vorhanden an jeder der beiden Leitungen. Ich messe zudem keinen Unterschied ob mein Programm im Ruhe-Modus läuft (am Anfang _delay_ms(500000);) oder ob er in seiner Endlosschleife hängt. Zudem konnte der Sensor mit einem Arduino ja sauber ausgelesen werden was ein Hardwareproblem unwahrscheinlich macht. Wie oben vorgeschlagen habe ich es auch mal mit einer "verschobenen" Adresse probiert. Ich komme jedoch nie über diese Zeile hinaus: i2c_start_wait( 0xA2 ); oder i2c_start_wait( 0x51 );
Habe das Problem gefunden! In dem Assembler-Code der I2C Bibliothek von Peter Fleury "i2cmaster.S" werden die Werte für SDA_PORT und SCL_PORT ohne check mittels "#ifndef" einfach mit falschen Werten überschrieben: #define SDA_PORT PORTD // SDA Port D #define SCL_PORT PORTD // SCL Port D Für einen ATMega liegen diese jedoch bekannterweise am Port C. Richtig ist also diese Datei direkt anzupassen wie folgt: #define SDA_PORT PORTC // SDA Port D #define SCL_PORT PORTC // SCL Port D Vielen Dank an Alle die mich hier unterstützt haben. Ich hoffe diese Lösung hilft jemanden Anderen der auch mal Tomaten auf den Augen hat ebenso weiter. Viele Grüße
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.