Hallo,
ich habe da vor 2 Jahren mal ein Thread gehabt, der aber nicht zu Ende
geführt wurde. Bin seit 2 Tagen an der I2C Statemaschine eines STM32F103
dran, um richtige und verständliche EEPROM Routinen zu schreiben. Habe
einen Logic Analyser mit dran und kann mit das Ganze auch anschauen.
Falls hier jemand ist, der sich schon INTENSIV mit dem Thema befasst hat
und vor allem selbst den Code geschrieben hat, der möge doch mal bitte
hier schreien.
Bytes schreiben klappt soweit ganz gut, auch mit dem Polling. Bytes
lesen liefert zwar richtige Ergebnisse aber mich stört das 255+NAK im
Bild. Da geht zeit bei flöten, der Stop müsste eigentlich direkt
dahinter kommen.
Code aus dem Netz gibt es zwar aber auch da sind Fehler drin, weil da
eine "serielle Denke" am Werk war, zb bei
uint8_t i2c_receive_nack()
stand ursprünglich noch ein i2c_stop() dahinter, so wie man es von einem
AVR her kennt. Fakt ist aber, dass wir es hier mit einer sehr komplexen
Multi-Master fähigen Statemachine zu tun haben, die ein ganzes Netzwerk
betreiben kann und die VORHER gefüttert wird und die dann ihr Programm
auf dem Bus runterspult.
Mein Hauptanliegen ist, ob ich das richtig codiert habe und vor allem,
ob ich das richtig verstanden habe?
Ich frage mich zb immer noch was das "Event 5" auslöst? Ich frage es
zwar aber aber mein Code bleibt da hängen, wenn das EEPROM mit seinem
internetn Zyklus befasst ist.
Gruss,
Christian
Ich kann Dir nur insofern helfen, indem ich funktionierenden Code zum
auslesen eines LM75-Temperatur-Sensors anbiete. Vielleicht hilfts.
Gruß, der Erdowahn
Danke, den kenne ich schon. Ist wohl aus den Beispielen.
Habe ihn aber beiseitige gelegt, weil da noch DMA als zusätzliche
Erschwernis mit hinzu kommt.
geht mir mhr um so einfache Dinge warum eine einfache Abfrage der SM im
i2c_start(), ob sie beschäftigt ist
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
schon einen Hänger verursacht an der Stelle, weil die Schleife nie
verlassen wird.
Hallo,
ich schieb den nochmal hoch, da ich mich nach langer Pause mal wieder
damit befassen wollte.
Wer kennt sich richtig gut aus mit der I2C State Machine des STM32F103 ?
Wo welche Events abgefragt und ausgelöst werden müssen, wo Timeout und
wo nicht usw. Ich habe funktionierenden Code laut Analyzer aber der
hängt sich auch ab und an mal einfach auf, Bumms.... Event kommt nicht,
alles steht still und das geht nicht.
Diese Statemachine ist nicht trivial, vor allem nicht wenn man auf
maximalen Durchsatz gehen will, Pageing optimiert nutzt. Und
Softwarelösungen kommen mir nicht ins Haus, wenn ich eine Top Hardware
habe, die im DMA arbeiten kann.
Gruss,
Christian
Super! Danke Dir! Ich schau mir das mal in Ruhe genau an und gleiche es
mit meinem Code ab.
Berücksichtigst Du auch die Zykluszeit fürs Schreiben oder nimmst du
einfach einen festen Wert, zb 3-4ms. Ich schreibe quasi alles mit
Pagewerite, sobald es mehr als 2 Bytes sind.
Weiterhin schafft man es, grad beim Debuggen so ein E2PROM auch intern
abzuschiessen, so dass es gar nicht mehr reagiert. Man muss nur eine
Sequenz mittendrin abbrechen, dann ist die interne Statemachine
durcheinander. Dafür habe ich noch keine Lösung ausser ON/OFF der ganzen
Schaltung.
Christian J. schrieb:> Weiterhin schafft man es, grad beim Debuggen so ein E2PROM auch intern> abzuschiessen, so dass es gar nicht mehr reagiert. Man muss nur eine> Sequenz mittendrin abbrechen, dann ist die interne Statemachine> durcheinander. Dafür habe ich noch keine Lösung ausser ON/OFF der ganzen> Schaltung.Beitrag "Re: I2C hängt sich auf"
MfG Klaus
Klaus schrieb:> Christian J. schrieb:>> Weiterhin schafft man es, grad beim Debuggen so ein E2PROM auch intern>> abzuschiessen, so dass es gar nicht mehr reagiert. Man muss nur eine>> Sequenz mittendrin abbrechen, dann ist die interne Statemachine>> durcheinander. Dafür habe ich noch keine Lösung ausser ON/OFF der ganzen>> Schaltung.>> Beitrag "Re: I2C hängt sich auf">> MfG Klaus
Ähm.... wie kann man sich das genau vorstellen, dieses "Wackeln"? Das
Schaltwerk meiner Waschmaschine ist dafür nämlich auch anfällig. Da
nützt kein normaler Start mehr was. Und bei einer Statemachine wie der
Prime Cell des STM32 kannste die Leitungen eh nicht manuell ansteuern,
musst sie vorher abkoppeln. Die versteht nur die regulären Abläufe.
@Felix:
Habe jetzt 2 Stunden versucht deinen Code zum Laufen zu kriegen. Ist
noch ein kleiner Bug drin, nämlich dass
// Generate I2C stop condition
I2C_GenerateSTOP(I2C_KANAL, ENABLE);
// Wait until I2C stop condition is finished
while (I2C_GetFlagStatus(I2C_KANAL, I2C_FLAG_STOPF));
die stop Condition nicht auf Ausführung überprüft wird.
Auch hier ist ein Unterschied, nämlich die Verwendung von I2C-CheckEvent
und I2C_FlagStatus.
// Start-Sequence
I2C_GenerateSTART(I2Cx, ENABLE);
timeout = I2C1_TIMEOUT;
while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_SB)) {
if(timeout != 0)
timeout--;
else
return(I2C1_Timeout(I2Cx, -1));
}
I2C_GenerateSTART(I2Cx, ENABLE); löst nämlich ein Event aus.
Du verwendest kein Pagewrite, deine Byte Write Routine wird daher Fehler
melden, wenn du zu schnell schreibst, denn dann antwortet das Eprom
nicht solange der Schreibzyklus nicht beendet ist.
Da habe ich das eingebaut, der hämmert solange eine Start Cond. raus,
bis das Ding endlich antwortet.
/* Warte bis I2C Interface frei */
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/* ACK ein */
I2C_AcknowledgeConfig(I2C_KANAL, ENABLE);
do {
/* Erzeuge START Bedingung ---- FIXXXME */
I2C_GenerateSTART(I2C_KANAL, ENABLE);
if (I2C_WaitForEvent(200, I2C_EVENT_MASTER_MODE_SELECT) !=
SUCCESS)
return ERROR;
// Adressiere das E2PROM
I2C_Send7bitAddress(I2C_KANAL, EE, I2C_Direction_Transmitter);
} while (I2C_WaitForEvent(200,
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS);
Christian J. schrieb:> Ähm.... wie kann man sich das genau vorstellen, dieses "Wackeln"?
Pin von SCL zum Ausgang machen, dann High, dann Low, dann High ...
Die Statemachine im Slave zuende takten
MfG Klaus