STM32 I2C Übertragungsende abwarten

Gast #2581749
Lesenswert?

Hallo zusammen!
Programmiere derzeit ein wenig für den STM32 und habe nun die 
I²C-Schnittstelle auch zum laufen gebracht.
Geholfen hat mir dabei dieser Code sehr:
http://www.micromouseonline.com/2011/09/10/i2c-use-on-the-stm32f103r-medium-density-devices/#axzz1oM1D8P00

Jetzt hab ich aber derzeit die While-Schleifen, in welchen auf das Ende 
einer Übertragung gewartet wird, auskommentiert, da sich mein Programm 
immer in diesen verläuft.
Es gibt zu diesem Problem schon Beiträge (Ja, SuFu benutzt...;-)), aber 
die haben alle keine Lösung dieses Problems oder sind nicht zu ende 
geschrieben.
An was kann es liegen? Kann ich die Abfrage etwas anderst gestalten? Hab 
auch in meinem Code schon das hier probiert:
1
    /* initiate start sequence */
2
    I2C_GenerateSTART(I2C1, ENABLE);
3
    /* check start bit flag */
4
    while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_SB));
5

6
    /*send write command to chip*/
7
    I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7<<1, I2C_Direction_Transmitter);
8
    /*check master is now in Tx mode*/
9
    while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR));
10
    //while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
11
    /*mode register address*/
12
    I2C_SendData(I2C1, 0x01);
13
    /*wait for byte send to complete*/
14
    while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF));
15
    //while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
16
    /*clear bits*/
17
    I2C_SendData(I2C1, 0x02);
18
    /*wait for byte send to complete*/
19
    while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF));
20
    //while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
21
    
22
    /*generate stop*/
23
    I2C_GenerateSTOP(I2C1, ENABLE);
24
    /*stop bit flag*/
25
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));

Also eben auf das Flag gewartet und nicht die Event-Funktion.
Hat das schonmal einer gemacht und möchte sich dazu outen? Wäre echt 
dankbar!

Grüße
Dennis
Gast #2581858
Lesenswert?

Langsam glaube ich dass da was in der Lib nicht stimmt:
1
  if(i2creg != 0)
2
  {
3
    /* Get the I2Cx SR1 register address */
4
    i2cxbase += 0x14;
5
  }
6
  else
7
  {
8
    /* Flag in I2Cx SR2 Register */
9
    I2C_FLAG = (uint32_t)(I2C_FLAG >> 16);
10
    /* Get the I2Cx SR2 register address */
11
    i2cxbase += 0x18;
12
  }

Warum zum Teufel wird I2C_FLAG, ein zu dem Zeitpunkt immer 8-Bit breiter 
Wert, ganze 16-Bit ins Nirvana geschoben. Ist doch klar, dass dann das 
Soll-Flag NULL ist, verglichen mit dem Registerinhalt ist das immer 
unwahr.

Gibts jemanden, der das zum laufen gebracht hat? Bitte melden, bin am 
verzweifeln.
#2581887
Lesenswert?

Dennis X. schrieb:

> Gibts jemanden, der das zum laufen gebracht hat? Bitte melden, bin am
> verzweifeln.

I2C funktioniert interrupt-basiert besser als in einfachen 
Aktion-warten-Aktion-warten Abfolgen. Die neigen dazu, sich in 
unerwarteten Situationen aufzuhängen. Wenn sich die Statemachine des 
I2C-Controller nicht exakt so benimmt, wie du es erwartest, dann ist 
Sense.

Mit Interrupts bestimmt hingegen die Statemachine die Aktionen des 
Programms. Man kann das auch ohne Interrupts machen, aber die 
Arbeitsweise sollte so sein, dass der Zustand der Statemachine die 
Handlungen des Programms bestimmt, nicht etwa das Programm auf einen 
bestimmten Zustand wartet. Das gilt für alle Arten von Controllern, ob 
AVR oder STM32.

Wenn dein Programm also hängen bleibt, dann solltest du überprüfen, ob 
die Statemachine sich tatsächlich dort befindet, wo du sie vermutest. Du 
solltest also beim Warten mal in die Statusregister reinsehen.
Gast #2581908
Lesenswert?

Hallo A.K. hab gesehn, dass du in einem anderen Thread auch bei den 
Interrupts und I²C geschrieben hast. Hast du vielleicht ein Beispiel. 
Initialisiert ist ja alles soweit, bei mir scheitert es daran, 
abzuwarten, ob und was auf dem Bus passiert.
Wär echt nett.
Dennis
#2581923
Lesenswert?

Dennis X. schrieb:

> Hast du vielleicht ein Beispiel.

Nichts was dir helfen würde. Ich gehe bei sowas anders an die Sache ran, 
und was dabei rauskommt ist eine C++ Klasse mit Abhängigkeit von einigen 
anderen selbstgebauten Dingen. Soll heissen, ich baue eine eigene 
Library, mit viel höherem Abstraktionsniveau als ST, und das ohne 
Verwendung der StdPeriphLib.
Gast #2582315
Lesenswert?

Phuu, hab ja grad auch nochmal eine Lib direkt von ST gefunden, doch bis 
die mal lief... Naja ich glaub ich schreib echt auch noch was eigenes. 
Man kann sich zwar ein weig damit anfreunden, doch was eienes ist 
einfach nochmal ein Stück vertrauter.

Danke nochmal!
Dennis

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren