Forum: Mikrocontroller und Digitale Elektronik I2C hängt sich auf


von Greenhorn (Gast)


Lesenswert?

Hallo zusammen,

ich habe mich in den letzten Wochen mit dem MSP430G2553 Launchpad 
vertraut gemacht und mich nun an I2C herangetastet. Dazu verwende ich 
zunächst TI Beispiele und spreche einen Sensor über I2C an.

Das funktioniert.

Aber, der MSP430 hängt sich willkürlich auf und beim Debuggen ist mir 
aufgefallen, dass er sich an folgender Stelle aufhängt, bzw. stehen 
bleibt.
1
while (UCB0CTL1 & UCTXSTP);                   // Ensure stop condition got sent

Ist das Problem anderen MSP430 Usern auch schon aufgefallen?

Beste Grüße,
Greenhorn

von Klaus R. (klara)


Lesenswert?

Greenhorn schrieb:
> Hallo zusammen,
>
> ich habe mich in den letzten Wochen mit dem MSP430G2553 Launchpad
> vertraut gemacht und mich nun an I2C herangetastet. Dazu verwende ich
> zunächst TI Beispiele und spreche einen Sensor über I2C an.
>
> Das funktioniert.
>
> Aber, der MSP430 hängt sich willkürlich auf ....

Mit welcher Taktfrequenz arbeitest Du am I2C-Bus?
Welche Leitungslänge?

Vielleicht ist Dein Sensor nicht so flot und versucht ein 
Clockstreching.
Verringere mal den I2C Takt auf die Hälfte.
mfg klaus

von Klaus (Gast)


Lesenswert?

Ohne jetzt die Signale auf deinem I2C Bus auf meinem Scope gesehen zu 
haben, vermute ich, daß der Slave SDA oder SCL oder beide auf low hält. 
Damit kommt kein gültiges Stop zustande.

Typische Gründe dafür sind nicht sauber zuende geführte Nachrichten: 
beim Lesen das letzte Byte nicht mit NACK quitiert oder beim Debuggen 
wurde ein Zyklus abgebrochen. Häufig liegt die Ursache eine Weile zurück 
und wird nicht erkannt, da das ACK vom Slave nie ausgewertet wird, und 
erstmal einen Weile in den klemmenden Bus gesendet wird.

MfG Klaus

Seh gerade, Clockfrequenz runtersetzen. Fehlt noch der Ratschlag mit 
kleiner Pullups. Beides kommt immer, hat aber bei 99% der Threads, die 
ich in Erinnerung habe, nicht geholfen.

von sdg (Gast)


Lesenswert?

I2C bei MSP430 lasse ich grundsätzlich nach dem start in der main mal 
die bits toggeln so 1000mal, ich hab das gefühl die hängen sich manchmal 
willkürlich auf und kommen nicht mehr zurück, hatte ich glaube auch so 
mal im e2e forum gelesen, bei mir hilft das sehr oft.

Dann ist natürlich wichtig was für einen I2C slave du dran hast und ob 
dort alles passt, ob die angesprochenen pullups an SDA und SCL sind und 
ich fange immer mit langsamen Taktfrequenzen an, falls ich Probleme 
habe, os hab ichs bisher immer irgendwann :) rausfinden können.

von Greenhorn (Gast)


Lesenswert?

Hallo zusammen,

danke für die hilfreichen Tipps. Ich habe eine Lösung gefunden. Nach der 
Initialisierung des I2C Moduls habe ich nun ein:
1
__delay_cycles(10000);

eingefügt.

Ich habe in einem anderen Forum gelesen, dass nach der Abarbeitung der 
Initialisierungsbefehle das Modul erst noch eine Zeit X benötigt um sich 
richtig zu initialisieren, während dessen das Programm aber schon den 
nächsten Befehl abarbeitet.

Lange Rede kurzer Sinn, das Problem ist seit dem nicht mehr aufgetaucht. 
Zumindest bis jetzt.

Beste Grüße,
Greenhorn

von Klaus (Gast)


Lesenswert?

sdg schrieb:
> I2C bei MSP430 lasse ich grundsätzlich nach dem start in der main mal
> die bits toggeln so 1000mal, ich hab das gefühl die hängen sich manchmal
> willkürlich auf und kommen nicht mehr zurück, hatte ich glaube auch so
> mal im e2e forum gelesen, bei mir hilft das sehr oft.

Hat mit MSPxx nichts zu tun. 8 mal mit SCL wackeln und dann prüfen, ob 
SCL und SDA high sind, ist die gängige Prozedur einen verklemmten I2C 
Bus zu reseten.

MfG Klaus

von Klaus R. (klara)


Lesenswert?

Klaus schrieb:
> sdg schrieb:
>> I2C bei MSP430 lasse ich grundsätzlich nach dem start in der main mal
>> die bits toggeln so 1000mal, ich hab das gefühl die hängen sich manchmal
>> willkürlich auf und kommen nicht mehr zurück, hatte ich glaube auch so
>> mal im e2e forum gelesen, bei mir hilft das sehr oft.
>
> Hat mit MSPxx nichts zu tun. 8 mal mit SCL wackeln und dann prüfen, ob
> SCL und SDA high sind, ist die gängige Prozedur einen verklemmten I2C
> Bus zu reseten.
>
Ich muss sagen, das klingt alles nach Voodoo. Ich habe vier I2C-Busse 
gesteuert über MSP430F2013 seit über 7 Jahren im Einsatz. So ein 
I2C-Slave ist ein ganz blöder Baustein, der wie eine Schaltuhr einer 
alten Waschmaschine arbeitet. Dementsprechend arbeiten auch die MSP430 
als I2C-Master. Die Signale des Slave werden über Interrupts erkannt und 
in einem Register festgehalten, wieder so ähnlich wie bei einer 
Schaltuhr einer alten Waschmaschine.

Also, man muss nicht erst "8 mal mit SCL wackeln und dann prüfen, ob SCL 
und SDA high sind", sondern ein I2C-Init (Start) und schon geht es los. 
So sollte es sein.

Nicht von ungefähr habe ich nach der Taktfrequenz des I2C-Busses 
gefragt. Auch nach der Leitungslänge. Der nächste Parameter wäre, sind 
mehrere I2C-Clients am Bus? Es geht hier um die Übertragungsparameter 
des I2C-Busses für die gewisse Grenzen, in der Hauptsache Leitungs- und 
Anschlusskapazitäten, einzuhalten sind. Hierzu siehe die "philips i2c 
specification".

http://www.nxp.com/documents/user_manual/UM10204.pdf

....

So, ich habe die aktuelle Spezifikation überflogen und bin auf die 
Kapitel "3.1.15   START byte" und "3.1.16   Bus clear" gestossen. In der 
Tat wird inzwischen empfohlen einen speziellen Start durchzuführen der 
dem "SCL wackeln" nahe kommt.

Ich muss sagen, diesen speziellen Start habe ich bisher noch nicht 
benötigt. Dabei arbeite ich mit bis zu 10m I2C-Bus-Länge, aber nur bei 
ca. 8 kHz. Am 5V I2C-Bus habe ich 2,2 kOhm Pullups. Es ist auch ein 
Unterschied ob man einen PCF8574 oder einen DS1631 ansteuert. Letzterer 
ist etwas empfindlich. Einen PCF8574 habe ich mal dagegen über 50m 
Telefonleitung 4x0,6mm noch mit 100 kHz ansteuern können und das ohne 
Repeater/Hub/Extender.

Ein am I2C-Slave seriell geschalteter Widerstand von ca. 300 Ohm (330 
Ohm) am 5V Bus vor dem Clk und DTA Eingang verbessert das 
Übertragungsverhalten.

Seite 37:
"Optional series resistors Rs protect the I/O stages of the I2C-bus 
devices from high-voltage spikes on the bus lines and minimize ringing 
and interference."

Weiteres siehe hierzu auf Seite 58 "7.3 Series protection resistors".

Noch ein Rat, Firmen wie TI wollen natürlich gut dastehen und setzen in 
ihren Demos die höchsten Taktraten ein. Wenn es nicht unbedingt sein 
muss, gehe mit der Frequenz herunter.

mfg klaus

: Bearbeitet durch User
von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Überprüfe Deinen Code mal dahingehend ob vielleicht bei irgendeinem 
Lesezugriff vor der STOP Condition fälschlicherweise ein ACK gesendet 
wird. Dieses ACK (an Stelle eines NACK) hat mich letzte Woche gut 5 
Abende meiner Freizeit gekostet.

von Olaf (Gast)


Lesenswert?

> So ein I2C-Slave ist ein ganz blöder Baustein, der wie
> eine Schaltuhr einer alten Waschmaschine arbeitet.

Das ist nicht immer so. Manche I2C Bausteine machen eher Probleme wie 
andere, manche Layouts sind schlechter und manche Umgebungen haben mehr 
Störungen. Es ist keine Frage das I2C in 99.9% der Faelle gut 
funktioniert, aber nicht in 100%.

Und deshalb ist sowas hier:

> while (UCB0CTL1 & UCTXSTP);

Der ganz grosse Mist! Da gehört immer auch ein Zaehler rein und bei 
Ablauf wird der Bus mit Dummytakten resettet und die I2C-Maschine im 
Controller neu initialisiert.

Alles andere fuehrt zu diesen Scheissgeraeten wo man alle paar 
Monate/Jahre mal den Stecker ziehen muss damit sie wieder laufen.

Olaf

von DJ T. (Gast)


Lesenswert?

Ein Tip:
Wenn Du eine laufende Kommunikation unkontrolliert unterbrichst (z.B. 
durch Reset des µC durch den Debugger), kann es sein, dass der Slave 
"hängen bleibt", weil er auf die Beendigung dieser Kommunikation wartet.

Folgendes Szenario hab ich mal erlebt:
1. Power on, µC + Slave okay
2. µC kommuniziert erfolgreich mit Slave
3. Reset an µC, Kommunikation wird mitten in Telegram unterbrochen
4. µC fährt wieder hoch und will mit Slave reden
5. Slave antwortet nicht, weil er noch mitten im alten Telegram steckt
6. Power off/on hilft

Vielleicht hast Du etwas ähnliches?

von Klaus (Gast)


Lesenswert?

Klaus Ra. schrieb:
> Ich muss sagen, das klingt alles nach Voodoo.

Klaus Ra. schrieb:
> So ein
> I2C-Slave ist ein ganz blöder Baustein, der wie eine Schaltuhr einer
> alten Waschmaschine arbeitet.

Und da passt doch alles zusammen. Wenn deine Waschmaschine nicht genug 
Takte für die Übertragung eines Bytes zusammenkriegt, steht sie da, hält 
SDA low (denn das ist der aktuelle Bitwert) und wartet auf den nächsten 
Takt. In dem Zustand kann auf dem Bus weder ein START noch ein STOP 
erzeugt werden (SDA ist immer low). Jetzt kann entweder die Waschfrau 
den Stecker ziehen oder sie dreht den Programmschalter von Hand auf 
"fertig".

MfG Klaus

von Klaus R. (klara)


Lesenswert?

Klaus schrieb:
> Klaus Ra. schrieb:
>> Ich muss sagen, das klingt alles nach Voodoo.
>
> Klaus Ra. schrieb:
>> So ein
>> I2C-Slave ist ein ganz blöder Baustein, der wie eine Schaltuhr einer
>> alten Waschmaschine arbeitet.
>
> Und da passt doch alles zusammen. Wenn deine Waschmaschine nicht genug
> Takte für die Übertragung eines Bytes zusammenkriegt, steht sie da, hält
> SDA low (denn das ist der aktuelle Bitwert) und wartet auf den nächsten
> Takt. In dem Zustand kann auf dem Bus weder ein START noch ein STOP
> erzeugt werden (SDA ist immer low). Jetzt kann entweder die Waschfrau
> den Stecker ziehen oder sie dreht den Programmschalter von Hand auf
> "fertig".
>
Ich hatte mich ja schon selber berichtigt. Die I2C-Spezifikationen sind 
wohl wegen noch höherer Taktraten angepasst und erweitert worden. Das 
die "I2C-Schaltuhr" auch schon mal stehen bleibt, habe ich bei mir so 
gelöst, dass ich für eine I2C-Aktion ein Timeout vorgebe. Letztlich wird 
sogar nach einigen Minuten der I2C-Master samt Bus kurz stromlos 
gemacht. Ich muss sagen, die reinen I2C-Fehler sind eher sehr, sehr 
selten.

Allerdings werde ich meine Protokolle auf reine I2C-Fehler überprüfen 
und überlegen ob und wie man auf I2C-Blockaden reagieren kann. Dazu 
werde ich mir mal die TI - I2C-LIB für CC6 anschauen.
...
So wie ich das in der Lib-Source sehe haben die da ein 
USCI_B_I2C_masterSendSingleByteWithTimeout und auch ein 
USCI_B_I2C_masterSendSingleByteWithTimeout, aber keine besondere 
Funktion für einen hängenden Slave. Ich werde mir mal die Doku 
vornehmen.

mfg klaus.

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

Klaus Ra. schrieb:
> Ich hatte mich ja schon selber berichtigt. Die I2C-Spezifikationen sind
> wohl wegen noch höherer Taktraten angepasst und erweitert worden.

Mit der Geschwindigkeit sollte das nichts zu tun haben. Ich denke, daß 
selbst ein Uralt-EEPROM ala 24Cxx den Bus verklemmt, wenn man ein Read 
in der Mitte abwürgt. Ich kann das aber im Moment nicht überprüfen.

Ich bin zum ersten mal auf einen hängenden Bus gestoßen, als ich das 
letzte zu lesende Byte nicht mit NAK quitiert habe. Ist zwar eigentlich 
gängig, aber nicht jeder Slave braucht das. Die nächsten Fälle kamen mit 
besseren Debuggern. Nicht mehr Print und durchlaufen lassen, sondern: 
Breakpoint, Step, achja.., Restart. Trotz init hing dann der Bus. Ein 
Power Cycle, d.h. HW-Reset für den Slave, brachte das in Ordnung. Jetzt 
mach ich das 8 mal Takt auf SCL als Teil des I2C init, bevor ich den HW 
I2C einschalte. Kostet kaum Zeit und funktioniert dann auch beim 
Debuggen.

Das kann auch zur Laufzeit helfen. wenn vor dem Anlegen vom Start der 
Bus nicht idle ist (Single Master) noch mal init laufen lassen. Klappts 
dann noch nicht, ist die HW defekt.

Der Timeout ist IMHO mit dem SMBUS gekommen. Das betrift aber die Slaves 
eigentlich nicht. Auf den RAM-Riegeln sind die Standard-24Cxx.

MfG Klaus

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.