Forum: Mikrocontroller und Digitale Elektronik In I2C "Transmission end" ohne While-Schleife lösen


von daniel san (Gast)


Lesenswert?

Hi ich brauche einen Rat von euch.

Es geht um eine I²C-Kommunikation,

normalerweise (in nicht sicherheitskritischen Anwendungen) wartet man 
m.H. eine while-Schleife ab, bis die Daten rausgeschickt werden.

so wie hier im Pseudo-Code:
1
output_register = i2c_data;
2
3
while(output_register == leer)//warten bis alle Daten raus (transmission end)
4
{
5
;
6
}
7
8
nächster_Befehl;
9
.
10
.
11
.

Wie löse ich das ohne eine While-schleife?
Ich hab immer gelernt in sicherheitskritischen Anwendungen ne 
while-schleife einzusetzen lieber if-abfragen.

Am liebsten möchte ich das in der Interrupt-routine lösen, weil dieses 
Interrupt immer nur dann ausgelöst wird wenn die Daten raus sind.

Gibt es dazu einen Pseudo-Code, Beispiel-Code wie man sowas macht?

Ich verwende auch zwischendruch ein Repeated Start.

Wer hat sowas schon mal gemacht oder hat ne Idee wie ich das lösen kann?

Grüße, Daniel

von Ralf (Gast)


Lesenswert?

Hi Daniel,

hast du ein FlowChart der I2C-Kommunikation? Wenn ja brauchst du die 
StateMachine dazu nur so implementieren, dass an keiner Stelle gewartet 
wird, sondern bestimmte Statusbits/-bytes gesetzt werden, die die 
StateMachine beim nächsten Durchlauf veranlassen wieder zu prüfen.

Was dein konkretes Problem von oben betrifft: Anstatt while() verwendest 
du if-else. Wenn(if) die Daten raus sind, holst du die neuen Daten, 
ansonsten(else) verlässt du die Funktion ohne weiteres wieder. In beiden 
Fällen kannst du über einen Rückgabewert signalisieren ob was gegangen 
ist...

Somit blockierst du den Rest der Applikation nicht. Die Sache hat nur 
einen Haken, es kann sein dass du dann auch andere Programmteile 
entsprechend ummodeln musst.

Du schreibst du willst es im Interrupt machen. Dann brauchst du doch die 
while-Schleife gar nicht mehr...

Ralf

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

daniel san schrieb:
> normalerweise (in nicht sicherheitskritischen Anwendungen) wartet man
> m.H. eine while-Schleife ab, bis die Daten rausgeschickt werden.
Nein I2C ist so schnarchlangsam, da wartet man nicht, sondern tut 
nebenher was Sinnvolles.
Man schickt also die Daten los, macht dann was anderes, schaut 
zwischendurch mal wieder, ob die Übertragung schon fertig ist, macht 
wieder was anderes, schaut wieder nach, macht was anderes...
Und wenn man dann irgendwann sieht, dass der I2C fertig ist, dann 
schickt man das nächste Byte los, macht was anderes, sieht nach, ob die 
Übertragung schon fertig ist, macht was anderes...

Was du brauchst heißt "Zustandsautomat in der Hauptschleife".

Dieses Programmiermodell wird allerdings nur in der Praxis verwendet 
(schon immer bei SPSen, da heißt der Zustandsautomat allerdings 
verniedlichend "Merker") und nicht an Schulen gelehrt.
Es widerspricht der gängigen Lehrmeinung, wonach ein Programm immer auf 
eine Eingabe wartet, dann die Berechnung komplett abschließt, dann den 
Rechenwert ausgibt, um wieder von vorn zu beginnen...

von (prx) A. K. (prx)


Lesenswert?

daniel san schrieb:

> Wie löse ich das ohne eine While-schleife?
> Ich hab immer gelernt in sicherheitskritischen Anwendungen ne
> while-schleife einzusetzen lieber if-abfragen.

Wenn man in der betreffenden Zeit sowieso nichts zu tun hat, dann ist 
eine solche Schleife ok. Allerdings sollte man einen möglichen Timeout 
mit einbauen. Es kann durchaus geschehen, dass eine I2C-Kommunikation 
mal fehlschlägt und es bessere Auswege gibt als den Watchdog-Reset.

> Am liebsten möchte ich das in der Interrupt-routine lösen, weil dieses
> Interrupt immer nur dann ausgelöst wird wenn die Daten raus sind.

I2C per Interrupt ist sehr sinnvoll. Nur wartet man dann doch wieder 
irgendwo auf den Abschluss, diesmal per Flag oder Pufferstatus. Die 
Frage ist eher, auf welche Weise man wartet, ob in kleiner Schleife wie 
hier, oder ob per State-Machine in der grossen Schleife - oder per RTOS 
in der Task.

von (prx) A. K. (prx)


Lesenswert?

daniel san schrieb:

> Gibt es dazu einen Pseudo-Code, Beispiel-Code wie man sowas macht?

Abstrakten Pseudo-Code müsste erst einmal jemand schreiben, gibts bei so 
sachbezogenen Themen nicht allzu häufig. Konkreten Beispielcode hingegen 
findet man oft in Application Notes. Die aber sind nicht abstrakt oder 
Pseudo, sondern beziehen sich auf echtes Silizium. Und dazu wärs 
hilfreich, das zu verraten, was bei Fragestellern oft wie ein 
Staatsgeheimnis behandelt wird: Welche Controller-Familie man im Auge 
hat.

von Matze T. (gruetzwurschd)


Lesenswert?

Vielleicht kann man sich da nen code basteln, der zyklisch von nem Timer 
aufgerufen wird?

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.