mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32F030 / I2C EEPRom / Komisches Verhalten


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Markus S. (acepilot)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Versuche seid geraumer Zeit mit meinem STM32F030C8T6 eine stabile I2C 
Kommunikation hinzubekommen. Mittlerweile sehe ich aber den Wald vor 
lauter Bäumen nicht mehr. Programmiert wurde das ganze in der CoocCox 
IDE. Der Controller sitzt auf einer selbst entwickelten Platine und 
zeigt so auch keine Auffälligkeiten. An die ganzen Blockkondensatoren 
sowohl für den Kontroller als auch für das EEPROM wurden gedacht. Die 
I2C Busleitungen werden über 4k7 auf Vcc (3,3 Volt) gezogen. Der 
Kontroller läuft mit 44,236 MHz. Die I2C Timings wurden mittels der ST 
Excel Tabelle ermittelt.

Steppe ich durch mein Programm im Debugger Schritt für Schritt durch 
klappt alles und die Daten werden sauber in das EEPRom geschrieben. 
Versuche ich die Schreibfunktion im ganzen auszuführen schreibt er ein 
Byte, beim Versuch ein weiteres Byte zu schreiben bleibt er hängen und 
bekommt das I2C_FLAG_TXIS nicht gesetzt.

Aufruf der Schreibfunktion:
      EEPRom_Write(I2CDev,EEPROMAddr, 0x80, hbyte);
      EEPRom_Write(I2CDev,EEPROMAddr, 0x81, lbyte);

Implementation beschreibung des EEPROMS:
void EEPRom_Write(I2C_TypeDef* I2Cx, uint16_t address, uint8_t Reg, uint8_t Val) {
  //Wait until I2C isn't busy
  while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY) == SET);

  //"Handle"
  I2C_TransferHandling(I2Cx, address, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);

  //Ensure the transmit interrupted flag is set
  while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_TXIS) == RESET);

  //Send the address of the register we wish to write to
  I2C_SendData(I2Cx, Reg);

  //Ensure that the transfer complete reload flag is
  //set, essentially a standard TC flag
  while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_TCR) == RESET);

  //Now that the EEPROM knows which register
  //we want to write to, send the address again
  //and ensure the I2C peripheral doesn't add
  //any start or stop conditions
  I2C_TransferHandling(I2Cx, address, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);

  //Again, wait until the transmit interrupted flag is set
  while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_TXIS) == RESET);

  //Send the value you wish you write to the register
  I2C_SendData(I2Cx, Val);

  //Wait for the stop flag to be set indicating
  //a stop condition has been sent
  while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF) == RESET);

  //Clear the stop flag for the next potential transfer
  I2C_ClearFlag(I2Cx, I2C_FLAG_STOPF);
}

Damit bei Bedarf besser geholfen werden kann, habe ich auch noch das 
Komplette Coocox Projekt angehängt.

Wäre super, wenn jemand etwas Licht ins dunkle bringen könnte.

Gruß,
Markus

von hp-freund (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Moin,

habe kein Coocox, würde aber erst einmal die Takte prüfen.
Hast Du Messmöglichkeiten?

Wenn ja, die Möglichkeiten des MCO nutzen...
Ist die ms korrekt?

Weiterhin ist mir aufgefallen das deine eeprom.c viele \00 enthält.
Weiß aber nicht ob das eine Rolle spielt.

von Markus S. (acepilot)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo hp-freund, deine Vermutung geht schon einmal in die richtige 
Richtung. Habe gerade mal den I2C Bus oszillographiert. Ich konnte dabei 
kaum meinen Augen trauen. Das erste Oszillogram zeigt mehr als deutlich 
das die I2C Clock gegen 180kHz geht, was natürlich viel zu schnell für 
das EEPROM ist (scope_0.bmp).

Also habe ich darauf nochmal angefangen, alles von Anfang an zu 
kontrollieren. Verwendet wird ein 14,745 MHz Quartz. Mit den Coocox 
standard Projekten wird versucht den Takt über HSE und einen PLL 
Multiplikator von 6 zu erzeugen. Über diese gesamte Konfiguration kann 
man auch wunderbar drüber steppen. Nur 14,745 MHz mal 6 sind alles 
andere als 44,236 MHz. Ein wunder das der Controller das überhaupt 
mitgemacht hat und nicht viel früher ausgestiegen ist.

Nachdem ich dies korrigiert habe, sieht das zweite Oszillogram auch 
schon viel besser aus (scope_1.bmp). Und die Frequenz liegt zumindest in 
der richtigen Region, wenn sie auch nicht zu 100% getroffen wurde.

Leider ändert das noch nichts an dem beschreiben des EEPRoms. Ein 
wiederholtes lesen ist unbegrenzt möglich. Versuche ich Daten in das 
EEPROM zu schreiben bleibe ich beim selben Problem hängen das die I2C 
Flags nicht sauber ankommen.

Ich werde versuchen spätestens morgen nochmal den MCO Pin zu 
oszillographieren damit man ein vollständiges Bild bekommt.

Sollte noch jemand weitere Anmerkungen haben, sind diese herzlich 
willkommen.

von Markus S. (acepilot)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe gerade testweise nach jedem Aufruf der EEPRom Schreibfunktion 
ein Delay von einer Millisekunde eingefügt. Mit diesem Delay läuft auch 
das Beschreiben des EEPRoms ohne Probleme.

Da kann doch, meines Verständnisses nach, nur noch etwas an meiner 
Routine faul sein. Es kann ja nicht die Lösung sein ein Delay 
einzufügen...

von Schnulli (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Markus S. schrieb:
> Da kann doch, meines Verständnisses nach, nur noch etwas an meiner
> Routine faul sein. Es kann ja nicht die Lösung sein ein Delay
> einzufügen...

Die Lösung dürfte darin bestehen, daß man das Schreiben des vorherigen 
Bytes ins EEPROM auch abwartet. Das ist doch selbstverständlich!
Alternativ gibt es den page mode, bei dem auch mehrere Bytes - Anzahl 
steht im Datenblatt - am Stück geschrieben werden können und nur am Ende 
gewartet werden muß.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.