Forum: Mikrocontroller und Digitale Elektronik I2C macht mich wahnsinnig


von Cimbom G. (cimbomgs)


Lesenswert?

Hallo Freunde,

ich bin jetzt seit Monaten dabei über die I2C-Schnittstelle 2 
Mikrokontroller zu verbinden. Sie sollen Daten gegenseitig austauschen. 
Aber geklappt hat es bis heute noch nicht

Ich setze 2 Freescale Mikrocontroller ein (MC56F8036).

Beide Mikrocontroller können sowohl als Master als auch als Slave 
arbeiten. D.h. im Laufe des Programms wird eingestellt welcher 
Mikrocontroller als was arbeiten soll (Master oder Slave)

Wenn der Master sendet, dann wiederholt er es solange bis der Slave mit 
ACK bestätigt, dass das Datum erfolgrecih gesendet wurde.
1
//Master-Mode 1. Mikrocontroller
2
I2C1_SetMode(master);
3
4
do  //solange bis senden OK
5
{
6
  tx_abort=FALSE;
7
    
8
  I2C1_SelectSlave(slave_addr); // Slave auswaehlen
9
  I2C1_SendBlock(&data[0], 4, &send_temp); // Daten senden
10
  Cpu_Delay100US(1);
11
} while( tx_abort ); //tx_abort wird immer wieder auf true gesetzt bis Tx erfolgreich
12
13
14
15
//Slave-Mode 2.Mikrocontroller
16
I2C1_SetMode(slave);
17
  
18
do // solange bis empfangen OK
19
{
20
  Err = I2C1_RecvBlock(&empf[0], 4, &recv_temp); //Daten empfangen
21
  Cpu_Delay100US(10); //Delay
22
} while( ((Err == ERR_BUSOFF) || (Err == ERR_RXEMPTY) || 
23
(Err == ERR_OVERRUN) || (Err == ERR_DISABLED)) && (recv_temp!=4) );

Das Problem ist, wenn die Daten gesendet werden, werden sie erst im 
Puffer von I2C gespeichert und anschließend kann ich die Daten aus dem 
Puffer holen und in mein Array speichern. Und während ich die Daten 
bearbeite, kommen schon die nächsten Daten und irgendwann ist alles ganz 
durcheinander..
Wie kann ich das verhindern? Wie kann ich den I2C-Bus solange stoppen, 
bis der Buffer frei wird, bzw. ich die Daten verarbeitet habe?

Kann mir BITTE jemand eine vernünftige Routine für I2C-Bus sagen?

von Cimbom G. (cimbomgs)


Lesenswert?

kann jemand ein gutes Buch zu I2C empfehlen??

von Johnny Maxwell (Gast)


Lesenswert?

> Wie kann ich das verhindern? Wie kann ich den I2C-Bus solange stoppen,
> bis der Buffer frei wird, bzw. ich die Daten verarbeitet habe?

clock stretching?

von jack (Gast)


Lesenswert?

>clock stretching?

Blödsinn. Der Master kann jederzeit die Datenübertragung stoppen.

von Cimbom G. (cimbomgs)


Lesenswert?

sorry aber was genau ist "clock stretching" :-/ ?

von Sven P. (Gast)


Lesenswert?

clock stretching meint, dass der nicht-taktgebende Kommunikationspartner 
(normalerweise der Slave) das Taktsignal einfach mal eben auf festklemmt 
(also auf einem Pegel hält). Das merkt der Taktgeber ja dann ("Wie? 
Immer noch LOW obwohl ich schon HIGH sage? OK..warten2).

von Johnny Maxwell (Gast)


Lesenswert?

>> clock stretching?
> Blödsinn. Der Master kann jederzeit die Datenübertragung stoppen.

Sorry, ich hab das so verstanden, als wäre der Client zu langsam.

@Cimbon Gs: Soso, du beschäftigst dich also seit Monaten mit I2C, weißt 
aber nicht was clock stretching ist :)
Das heißt einfach, dass der Client SCL auf low hält und der Master 
solange warten muss.

von jack (Gast)


Lesenswert?

>Sorry, ich hab das so verstanden, als wäre der Client zu langsam.

Tut mir leid, Du hast wahrscheinlich recht, der Client ist zu langsam 
und
soll den Master aufhalten.

von Cimbom G. (cimbomgs)


Lesenswert?

es ist so:

zu erst sendet MC1 an MC2 einen Befehl zum starten, wenn MC2 seine 
Messung beendet hat wird MC2 zu Master und MC1 zu SLave. MC2 sendet das 
Ergebnis an MC1 und wenn MC1 das Ergebnis erhalten hat beginnt er mit 
seiner eigenen Messung. Danach wird MC1 wieder zu Master und MC2 zu 
Slave

In der Zeit, wo MC1 seine Messung durchführt wartet MC2 bis MC1 das 
Befehl zum starten sendet. D.h. es könnte und dürfte nie zu einem 
überlauf kommen.
(Beide MC's warten immer aufeinander)

Aber es passiert trotzdem, dass MC1 mehr als 4 chars im Buffer hat. D.h. 
das irgendwie der MC2 mehrmals seine Messung durchführt und an MC1 
sendet..

Dieses Phänomen kann ich einfach nicht verstehen.
Ich meine MC2 muss immer erst auf MC1 warten und dann seine Messung 
starten. und wenn MC2 mit der Messung fertig ist, sendet er das Ergebnis 
an MC1

von Cimbom G. (cimbomgs)


Lesenswert?

Johnny Maxwell wrote:
> @Cimbon Gs: Soso, du beschäftigst dich also seit Monaten mit I2C, weißt
> aber nicht was clock stretching ist :)

naja ich habe den Begriff "clock stretching" zum ersten Mal gehört, 
daher habe ich es nicht ganz verstanden

von Cimbom G. (cimbomgs)


Lesenswert?

naja ich könnte auch  mit einfachem Master-Slave modus arbeiten, d.h. 
einer ist immer Master und der andere immer Slave. Aber dann habe ich 
das Problem, obwohl der Slave seine Daten nicht auf den I2C-Bus gelegt 
hat, bekommt der Master lauter Nullen...

Ich könnet eine Routine schreiben, dass solange das empfangene Datum 
eine Null ist das Empfangen wiederholt, aber das Ergebnis kann ja auch 
Nullen enthalten und das würde wieder alles Verfälschen

von Cimbom G. (cimbomgs)


Lesenswert?

ach "bidde" kann jemand zu meinem Code was sagen?

von holger (Gast)


Lesenswert?

>Aber es passiert trotzdem, dass MC1 mehr als 4 chars im Buffer hat. D.h.
>das irgendwie der MC2 mehrmals seine Messung durchführt und an MC1
>sendet..
>
>Dieses Phänomen kann ich einfach nicht verstehen.

Das ist kein Phänomen. Das hast du selber programmiert.
Mach eine saubere Master/Slave Verbindung und gut.
Solange der Master nichts anfordert hält der Slave
einfach die Klappe.

von Cimbom G. (cimbomgs)


Lesenswert?

holger wrote:

> Solange der Master nichts anfordert hält der Slave
> einfach die Klappe.

ja aber wie oben schon erwähnt, wenn der Master von Slave lesen möchte 
aber der Slave nocht nicht soweit ist, legt der I2C-Bus Nullen auf die 
Leitung..Der Master kann nicht auf "Nicht-Null" prüfen, weil das 
Ergebnis auch Nullen enthalten kann..

Beispiel:

Slave hat 4 Bytes zu senden, bzw. Master muss 4 Bytes lesen.
1. Byte 0
2. Byte 1
3. Byte 0
4. Byte 7

d.h. wenn Master auf eine "Nicht-Null" wartet, wird das Ergebnis ganz 
falsch :-(

von Falk B. (falk)


Lesenswert?

@ Cimbom Gs (cimbomgs)

>ja aber wie oben schon erwähnt, wenn der Master von Slave lesen möchte
>aber der Slave nocht nicht soweit ist, legt der I2C-Bus Nullen auf die
>Leitung..

Nöö.

>Der Master kann nicht auf "Nicht-Null" prüfen, weil das
>Ergebnis auch Nullen enthalten kann..

Nöö. Wenn der Slave noch nicht bereit ist zum antworten, dann antwortet 
er einfach nicht. Damit geht die Addressierung mangels ACK "daneben" und 
der Master muss es später nochmal versuchen. Ganz einfach. Siehe 
I2C- Spezifikiation.

>d.h. wenn Master auf eine "Nicht-Null" wartet, wird das Ergebnis ganz
>falsch :-(

Du solltest dich dringend mal mit den grundlagen von I2C befassen.
Dann löst sich dein "Problem" in Luft auf.

MFG
Falk

von holger (Gast)


Lesenswert?

>ja aber wie oben schon erwähnt, wenn der Master von Slave lesen möchte
>aber der Slave nocht nicht soweit ist, legt der I2C-Bus Nullen auf die
>Leitung..Der Master kann nicht auf "Nicht-Null" prüfen, weil das
>Ergebnis auch Nullen enthalten kann..

Wie Falk schon sagte: Wenn der Slave nicht antworten kann
kommt kein gültiges ACK für den Master. Was in den Datenbits steht ist
dann völlig wurscht.

von Cimbom G. (cimbomgs)


Lesenswert?

Falk Brunner wrote:

> Du solltest dich dringend mal mit den grundlagen von I2C befassen.

habe ich schon zum 100. Mal gemacht, aber das Hilft nicht weiter.

Bei Freescale gibt es folgende Eigenschaft:
Empty character - A character being sent when no data is ready to be 
transmitted.

>Nöö. Wenn der Slave noch nicht bereit ist zum antworten, dann antwortet
>er einfach nicht.
Das hätte ich auch am liebsten, aber dem ist nicht so :-/..Wenn Slave 
nicht zu senden hat, antwortet der I2C-Protokoll mit einem "Empty 
character"

Und das ist der Grund, warum ich Multi-Master einsetze. Immer der MC, 
der als Slave konfiguriert ist wartet bis Master sendet. Daher existiert 
kein "Empty character", wenn der eine oder der andere nichts zu senden 
hat

von Falk B. (falk)


Lesenswert?

@ Cimbom Gs (cimbomgs)

>> Du solltest dich dringend mal mit den grundlagen von I2C befassen.

>habe ich schon zum 100. Mal gemacht, aber das Hilft nicht weiter.

Das glaube ich kaum.

>Das hätte ich auch am liebsten, aber dem ist nicht so :-/..Wenn Slave
>nicht zu senden hat, sendet der I2C-Protokoll mit einem "Empty
>character"

Glaub ich nicht. Kann man sicher abstellen.

>Und das ist der Grund, warum ich Multi-Master einsetze. Immer der MC,
>der als Slave konfiguriert ist wartet bis Master sendet.

Dann ist es kein Multmaster!

> Daher existiert
>kein "Empty character", wenn der eine oder der andere nichts zu senden
>hat

Du drehst dich im Kreis.

MfG
Falk

von Johnny Maxwell (Gast)


Lesenswert?

Ich kenne den Controller zwar überhaupt nicht, hab aber mal für dich die 
Errata rausgesucht:

http://www.freescale.com/files/dsp/doc/errata/MC56F8036E.pdf

Da stehen jede Menge Sachen zu I2C drin, vielleicht hilft dir das 
weiter.

von Cimbom G. (cimbomgs)


Lesenswert?

Falk Brunner wrote:
> Das glaube ich kaum.
glaub mir das habe ich :-(

> Glaub ich nicht. Kann man sicher abstellen.
habe ich schon mehr mals das Datenblatt angeschaut, nirgends ein Zeichen 
davon wie man es abstellen kann. Vor allem es wird auch nirgends erwähnt 
das es so passiert aber in der Entwicklungsumgebung ist es vorhanden

> Du drehst dich im Kreis.

das weiß ich, aber finde keinen Weg aus dem Kreis rauszukommen.

>Ich kenne den Controller zwar überhaupt nicht, hab aber mal für dich die
>Errata rausgesucht:

Kenne ich auch schon, aber Hilft auch nicht wirklich weiter.

von Peter D. (peda)


Lesenswert?

Cimbom Gs wrote:

> Das hätte ich auch am liebsten, aber dem ist nicht so :-/..Wenn Slave
> nicht zu senden hat, antwortet der I2C-Protokoll mit einem "Empty
> character"


Im Philips I2C-Standard gibts keinen "Empty character".

Der Master muß auf die Adresse immer das ACK prüfen und der Slave darf 
das NACK setzen, damit der Master kein ACK kriegt.

Falls wider Erwarten der Slave kein NACK setzen können sollte, dann 
einfach das Slave-I2C solange disablen.

Wenn der Master das ACK nicht testet, dann kann er ja nicht mal 
Standard-I2C Chips bedienen, wie z.B. EEPROMs 24C512 usw..

Diese ICs senden nämlich immer NACK, solange sie intern mit Schreiben 
beschäftigt sind.

Dann könnte man sich damit behelfen, das Master-I2C in Software zu 
machen (Bitwackeln) und dann das NACK auswerten.


Peter

von Cimbom G. (cimbomgs)


Angehängte Dateien:

Lesenswert?

Peter Dannegger wrote:

> Im Philips I2C-Standard gibts keinen "Empty character".

das weiß ich.. Ach man ich möchte heulen

Im Anhang ist ein Bild von der Entwicklungsumgebung. Das "Empty 
character" kann man nirgends abschalten :'(

von Peter D. (peda)


Lesenswert?

Cimbom Gs wrote:

> Im Anhang ist ein Bild von der Entwicklungsumgebung. Das "Empty
> character" kann man nirgends abschalten :'(

Von solchen Code-Wizzards halte ich nicht viel.
Sie sind in der Regel völlig unausgereift und können natürlich nicht 
alle Anwendungsfälle vorhersehen.
Sie können nur ausschließlich das machen, was der Entwickler des 
Wizzards vorgedacht hat.

Ich hab auch noch nie gehört, daß jemals jemand mit sowas richtig 
arbeiten konnte.

Ich hab sowas noch nie benutzt, ich programmiere immer direkt in C.


Da muß es doch auch ein Datasheet oder Usermanual zu dem Chip geben, wo 
die ganze Peripherie beschrieben ist und auch das I2C.

Und da muß dann drinstehen, in welchem IO-Register welche Bits welche 
Bedeutung haben.

Und eins davon muß bedeuten, daß ein NACK empfangen wurde.


Peter

P.S.:
In dem Wizzard steht irgendwas von Errorinterrupt, könnte sein, daß das 
NACK im Errorinterrupt ausgelesen werden kann.

von Cimbom G. (cimbomgs)


Lesenswert?

ich verstehe die Welt nicht mehr :'(

von Peter D. (peda)


Lesenswert?

Cimbom Gs wrote:
> ich verstehe die Welt nicht mehr :'(

Wenn Du mit dem Wizzard arbeitest, muß es doch auch ne Doku und Hilfe 
dazu geben, die mußt Du durchlesen.

Ein Wizzard kann ja nicht zaubern.
Du mußt lesen, welche Funktionen er bereitstellt, wenn Du ihn verwenden 
willst.


Peter

von Cimbom G. (cimbomgs)


Lesenswert?

Peter Dannegger wrote:
> In dem Wizzard steht irgendwas von Errorinterrupt, könnte sein, daß das
> NACK im Errorinterrupt ausgelesen werden kann.

wenn Slave ein NACK erzeugt bzw SDA-Leitug auf HIGH beleibt (zBsp. weil 
der Slave den I2C deaktiviert hat), dann sieht der Master das NACK und 
kann abbrechen oder dem entsprechend reagieren. Aber wenn I2C aktiv ist 
aber der Slave keine Daten in TX-Buffer geschrieben hat, antwortet der 
I2C-Protokoll mit dem blöden "Empty character" und das entspricht keinen 
NACK sondern der  Master denkt, er hätte ein Byte vom Slave empfangen.

Das kann ich natürlich beliebig oft wiederholen, der Master würde jedes 
Mal das "Empty character" empfangen und würde denken, der Slabe hat die 
geforderten Daten herausgegenen.

:'(

von Peter D. (peda)


Lesenswert?

Cimbom Gs wrote:

> wenn Slave ein NACK erzeugt bzw SDA-Leitug auf HIGH beleibt (zBsp. weil
> der Slave den I2C deaktiviert hat), dann sieht der Master das NACK und
> kann abbrechen oder dem entsprechend reagieren.

Heißt das nun, der Slave sendet ein ACK?
In dem Fall ist Dein Fehler in der Slaveprogrammierung und nicht im 
Master.


> Aber wenn I2C aktiv ist
> aber der Slave keine Daten in TX-Buffer geschrieben hat, antwortet der
> I2C-Protokoll mit dem blöden "Empty character" und das entspricht keinen
> NACK sondern der  Master denkt, er hätte ein Byte vom Slave empfangen.

Das geht nur, wenn Du den Slave nach dem ACK auf die Adreßerkennung 
abschaltest.
Ansonsten hält nämlich der Slave das SCL solange auf low, bis Du ein 
Datenbyte reinschreibst (Clock Stretching).
Der I2C Bus synchronisiert sich immer auf den langsamsten Teilnehmer.
Es kann nie ein Byte verloren gehen.


Ich würde Dir raten, wenn Du mit den Wizzard nicht klarkommst, ihn über 
Board zu schmeißen und Dir selber die I2C-Beschreibung im Datenblatt 
durchzulesen.

Zumindest in den Atmel- und Philips-Datenblättern gibt es wunderschöne 
Zustandsgraphen und Ablaufdiagramme, die alle Phasen eines I2C-Transfer 
ausführlich beschreiben, die Bedeutung aller Statusbits und die darauf 
auszuführenden Aktionen.


Peter

von Falk B. (falk)


Lesenswert?

@ Cimbom Gs (cimbomgs)

>kann abbrechen oder dem entsprechend reagieren. Aber wenn I2C aktiv ist
a>ber der Slave keine Daten in TX-Buffer geschrieben hat, antwortet der
>I2C-Protokoll mit dem blöden "Empty character" und das entspricht keinen
>NACK sondern der  Master denkt, er hätte ein Byte vom Slave empfangen.

Wenn man das WIKRLICH nicht abschalten kann, dann muss dein Slave VORHER 
überlegen, ob er jetzt das aktuelle Datenpaket vollständig und schnell 
genug in den TX-Buffer schreiben kann oder nicht. Wenn nein, wird das 
Senden von ACK  direkt nach der Adressierung verweigert. Das musst du 
dem I2C Modul verklickern.

MfG
Falk

von Ulrich P. (uprinz)


Lesenswert?

Wow... Der arme kleine I2C Bus...

Also es gibt drei Arten einen I2C Bus zu bremsen. Alle sind 
spetifiziert, nur zwei davon sind geeignet Protokoll auf Byte-Ebene zu 
bremsen.

Bit-Stretching:
-----------------------
Bit-Stretching (oder Clock-Stretching) ist eine implizite Methode, weil 
der langsamere Partner am Bus durch das Ziehen auf LOW von SCL dem 
schnelleren Partner signalisiert, dass er mit dem voran gegangenen Bit 
noch beschäftigt ist.
Das ist vor allem dann wicht zu wissen, wenn man das Protokoll in 
Software emuliert. Man muss nicht nur SCL loslassen, wenn man das 
nächste Bit senden will, sondern man muss auch prüfen, ob SCL von allen 
Partnern los gelassen wurde. Erst wenn SCL HIGH ist, beginnt die in der 
Spec angegeben tHIGH zu laufen, nicht, wenn der Sender denkt, dass er 
SCL high gesetzt hat!
Bit-Stretching kann im Übrigen, gerade in der Adressierungsphase, von 
allen Chips am Bus genutzt werden, nicht nur von dem, denn man gerade zu 
adressieren meint.

Byte-Stretching:
-----------------------
Nach einem Byte kann der SCL-Zyklus bis zum ACK verzögert werden. Dies 
ist legal und absichtlich so vorgesehen, da es bei Controller basierten 
Lösungen ( egal, ob Hardware- oder Software-Implementation) erforderlich 
ist, zuerst einmal das Byte zu speichern und ggf. zu analysieren um 
entscheiden zu können, ob nun ein ACK oder ein NACK geantwortet werden 
muss.
Physikalisch wird es identisch zum Bit-Stretching behandelt (SCL LOW 
halten, bis Antwort erfolgen kann, ACK/NACK an SDA anlegen und SCL los 
lassen)

ACK-Polling
-----------------------
Um auf Protokoll-Ebene eine Verzögerung zu realisieren, kann man sein 
Device Offline schalten. D.h. es antwortet auf seine Adresse nicht mit 
ACK, sondern setzt entweder gezielt ein NACK oder ignoriert den 
Busverkehr komplett.
EEPROMs schalten sich z.B. offline so lange sie mit dem internen 
Programmieren beschäftigt sind. Möchte man weitere Daten schreiben, so 
pollt man das EEPROM auf seiner Adresse, bis man wieder ein ACK erhält. 
So kann man z.B. unterschiedlich schnelle EEPROMs mit ihrer maximalen 
Geschwindigkeit nutzen, ohne die Software ändern zu müssen.
Auch vernetzte Mikrocontroller sollten diese Art der 
Kommunikations-Verzögerung nutzen, da sie einfach zu realisieren ist.

Alle anderen Verzögerungen, wie zum Beispiel das immer wieder gerne 
gemachte SCL low NACH DEM ACK sind illegal, tabu, nicht kontrollierbar.

Protokolle
-----------------------
Wer ein Protokoll auf I2C implementiert, sollte I2C komplett betrachten 
und dann los legen. Ein Datenrahmen unbekannter Größe wird immer durch 
ein START und ein STOP begrenzt. Mehr hat man nicht. Was man tun sollte 
ist auch das letzte ACK mit einbeziehen. D.h. wenn ein Partner nicht 
mehr zu empfangen hat, dann beantwortet er das letzte Byte mit NACK.

Das Protokoll sollte möglichst früh eine Angabe darüber machen, wie viel 
Daten zu erwarten sind. D.h. man könnte es folgendermaßen aufbauen:
{ST}(ADR)[CMD][LEN][DATA]...[DATA]{SP}
{ST} ist die START-Kondition auf dem Bus
(ADR) Adressiert den Partner
[CMD] ist das Kommando
[LEN] die Anzahl der zum Kommando gehörenden und nun folgenden Parameter
[DATA] sind die Parameter oder Daten
{SP} ist die STOP-Kondition
Der Empfänger kann und sollte auf das letzte [DATA] mit NACK antworten. 
So hat der Sender hier schon eine Information, ob er genauso viel 
gelesen hat, wie er zu senden hatte.

Warum sende ich zuerst CMD und dann LEN? Nun so kann man einfach 
dynamische Längen für einen CMD erzeugen und der Empfänger kann vorab 
schon mal prüfen, welche Menge an Daten er mindestens und maximal haben 
will.
Schon mit dem dann folgenden LEN kann ein Fehler aufgedeckt werden.


Timing
-----------------------
Beim Lesen der I2C Spec sollte man beachten, dass viele Timing-Parameter 
als MIN angegeben sind. D.h. hier ist ein Minimum einzuhalten. Ich habe 
schon viele Software-Implementationen gesehen, bei denen nahezu alle 
Parameter irgendwie mit Gewalt exakt auf die in der Spec angegebenen 
Zahlen gepresst wurden. Das ist i.d.R. falsch.

Gruß, Ulrich

von Ulrich P. (uprinz)


Lesenswert?

Hab ich Euch jetzt erschlagen, oder gibt es Fortschritte?

Gruß, Ulrich

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.