Hallo Community, Ich versuche seit gestern vergeblich ein I2C EEPROM am STM32F103C8T6 (Blue Pill Board, es ist aber glaubig ein Fake-uC auf dem Board verbaut da man ihm mit ST-Link GDB Server nicht programmieren kann es geht nur mit OpenOCD, weiß nicht ob es evtl. damit was zutun hat?) ans laufen zu bekommen. Als EEPROM verwende ich ein ST24C08WP, hatte zuerst ein Nagel neuen Chip genommen aber als er beim lesen immer nur 0xFF zurückgegeben hat obwohl ich ein anderen Wert vorher einprogrammiert habe. Habe ich irgendwann mal den gleichen EEPROM-Chip aus einem Gerät von mir genommen wo schon Daten drin sind und den ausprobiert. Es kamen dann auch andere Werte als 0xFF im unteren Adressbereich also habe ich den neuen EEPROM Chip mit einem ATMega328P testweise programmiert auf die Adresse 0x08 habe ich den Wert 0x18 geschrieben. Wenn ich mit dem STM32F1 die Adresse 0x08 auslese bekomme ich den Wert 0x18, gut schon mal das lesen funktioniert. Nur das schreiben will nicht. Da ich keinen Logikanalysator habe, habe ich mir das Signal mit meinem Oszilloskop angeschaut, und es versucht zu dekodieren(Beim AVR Bild habe ich es mit eingefügt beim STM32 sind mir immer wieder Unstimmigkeiten beim ACK aufgefallen). Deswegen auch Adresse 0x08 und 0x18 an Daten da diese Bits in der Mitte des Bytes liegen ist es einfacher sie zu erkennen. Das einzige was mir wirklich bei den beiden Schreibzugriffen zwischen AVR/STM32 auffällt ist das dass der ACK beim STM32 nur 1us statt fast 10us wie beim AVR dauert. Und das nachdem der ACK für die Daten kam die SCL Leitung noch weitere Zwei Clock Impulse liefert bevor die STOP Bedienung kommt. Jedoch passiert das gleiche beim Lesen mit dem STM32 auch und dort scheinen die Daten dem EEPROM ja wohl zu passen sonst würde er ja nicht die richtigen Daten zurückschicken. Der Chip scheint ja auch zu antworten den schließlich wird das "Address Match Bit" im SR1 Register gesetzt ohne EEPROM/Falscher Adresse bleibt der Code in der while Schleife hängen. Wie die Daten/Register "gefüttert" werden müssen habe ich mir aus dem "Transfer sequence diagram for master transmitter" Diagramm geholt. Ich habe mir dann heute morgen ein Tutorial Video angeschaut über den I2C Bus beim STM32 und konnte somit schonmal ein Fehler in meiner Schreibsequenz ausschließen da der Schreibcode identisch mit meinem war. Und bei ihm in Video konnte der damit Problemlos ein Atmel 2Kibit EEPROM beschreiben. Die I2C Frequenz liegt bei etwa 100KHz was auch der Maximale für den EEPROM Chip ist. Aber auch mit niedrigen Frequenzen wie 80KHz oder 50KHz macht es kein Unterschied. Lesen geht aber schreiben nicht. Die Frequenz des APB1 Bus liegt bei 36MHz. CPU selbst läuft auf 72MHz. CCR Wert ist 180 und TRISE ist 37. 4,7kOhm PullUp Widerstände sind extern am Bus vorhanden nach 3,3V. Mein Code habe ich mal als Datei angehängt(Habe ihn nur auf den I2C Schreibkram begrenzt da das auch mein letzter Test war um auszuschließen das andere Peripherie wie PWM, USART, SPI etc... die noch aktiv waren darein zu stören. Wenn dann die gelesen Daten 0x20 entsprachen ging die Onboard LED an(Sie ging aber nie an) Ich weiß nicht mehr weiter woran es liegen könnte. Habt ihr ne Idee? Mfg
Lesen und Schreiben wird in durch die Hardware des Controllers bestimmt, d.h. er generiert das R/W -Bit selber. Du kannst nicht einfach R/W zu der Adresse hinzufügen, dass macht der Controller selber wenn du ihn im entsprechendem Register sagst Lesen oder Schreiben. Das ist ne miese Falle...
Ingo Less schrieb: > Lesen und Schreiben wird in durch die Hardware des Controllers bestimmt, > d.h. er generiert das R/W -Bit selber Hallo, also im Datenblatt darüber konnte ich jetzt nix finden das er es selbst generiert. Ingo Less schrieb: > du kannst nicht einfach R/W zu > der Adresse hinzufügen, dass macht der Controller selber wenn du ihn im > entsprechendem Register sagst Lesen oder Schreiben Welche Bit soll das den in dem CR1/CR2 Registern sein? Habe gerade nochmal geschaut habe da nicht gefunden um den Bus es mitzuteilen das es nun eine Lese oder Schreibzugriff ist. Unter Start Condition steht: "Once the Start condition is sent: * The SB bit is set by hardware and an interrupt is generated if the ITEVFEN bit is set. Then the master waits for a read of the SR1 register followed by a write in the DR register with the Slave address" Mfg
Ingo Less schrieb: > Lesen und Schreiben wird in durch die Hardware des Controllers bestimmt, > d.h. er generiert das R/W -Bit selber. Du kannst nicht einfach R/W zu > der Adresse hinzufügen, dass macht der Controller selber wenn du ihn im > entsprechendem Register sagst Lesen oder Schreiben. Das stimmt in Bezug auf Bus lesen/schreiben, aber nicht in Bezug auf EEPROM lesen/schreiben. Beim EEPROM lesen wird auf dem Bus gelesen und geschrieben.
Felix N. schrieb: > Welche Bit soll das den in dem CR1/CR2 Registern sein? Sorry, grade gesehen das du einen F1 benutzt. Bei einem F0 ist es das Bit im RD_WRN im CR2 Register.
Felix N. schrieb: > Das einzige was mir wirklich bei den beiden Schreibzugriffen zwischen > AVR/STM32 auffällt ist das dass der ACK beim STM32 nur 1us statt fast > 10us wie beim AVR dauert. 1µs = 1MHz I2C-Takt. Manche EEPROMs können das, aber nicht jeder. Setze mal den Takt auf 100kHz runter. Felix N. schrieb: > Und das nachdem der ACK für die Daten kam die > SCL Leitung noch weitere Zwei Clock Impulse liefert bevor die STOP > Bedienung kommt. Das STOP muß immer direkt auf das ACK/NACK folgen. Da ist also eindeutig was faul in Deiner I2C-Lib.
Felix N. schrieb: > Das einzige was mir wirklich bei den beiden Schreibzugriffen zwischen > AVR/STM32 auffällt ist das dass der ACK beim STM32 nur 1us statt fast > 10us wie beim AVR dauert. Nein, ich glaube du verwechselst ACK und NACK. I²C ist open-drain, d.h. wenn der Gegenpart nicht antwortet (z.B. falsche Adresse) bleibt die Datenleitung high, was deswegen einem NACK entspricht. Nur wenn die Gegenstelle ihre eigene Adresse erkennt und aktiv die Datenleitung auf low zieht wird weitergemacht. Deswegen: ACK=low und NACK=high. Das ACK wird vom Empfänger in der steigenden Flanke des Neunten Bit übertragen. In der darauf folgenden fallenden Flanke lässt der Empfänger die Datenleitung nochmal los und der Sender übernimmt nochmal, deswegen siehst du da auf der Datenleitung immer diesen kurzen Puls. Beim AVR bleibt die Datenleitung während des neunten Bit high -> Der Empfänger antwortet nicht. Beim ST ist die Datenleitung während des neunten Bit low -> Der Empfänger ACK'ed die Anfrage, anschliessend übernimmt nochmal der ST (deswegen der kurze Peak auf der Datenleitung) Gruß, Holger
Harry L. schrieb: > Den WP-Pin (Pin 7) richtig beschaltet? Jo der WP Pin liegt auf Masse. Also nicht schreibgeschützt. Walter T. schrieb: > Das stimmt in Bezug auf Bus lesen/schreiben, aber nicht in Bezug auf > EEPROM lesen/schreiben Ingo Less schrieb: > Sorry, grade gesehen das du einen F1 benutzt. Bei einem F0 ist es das > Bit im RD_WRN im CR2 Register Ah ok alles klar. Peter D. schrieb: > 1µs = 1MHz I2C-Takt. Manche EEPROMs können das, aber nicht jeder. > Setze mal den Takt auf 100kHz runter. Eben nicht. Die Taktfrequenz des SCL Signals liegt ziemlich genau bei 100KHz. Habe ich gerade nochmal mit meinem Scope geprüft. Allerdings verhält sich das ACK Signal sehr komisch(Siehe Bild). Es erfolgt für etwa 9,7us eine Anhebung auf 660mV danach erfolgt dann für ca. 1us eine Anhebung auf 3,3V des Signals. Also das 10us Signal ist wohl da allerdings auf gerade mal 0,6V was definitiv als LOW erkannt wird. Deswegen hatte ich ja oben auch geschrieben das dieses der einzige Unterschied zum AVR Bild ist. Beim AVR-I2C ist der ACK 10us lang und geht direkt auf 5V hoch. Bei dem STM32 nur für 1us auf 3,3V der Rest ist 0,6V. Allerdings wenn ich von einer EEPROM Adresse lesen möchte sieht das Signal und auch das ACK Bit genauso aus. Und da scheint es ihm ja wohl nicht zu stören denn die Daten kommen ja richtig raus aus dem Chip. Peter D. schrieb: > Das STOP muß immer direkt auf das ACK/NACK folgen. Tut es ja auch siehe meine main.c das ist der letzte Code welcher dieses Signal erzeugt. Der Ablauf ist wie folgt: (1) START Bedienung (2) Adresse schreiben -> Generiert ACK (3) Antwort auf Adresse? (4) Interne EEPROM Adresse schreiben -> Generiert ACK (5) Wert ins EEPROM schreiben -> Generiert ACK (6) STOP Bedienung Die ACK Generation ist die ganze Zeit über aktiviert. So das nach jedem übertragenden Byte ein ACK generiert wird. Das ganze wundert mich halt auch weil beim lesen muss ich ja dem Chip erst durch ein Schreibefehl die Adresse zuweisen dann ein neuen Start auslösen und die Daten dann lesen. Was ja funktioniert, also scheint er die gesendeten Daten zu verstehen. Nur warum er das beim schreiben nicht tut ist mir ein Rätsel. Mfg
Holger schrieb: > Nein, ich glaube du verwechselst ACK und NACK. I²C ist open-drain, d.h. > wenn der Gegenpart nicht antwortet (z.B. falsche Adresse) bleibt die > Datenleitung high, was deswegen einem NACK entspricht. Hallo, also deuten diese ersten 0,6V für 9,8us auf ein ACK des EEPROM Chips hin. Sprich nachdem senden der Salveaddress das er diese erkannt hat? Und dann entsprechend auch das ADDR Bit im Mirkocontroller gesetzt wird? Holger schrieb: > Beim AVR bleibt die Datenleitung während des neunten Bit high -> Der > Empfänger antwortet nicht. Hmm, komisch die Daten wurden trotzdem rein geschrieben ins EEPROM. Also ich habe mir gerade nochmal das Datenblatt des ST24C08WP angeschaut dort steht der Byte Write so drin. Als erstes muss eine START Bedienung erfolgen worauf dann die Geräteadresse mit R/W Bit 0 erfolgen muss. Wenn diese richtig ist antwortet der Speicherchip mit einem ACK. Danach muss die Adresse für den internen EEPROM Speicher erfolgen. Das wird dann vom Chip wird mit einem ACK bestätigt. Dann wird das zu Speicherende Byte gesendet was wieder vom Chip mit einem ACK bestätigt wird dann kommt die STOP Bedienung. Ich verstehe das nun so das der EEPROM Chip die ACKs erzeugt und nicht der I2C Master also muss ich das ACK Generierungs Bit im CR1 Register deaktivieren? Mfg
Felix N. schrieb: > Holger schrieb: >> Nein, ich glaube du verwechselst ACK und NACK. I²C ist open-drain, d.h. >> wenn der Gegenpart nicht antwortet (z.B. falsche Adresse) bleibt die >> Datenleitung high, was deswegen einem NACK entspricht. > > Hallo, also deuten diese ersten 0,6V für 9,8us auf ein ACK des EEPROM > Chips hin. Sprich nachdem senden der Salveaddress das er diese erkannt > hat? Und dann entsprechend auch das ADDR Bit im Mirkocontroller gesetzt > wird? Ja, das würde ich so interpretieren. Felix N. schrieb: > [...] > Also ich habe mir gerade nochmal das Datenblatt des ST24C08WP angeschaut > dort steht der Byte Write so drin. https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwiOu-3-mKTyAhUImBQKHQlbCsoQFnoECAYQAw&url=https%3A%2F%2Fwww.st.com%2Fresource%2Fen%2Fdatasheet%2Fm24c08-r.pdf&usg=AOvVaw0P4YggHW9alYwr6HgoNzX- Auf dem Bild auf Seite 11 erkennst du das ACK einem low entspricht. Felix N. schrieb: > [...] > Als erstes muss eine START Bedienung erfolgen worauf dann die > Geräteadresse mit R/W Bit 0 erfolgen muss. Wenn diese richtig ist > antwortet der Speicherchip mit einem ACK. Danach muss die Adresse für > den internen EEPROM Speicher erfolgen. Das wird dann vom Chip wird mit > einem ACK bestätigt. Dann wird das zu Speicherende Byte gesendet was > wieder vom Chip mit einem ACK bestätigt wird dann kommt die STOP > Bedienung. > > Ich verstehe das nun so das der EEPROM Chip die ACKs erzeugt und nicht > der I2C Master also muss ich das ACK Generierungs Bit im CR1 Register > deaktivieren? Genau, das ACK wird immer vom Empfänger generiert. Für den Fall das du Daten an das EEProm schickst, ACK'ed das EEPRom jedes empfangene Byte. Die Daten werden in der Regel in einen temporären Buffer geschrieben und erst beim Empfang der STOP-Condition in den internen Speicher übernommen. Möglicherweise ist es für das EEPRom ein Problem das zwischen ACK und STOP-Condition noch ein Datenbit kommt, so das es auf das nächste Datenbyte wartet anstatt die Daten in den internen Speicher zu übernehmen. Ich glaube du musst beim ST die STOP-Condition setzen bevor das letzte Datenbyte gesendet wird, dann sendet er die STOP-Condition sofort nachdem er das ACK empfange hat. Gruß, Holger
Holger schrieb: > [...] Möglicherweise ist es für das EEPRom ein Problem das > zwischen ACK und STOP-Condition noch ein Datenbit kommt, so das es auf > das nächste Datenbyte wartet anstatt die Daten in den internen Speicher > zu übernehmen. Vergiss den Satz. In der Grafik im Datenblatt gibt es ebenfalls noch ein Clock Signal bevor die STOP-Condition kommt.
Die Nadel stört nicht, der Pegel darf sich wärend SCL = 0 ändern und wird mit der steigenden Flanke eingelesen. Die 0,6V low Pegel sind allerdings recht hoch, deutet auf zu kleinen Pullup hin. Es sollten nicht mehr als max 3mA fließen.
Holger schrieb: > Ich glaube du musst beim ST die STOP-Condition setzen bevor das letzte > Datenbyte gesendet wird, dann sendet er die STOP-Condition sofort > nachdem er das ACK empfange hat. Selbst wenn man es macht. Dann bleibt der I2C Bus im "Busy" Mode stecken. Peter D. schrieb: > Die Nadel stört nicht, der Pegel darf sich wärend SCL = 0 ändern und > wird mit der steigenden Flanke eingelesen. OK. Peter D. schrieb: > Die 0,6V low Pegel sind allerdings recht hoch, deutet auf zu kleinen > Pullup hin. Es sollten nicht mehr als max 3mA fließen. Du meinst die 0,6V als Low Pegel? Die Pullup Widerstände sind 4,7kOhm groß. Es fließt nicht mal ein mA. I = U/R -> 3,3V/4,7kOhm = 0,00070 A = 700uA. Aus den AVR Datenblätter kenne ich diese Formel zum Berechnen der Pullup Widerstände noch: Wenn fscl <= 100KHz. Rmin = Vcc - 0,4V / 3mA und Rmax = 1000ns/Cbus und bei fscl >= 100KHz Rmin gleich wie bei <=100KHz nur rmax = 300ns/Cbus Wenn ich das jetzt mal für 100KHz beim STM32 durchrechne: fscl=100KHz, Vcc=0,3V, I=3mA, Cbus=~8pF(Aus Datenblatt ST24C08WP) Rmin = 3,3 - 0,4V / 3mA = 966,667 Ohm -> 1kOhm Rmax = 1000ns/8pF = 125kOhm Allerdings muss ich sagen das es nun funktioniert .... Ich weiß nicht woran es lag. Ich hatte testweise die PullUp Widerstände gegen 1K getauscht da ich aber versehentlich in der Software die Geräteadresse um 2 nach linkes statt 1 geschiftet habe bekam ich erst keine Antwort vom Chip. Habe dann die Widerstände wieder zurück nach 4,7k getauscht und dann den Software Fehler behoben und auf einmal wurde der zuvor geschriebene Wert wieder ausgelesen. Habe dann noch ein paar andere Werte getestet, funktioniert jetzt wie es soll. Keine Ahnung ob es Kontakt Schwierigkeiten gab oder das tolle Steckbrett wieder Schuld ist. Die Signal fürs Scope habe ich direkt an den Widerständen abgenommen und nicht am IC Pin selbst. Werde noch ein paar Sachen damit testen, und dann meine Lib weiterschreiben um mehrere Bytes zuschreiben bwz. zu lesen das scheint ja auch wohl eine Besonderheit bei den STM32 I2Cs zu sein. Sagte trotzdem mal danke an alle die mir geholfen haben! DANKE mfg
Felix N. schrieb: > Allerdings muss ich sagen das es nun funktioniert .... > > Ich weiß nicht woran es lag. Ich hatte testweise die PullUp Widerstände > gegen 1K getauscht da ich aber versehentlich in der Software die > Geräteadresse um 2 nach linkes statt 1 geschiftet habe bekam ich erst > keine Antwort vom Chip. Habe dann die Widerstände wieder zurück nach > 4,7k getauscht und dann den Software Fehler behoben und auf einmal wurde > der zuvor geschriebene Wert wieder ausgelesen. Hast du vielleicht versucht direkt nach dem Schreiben die Daten zu lesen? Das eeprom puffert die Daten und schreibt sie erst in den internen Speicher wenn es die STOP-Condition empfängt. Der Schreibvorgang dauert einige Millisekunden und in der Zeit reagiert das eeprom auch nicht auf seine Adresse (NACK). Deswegen musst du nach einem Schreibvorgang einige Millisekunden warten bis du die Daten auslesen kannst. Wenn du wissen willst wann das eeprom mit dem Schreiben fertig ist, kannst du es so lange Adressieren bis es nochmal reagiert (ACK). Gruß, Holger
Holger schrieb: > Hast du vielleicht versucht direkt nach dem Schreiben die Daten zu > lesen? Nein ich hatte immer nur eins gemacht also Schreiben oder lesen. Weil ich mir das Signal ja mit meinem Oszilloskop anschauen wollte wenn ich schreibe und lese triggert das Scope nur auf das schreiben und das lesen konnte ich nicht mehr mit einsehen. Holger schrieb: > Deswegen musst du nach einem > Schreibvorgang einige Millisekunden warten bis du die Daten auslesen > kannst. Ich weiß im Byte Mode 10ms und im Multibyte Mode 20ms mindestens. Habe später 50ms gewartet. Ich vermute das es schlechter Kontakt von den Widerstände ans Steckbrett oder zwischen Steckbrett und EEPROM IC wahr. Holger schrieb: > Wenn du wissen willst wann das eeprom mit dem Schreiben fertig ist, > kannst du es so lange Adressieren bis es nochmal reagiert (ACK). Meinst du mit dem warten bis das ADDR Bit gesetzt ist? Mfg
Felix N. schrieb: > Holger schrieb: >> Wenn du wissen willst wann das eeprom mit dem Schreiben fertig ist, >> kannst du es so lange Adressieren bis es nochmal reagiert (ACK). > > Meinst du mit dem warten bis das ADDR Bit gesetzt ist? Während das eeprom Daten schreibt reagiert es nicht auf die eigene Adresse, die Datenleitung bleibt also im Neunten Bit also high (=NACK)). Das kannst du im Register SR1[ ADDR ] abfragen. Nachdem alle Neun Bits übertragen wurden (8 Adressbits + 1 ACK/NACK) steht dort nämlich das Ergebnis drin (0=NACK, 1=ACK). Falls dort eine 0 drin steht (NACK) kannst du es erneut versuchen, so lange bis du entweder ein Timeout erreicht hast oder das eeprom nochmal antwortet.
Wichtig ist für das Schreiben das abschließende STOP. Ohne STOP wird das Schreiben verworfen (z.B. Power off, repeated START).
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.