Forum: Mikrocontroller und Digitale Elektronik Frage zum I2C Reset


von I2C (Gast)


Lesenswert?

Hi,

ich befasse mich gerade mit I2C und versuche mich an einer eigenen 
Implementierung einer Bibliothek für Atmel AVRs. Nun kann es ja dazu 
kommen, dass der Bus "verstopft" ist, wenn z.B. der Master inmitten 
eines Transfers neugestartet wird und so vergisst, dass er eigentlich 
noch SCL clocken müsste.

Dies wird z.B. hier 
(http://www.analog.com/static/imported-files/application_notes/54305147357414AN686_0.pdf) 
beschrieben. Dort wird auch gleichzeitig eine Lösung vorgestellt, die da 
lautet:

> The procedure is as follows:
> 1) Master tries to assert a Logic 1 on the SDA line
> 2) Master still sees a Logic 0 and then generates a clock
> pulse on SCL (1-0-1 transition)
> 3) Master examines SDA. If SDA = 0, go to Step 2; if
> SDA = 1, go to Step 4
> 4) Generate a STOP condition

Soweit auch alles klar. Allerdings verstehe ich den nächsten Satz nicht:

> Note that this process may need to be repeated because
> the cleared SDA line may have been cleared for the next
> bit, which was a 1.

Kann mir das jemand erklären? Anscheinend fehlt es mir hier an 
Vorstellungsvermögen, aber was genau ist hier das nächste "bit"?

Vielleicht könnt ihr mir auf die Sprünge helfen. Wie handhabt ihr das 
Ganze?

Vielen Dank!

von Mike (Gast)


Lesenswert?

Ich verstehe den Text so, dass beim Senden der STOP-condition der Slave 
noch ein Datenbit 0 ausgibt, wodurch die STOP-condition nicht am Bus 
durchkommt.

Ich mache das immer so, dass ich einfach nach beim Initialisieren des 
I2C 9 mal eine 1 sende (z.B: I2C Receive) und danch ein STOP ausgebe. 
Damit bekommt der Slave sicher ein NAK geschickt und sollte danach 
eigentlich schweigen. Die STOP-condition setzt dann den Bus zurück.

Das wird in folgendem Beitrag ausführlicher diskutiert:

http://www.microchip.com/forums/m175368-print.aspx

Gruss
Mike

von I2C (Gast)


Lesenswert?

Irgendwie scheint es da mehrere Ansätze zu geben. Interessanterweise 
heißt es in der offiziellen Spezifikation in Punkt 3.1.16:

> If the data line (SDA) is stuck LOW, the master should send nine clock
> pulses. The device that held the bus LOW should release it sometime within
> those nine clocks. If not, then use the HW reset or cycle power to clear
> the bus.

Das erscheint mir am Einfachsten in der Implementierung. Gibt es 
Probleme, die damit nicht gelöst werden?

von Klaus (Gast)


Lesenswert?

I2C schrieb:
> Irgendwie scheint es da mehrere Ansätze zu geben.

Die oben genannte Prozedur ist doch eigentlich das Gleiche. Sie versucht 
nur ein paar Pulse zu sparen, sollten weniger als 9 nötig sein. Ob das 
der Bringer ist?

MfG Klaus

von I2C (Gast)


Lesenswert?

Klaus schrieb:
> Die oben genannte Prozedur ist doch eigentlich das Gleiche. Sie versucht
> nur ein paar Pulse zu sparen, sollten weniger als 9 nötig sein. Ob das
> der Bringer ist?

Naja, nicht unbedingt, da sie auf das Senden der STOP Condition 
verzichtet. Je nach Implementierung der State Machine kann das ja 
durchaus etwas ausmachen.

Ich verstehe nur nicht wie ich eine STOP Condition generieren kann, wenn 
SDA schon high ist. Eine STOP Condition ist ja definiert als Low-High 
Übergang von SDA während SCL high bleibt. Wenn aber SDA schon high ist, 
sehe ich nicht wie ich einen Low-High Übergang hinbekommen soll, ohne 
vorhergehenden High-Low Übergang, was ja einer START Condition 
entspräche.

Übersehe ich hier etwas?

von Mike (Gast)


Lesenswert?

> Ich verstehe nur nicht wie ich eine STOP Condition generieren kann, wenn
> SDA schon high ist. Eine STOP Condition ist ja definiert als Low-High
> Übergang von SDA während SCL high bleibt. Wenn aber SDA schon high ist,
> sehe ich nicht wie ich einen Low-High Übergang hinbekommen soll, ohne
> vorhergehenden High-Low Übergang, was ja einer START Condition
> entspräche.
>
> Übersehe ich hier etwas?

Ja, der Master muss den Bus natürlich aktiv ansteuern.

In folgender Reihenfolge:

1. 0->SCL, 1->SDA
2. 0->SCL, 0->SDA
3. 1->SCL, 0->SDA
4. 1->SCL, 1->SDA

Der Schritt von 3 nach 4 ist die STOP-condition.

START-condition wäre SDA von 1 auf 0 bei gleichzeitig SCL High. Ein 
Pegelwechsel auf SDA bei SCL Low löst kein START aus.

von I2C (Gast)


Lesenswert?

Mike schrieb:
> 1. 0->SCL, 1->SDA
> 2. 0->SCL, 0->SDA
> 3. 1->SCL, 0->SDA
> 4. 1->SCL, 1->SDA

Könntest du das eben nochmal etwas ausführen? Worauf genau war das 
bezogen?

von Thomas K. (thomas_k39)


Lesenswert?

I2C schrieb:
> Mike schrieb:
>> 1. 0->SCL, 1->SDA
>> 2. 0->SCL, 0->SDA
>> 3. 1->SCL, 0->SDA
>> 4. 1->SCL, 1->SDA
>
> Könntest du das eben nochmal etwas ausführen? Worauf genau war das
> bezogen?

Auf Deine Frage: wie erzeuge ich eine STOP-Condition, wenn SCL und SDA 
high sind, ohne vorher eine START-Condition zu erzeugen.

Ganz einfach: im ersten Schritt (1.) SCL von High nach Low bringen.

Ist der Bus IDLE, so hat dies keine Bedeutung (ist insbesondere keine 
START-Condition). Ist der Bus belegt, so ist das einfach das Ende eines 
Bits.

Solange nun SCL auf Low ist, darf ich mit SDA machen, was ich will - in 
diesem Fall also SDA auf Low (2.) bringen.

Und kann jetzt die STOP-Condition problemlos erzeugen: SCL auf High 
gehen lassen (3.), danach SDA von Low auf High umschalten (4.)

von Walter T. (nicolas)


Lesenswert?

Hallo Thomas,
danke für Deine Erklärung. Sie hat mir heute sehr geholfen.

Viele Grüße
W.T.

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.