Forum: Mikrocontroller und Digitale Elektronik Kein stop condition bei I2C


von franzlst (Gast)


Lesenswert?

Moin,

ich habe am RN-Mega128Funk 
http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=64&products_id=158 
das RN-KeyLCD 
http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=66&products_id=81 
angeschlossen (als einziges Modul an den I2C Ausgängen).
Bereits vor ein paar Wochen habe ich Funktionen zur Ansteuerung 
geschrieben. Als I2C Bibliothek nutze ich diese: 
http://homepage.hispeed.ch/peterfleury/avr-software.html#libs

Meine Funktionen haben auch die ganze Zeit funktioniert, jetzt passt 
aber etwas nicht mehr, obwohl ich keine Änderung vorgenommen habe. Und 
zwar kann ich die Kommunikation starten (i2c_start(...)) und dann zB 
Zeichen übermitteln (beliebig viele, i2c_write(...)), dann scheint 
allerdings die Kommunikation mit i2c_stop nicht wieder beendet werden, 
da jeder Befehl, der im Programm danach folgt, nicht mehr ausgeführt 
wird.

Die Funktion i2c_stop sieht folgendermaßen aus:
1
/*************************************************************************
2
 Terminates the data transfer and releases the I2C bus
3
*************************************************************************/
4
void i2c_stop(void)
5
{
6
    /* send stop condition */
7
   TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
8
   
9
   // wait until stop condition is executed and bus released
10
   while(TWCR & (1<<TWSTO));
11
12
}/* i2c_stop */
Also wird anscheinend die "stop condition" irgendwie nicht ausgeführt, 
da das die einzige Schleife ist, die nicht verlassen werden könnte.

Jemand ne Ahnung, an was das liegen kann? Liegt es am RN-KeyLCD oder am 
µC?

Ich wäre über ne Hilfe echt froh

Danke

Franz

von Jörg X. (Gast)


Lesenswert?

Ich glaube, da musst du mehr Infos liefern, dein Code sieht ziemlich 
richtig aus
(auch wenn ich:
   while(! TWCR & ( 1 << TWINT)
schreiben würde, laut Datenblatt (des mega8, hab das vom 128er nicht da) 
sollte deine Variante aber auch gehen)

von Jörg X. (Gast)


Lesenswert?

upps da fehlen noch ");" damit niemand schimpft

von franzlst (Gast)


Lesenswert?

Ich habe jetzt deine Alternative ausprobiert:
Ergebnis: Nachkommende Befehle werden ausgeführt, das Display nimmt aber 
keine Zeichen mehr an.

Das Problem hat sich inzwischen als noch verzwickter herausgestellt, da 
es nicht mal mehr reproduzierbar ist.
Der µC hat ja 2 direkt parallel geschaltete I2C Ausgänge. An dem einen 
hängt das Display, an dem anderen 4 US-Sensoren (SRF02) und ein Kompass 
(CMPS03).

Zum Testen führe ich folgende Befehle aus:
1
mot_a_links(MAX_SPEED);
2
display_print_char('a');
3
display_print_char('b');
4
mot_b_rechts(MAX_SPEED);

Die Motorfunktionen spielen jetzt keine Rolle (dienen nur der optischen 
Kontrolle), der print Befehl sieht so aus:
1
void display_print_char(uint8_t zeichen)
2
{
3
  i2c_start(DISPLAY + I2C_WRITE);
4
  i2c_write(zeichen);
5
  i2c_stop();
6
}

Was beim Starten (Strom an) passiert scheint nun vom Zufall abzuhängen:
Manchmal bleibt der LCD beim Robotikhardware-Startbildschirm hängen, 
manchmal wird 'a' angezeigt. Motor A dreht sich immer. Eine weitere 
Zufallskomponente kommt dazu, wenn ich die Strippe mit den Sensoren 
wiederholz aus- und einstecke. Manchmal passiert dadurch gar nichts, 
manchmal wird die Anzeige gelöscht, manchmal erscheint dann statt dem 
Startbildschirm das 'a', manchmal kommt das 'b' hinzu und Motor B geht 
noch an, manchmal kommen gleich beide Buchstaben und beide Motoren 
springen an. Was ich noch festgestellt habe, ist dass wenn die Sensoren 
von Anfang an drangesteckt sind immer nur der Startbildschirm erscheint 
und kein 'a'.
Anscheinend hängt es davon ab, wie ich das Kabel der Sensoren ziehe.

Durch die veränderte i2c_stop Funktion werden nun beim Start, wenn die 
Sensoren abgesteckt sind, beide Motoren eingeschalten und 'a' wird 
angezeigt. Das Ein- und ausstecken der Sensoren scheint nichts mehr zu 
machen.

Ich bin hier echt fast am Verzweifeln, weil ich seit Stunden nicht 
weiterkomme. Und ich hasse den Zufall bei der Programmierung...

Danke

Franz

von Thomas (Gast)


Lesenswert?

Hast Du mal Deine Pull-ups überprüft ? Benutzt Du interne (µC) oder 
externe Pullups? Wie hoch ist der Widerstandswert ?

http:\\www.naventics.net

von Thomas (Gast)


Lesenswert?

Hast Du mal Deine Pull-ups überprüft ? Benutzt Du interne (µC) oder
externe Pullups? Wie hoch ist der Widerstandswert ?

http://www.naventics.net

von Jörg X. (Gast)


Lesenswert?

Klingt schon fast nach 'nem Hardware Problem (Abblock C, Pull-Up, 
Masserverbindung, etc.) ansonsten machst du dich vielleicht mal mit dem 
TWI-Status-Register vertraut ( falls es doch kein Hardware-Problem ist 
). Das Status reg. sollte dann "sagen", ob das Lcd-Modul etc. nicht 
antwortet, ob sich der mega128 aufhängt, usw..

hth

von Joerg W. (joergwolfram)


Lesenswert?

lass mal die while-Schleife weg. Soweit ich weiss, braucht man nach STOP 
nicht zu warten.

von Winne (Gast)


Lesenswert?

dito while schleife Hängt dein Programm auf. Siehe unten.

Alternativ zur "while schleife" kurz warten und prüfen ob SDA und SCL 
high sind.

wenn nicht hält wer fest am besten nen oszilloskop drann hängen.

Meines Wissens wird beim 128  nach der Stopcondition der TWI kein Flag 
gesetzt oder gelöscht, Sieh mal im Datasheet nach. Das Beispiel prüft 
den erfolg der stopcondition nicht. Ich hatte das auch versucht und mein 
Programm hatte sich in der gleichen Weise aufgehängt. Ohne prüfen weiter 
hat geholfen und funktioniert fehlerfrei.

von Michael U. (Gast)


Lesenswert?

Hallo,

hab jetzt nicht ins 128er Datenblatt geschaut, denke aber Atmel wird da 
auch beim Mega16 nicht weiter abweichen im Verhalten des TWI.

Stop setzt TWINT nicht zurück, TWSTO wird zurückgesetzt, wenn Stop 
abgearbeitet wurde.
Ich beutze es auch mit TWSTO-Abfrage ohne Probleme.
Wenn ich nicht auf das Ende von Stop warte, muß ich etliche Zeit warten, 
bis ich an den Bus wieder rankomme.

Ich würde vermuten, irgendeiner gibt den I2C-Bus nicht sauber frei, ich 
denke, der AVR wird bei Stop auch nur darauf warten, daß SDA und SCL 
wieder auf H sind.

Gruß aus Berlin
Michael

von Winne (Gast)


Lesenswert?

na dan n weist du j bescheid ;-)

such den strolch!

Und immer drann denken wer viel mist, mist viel Mist ;-))))))

aja: Leitunskapazität und Pullupgrösse ? (Tau?)



von franzlst (Gast)


Lesenswert?

Vielen Dank für die vielen Antworten. Ich habe jetzt angefangen nochmal 
etwas im Datenblatt zu lesen: 
http://www.atmel.com/dyn/resources/prod_documents/doc2467.pdf

Jetzt weiß ich (bzw glaub ich zu wissen ^^), dass weil ich nur einen 
Master habe, ich eigtl gar keinen stop Befehl brauche. Ich habe bei mir 
also sämtliche stop Befehle auskommentiert, womit die start Befehle zu 
repeated start Befehlen werden.

So funktioniert das jetzt alles prima bis jetzt, ich bin ja so froh :)

Beim Kompass habe ich festgestellt, dass das V_DD Kabel lose war, und 
somit dieser den Bus wohl immer blockiert hat, wenn die Sensoren 
angeschlossen waren.

Wenn ich mal etwas Zeit finde, werde ich wohl noch etwas weiterlesen, 
vllt finde ich noch herraus, warum das anfangs so funktioniert hat (mit 
stop) und jetzt nicht mehr.

Ach ja als PullUp hab ich nur die internen Widerstände, die betragen 
laut Datenblatt minimal 20 kOhm und maximal 50 kOhm (Datenblatt S. 322). 
Als Gymnasiast und Elektronikanfänger hat man leider zu Hause noch kein 
Oszilloskop rumfliegen ^^

Nochmal danke und einen schönen Aschermittwoch

Franz

von Michael U. (Gast)


Lesenswert?

Hallo,

Stop ist spätestens dann von Interesse, wenn ein Slave nicht alles 
mitbekommen hat. Dann kann der Bus ohne Stop blockiert bleiben.

Die inernen Pullup wären mir zu hochohmig, speziell wenn mehrere Sachen 
dranhängen und der Bus schneller als 100kHz gefahren wird.
Atmel gibt im Datenblatt min. rund 1,5k und die Maximalwerte enden auch 
so um die 3-10k je nach Rate und Kapazität.

Datenblatt Mega128 Seite 325 TWI Interface Characteristics.

Ich habe mit einem Slave und kurzer Verbindung (Steckbrett) meist 3,3k 
genommen.

Gruß aus Berlin
Michael

von franzlst (Gast)


Lesenswert?

Okay, nachdem das jetzt doch noch nicht 100% funktioniert hat, hab ich 
wieder etwas weitergelesen.

Bei der ursprünglichen while-Schleife wird ja auf das TWSTO Bit 
gewartet, dass das zurückgesetzt wird. Laut Datenblatt ist das richtig 
so:
"Bit 4 – TWSTO: TWI STOP Condition Bit
Writing the TWSTO bit to one in Master mode will generate a STOP 
condition on the Two-wire Serial Bus. When the STOP condition is 
executed on the bus, the TWSTO bit is cleared automatically"

Es scheint nicht am Display zu liegen, da auch beim Ultraschallsensor 
(als einziger am I2C Bus) dieses nicht gelöscht wird.

Deshalb jetzt ein paar Fragen zu den PullUp Widerständen:
Das Board hat ja 2 I2C Anschlüsse (die direkt miteinander verbunden 
sind). Müssen beide Anschlüsse die gleichen PullUp-Widerstände haben?
Laut Datenblatt ist der minimale Widerstand bei 5V Betriebsspannung etwa 
1,5 kOhm. Wie errechne ich jetzt aber für den maximalen Wert 
"capacitance of one bus line in pF"?
Wo werden die PullUps angelötet, direkt am I2C Ausgang? Oder benötigt 
jeder Slave seine eigenen Widerstände?
Die beiden Stränge sehen so aus:
1. Strang: 30cm Flachbandkabel, US-Sensor, 10cm Kabel, US-Sensor, 10cm 
Kabel, US-Sensor, 10cm Kabel, US-Sensor, 20cm Kabel, Kompasssensor.
2. Strang: 20cm Kabel, KeyLCD
RN-KeyLCD: http://www.robotikhardware.de/download/rnkeylcd1.2.pdf
US-Sensor: http://www.robotikhardware.de/download/srf02doku.pdf
Kompass: http://www.robotikhardware.de/download/cmps03kompass.pdf
(Wie kann man hier eigl Textlinks erstellen?)

Schonmal vielen Dank

Franz

von harti (Gast)


Lesenswert?

Hallo servas,
Also ist wahrscheinlich ein bisschen zu spät für eine Antwort, probiere 
es aber trotzdem.

Ich habe den gleichen Fehler gehabt (so bin ich auf den Eintrag 
gestoßen), und bin auch die Datenblätter durchgegangen.

Bei mir war der Fehler wie oben angedeutet, dass der Slave in meinem 
Fall der IC AD7156 den Bus nicht mehr "freigibt".
Genau die I2C Protokolle der ICs durchgehen!

Beschreibung:
---> Vor Stop Bedienung kein Acknowledg vom Master beim Empfangen von 
Daten vom SLAVE!
Ansonsten gibt der Baustein den Bus nicht mehr frei.
So sollts hinhaun!

Zum Thema Pull-Ups:
Verwende selber 47k Pull-Ups, und habe die Signale mit Oszi und 
Logicanalyser bei 10kHz (und 100kHz) durchgeprüft.,!
Stellt bei meinem Layout kein Problem da!

mfg harti

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.