huehoet schrieb:> Habe ich irgendetwas vergessen/falsch gemacht?
Ja, du hast vergessen das I2C Protokoll zu lesen lernen
verstehen. Schau in Datenblatt eines Slaves.
Unter anderem verlangt das Protokoll das Senden von
Start- und Stop-Bedingungen.
I2C Unwissender schrieb:> Unter anderem verlangt das Protokoll das Senden von> Start- und Stop-Bedingungen.
Habe ich doch?
Vllt. habe ich zu vergessen, dass es im Programm so aufgerufen wird:
1
i2cInitialize();
2
i2cStart();
3
i2cWrite(address);
4
i2cWrite(data1);
5
i2cWrite(data2);
6
i2cStop();
Da sollte doch eigentlich über das Setzen der Start und Stop Bits die
Bedingung automatisch gesendet werden oder nicht? So habe ich das
eigentlich aus der Ref. Man. heraus verstanden.
Das ist eigentlich quasi der gesamte Source Code.
Dann eben noch die main.c:
[c]
#include "i2c.h"
int main(void)
{
i2c_init();
i2c_start();
i2c_write(0x78); /* address */
/* ... hier werden nur weitere Werte genauso übertragen; dies sind aber
magic numbers, die nicht weiterhelfen; es geht um die Ansteuerung eines
OLED Displays, die Werte funktionieren mit genau dem gleichen Code nur
anderem I2C mit einem AVR problemlos */
i2c_stop();
while(1)
;
}
Max M. schrieb:> Wenn du einen Logic Analyzer oder ein Oszi hast, am besten damit> mal die> I2C Pins messen.
Habe ich leider nicht. :/
SCL vom Slave ist dabei über einen 4.7kR Pull-Up auf 3.3V mit SCL vom
STM32 verbunden, SDA genauso.
Ich habe es jetzt noch einmal mit einem Arduino und Beispielcode, mit
dem es vorher auch funktionierte, probiert und jetzt geht das Display
irgendwie plötzlich nicht mehr.
Auch mit diesem I2C-Scanner Sketch für Arduino finde ich das Display
nicht. Ich verstehe aber nicht warum. 5V müsste das Display doch
eigentlich vertragen, hat es davor doch auch. Habt ihr noch irgendwelche
Ideen, wie ich überprüfen kann, ob das Display hinüber ist oder wie ich
das reparieren kann?
Ist ein 0.91" OLED Display mit SSD1306 Controller.
Ich wäre für jede Hilfe dankbar.
Also der LM6206N3, der als Spannungsregler daraufsitzt, gibt konstant
3.35V aus. Das müsste ja eigentlich soweit normal sein. Laut Datasheet
kann der auch bis zu 6.5V ab, das dürfte es also nicht sein.
Aber was kann denn sonst kaputt sein? Die 5V sollten dann ja eigentlich
nicht an dem LM6206N3 vorbeikommen, oder?
>> Wenn du einen Logic Analyzer oder ein Oszi hast, am besten damit>Habe ich leider nicht. :/
Dann aber schnell bestellen.
Für unter 10EUR gibt's Saleae Clones.
Wenn Du ihn jetzt nicht brauchst, dann beim nächsten Projekt.
Da mache ich mich derart verrückt und dann ist es am OLED Display das:
die Lötstellen hatten irgendwie keine ordentliche Verbindung.
Einmal neugelötet und das Display geht wieder.
Wobei auch nur am ATmega. Am STM32F103 geht es immer noch nicht.
Schnupfi schrieb:>>> Wenn du einen Logic Analyzer oder ein Oszi hast, am besten> damit>>>Habe ich leider nicht. :/>> Dann aber schnell bestellen.> Für unter 10EUR gibt's Saleae Clones.> Wenn Du ihn jetzt nicht brauchst, dann beim nächsten Projekt.
Wo findest du das?
Mit meinem Multimeter kann ich aber übrigens weder an SCL noch an SDA
eine Frequenz oder Spannung gegenüber GND messen.
Irgendetwas wird also wohl in dem obigen Code nicht stimmen.
Aber ich habe keine Ahnung, woran es liegen könnte. Ich habe eigentlich
alle Register, die ich im Refman gefunden habe, entsprechend
beschrieben.
Wenn alle Stricke reißen, kannst du zur Not noch Bit-Banging machen, wie
in diesem Projekt: http://stefanfrings.de/esp8266/WIFI-Kit-8-Test2.zip
Ich würde mich an deiner Stelle aber lieber in das Problem reinfuchsen.
Leider kann ich Dir nicht helfen, ich habe Hardware-TWI bisher nur auf
AVR genutzt.
huehoet schrieb:> Schnupfi schrieb:>>>> Wenn du einen Logic Analyzer oder ein Oszi hast, am besten>> damit>>>>>Habe ich leider nicht. :/>>>> Dann aber schnell bestellen.>> Für unter 10EUR gibt's Saleae Clones.>> Wenn Du ihn jetzt nicht brauchst, dann beim nächsten Projekt.>> Wo findest du das?
Wer zieht Dir eigentlich morgens die Hosen an?
"USB Logic Analyzer Device Set USB Cable 24MHz 8CH 24MHz"
Leider hat sich das Problem auch immer noch nicht gelöst.
Allerdings komme ich dem Problem vllt. langsam näher:
die Statusbits werden irgendwie nicht gesetzt, so z.B. das Bit SB bleibt
irgendwie immer 0.
Das müsste doch eigentlich auf 1 gehen, sobald das Startsignal generiert
wurde - und das sollte ja eigentlich passieren.
Weiß denn keiner, wo der Fehler liegt? Irgendwer wird doch schon einmal
mit einem STM32F103 I2C betrieben haben, oder nicht?
Ich habe jetzt auch noch einmal mit einem Debugger mir alle Register
angesehen und bin zu folgendem Ergebnis gekommen:
I2C1->SR1: 0x00
I2C1->SR2: 0x02 (busy)
I2C1->CR1: 0x501 (ack, start, enable)
I2C1->CR2: 0x24 (frequency at 36MHz (SYSCLK=72MHz))
RCC->APB1ENR: 0x200000 (I2C1EN)
GPIOB->CRL: 0xff484444 (PB6/7 af, od, 50mhz)
AFIO: MAPR: 0x00 (PB6/7 for I2C1)
Das heißt aber vermutlich, dass der I2C-Bus einfach irgendwie nicht
aktiv ist, obwohl alle Bits eigentlich gesetzt sind. Ich habe es jetzt
auch mehrfach mit der Ref. Man. und der Standard-Lib abgeglichen und es
entspricht eigentlich genau den Vorgaben.
Was mir noch oben als Fehler aufgefallen ist und was ich ausgessert
habe, dass ich den I2C-Reset nicht zurückgesetzt habe und dass in CR2
die falsche Frequenz geschrieben wurde.
Das macht aber irgendwie absolut keinen Unterschied.
Was vermutlich eher zutrifft, ist, dass das BUSY Bit die ganze Zeit
gesetzt ist.
Ich habe es jetzt einmal mit einem Timeout probiert, wenn BUSY direkt
nach der Initialisierung gesetzt ist, dass ich dann einfach noch einmal
die Initialisierung wiederhole. Aber irgendwie ist es direkt nach der
Initialisierung wieder gesetzt.
Ich habe jetzt auch einmal I2C2 ausprobiert, ebenfalls kein Erfolg.
Ich habe es jetzt noch einmal getestet und pull-up sowie das Display
entfernt und die Pins offen gelassen. Und schon wird SB gesetzt, genauso
wie START auf 0 gesetzt wird und sich der µC im Master-Mode befindet
(erkennbar an MSL).
Allerdings bleibt BUSY dabei die ganze Zeit gesetzt. Das verstehe ich
irgendwie nicht.
huehoet schrieb:> Ich habe es jetzt noch einmal getestet und pull-up sowie das> Display> entfernt und die Pins offen gelassen. Und schon wird SB gesetzt, genauso> wie START auf 0 gesetzt wird und sich der µC im Master-Mode befindet> (erkennbar an MSL).> Allerdings bleibt BUSY dabei die ganze Zeit gesetzt. Das verstehe ich> irgendwie nicht.
Als Anmerkung noch:
ich habe am Display einmal nachgemessen und zwischen SCL/GND und SDA/GND
jweils 250kOhm messen können, zwischen SCL/VCC und SDA/VCC besteht
allerdings keinerlei Verbindung. Kann sich das jemand erklären? Weil
eigentlich braucht I2C ja Pull-Ups und keine Pull-Downs.
huehoet schrieb:> Ich habe es jetzt noch einmal getestet und pull-up sowie das> Display> entfernt und die Pins offen gelassen. Und schon wird SB gesetzt, genauso> wie START auf 0 gesetzt wird und sich der µC im Master-Mode befindet> (erkennbar an MSL).> Allerdings bleibt BUSY dabei die ganze Zeit gesetzt. Das verstehe ich> irgendwie nicht.
Ich habe das noch einmal genauer untersucht:
Hier, direkt nach der Initialisierung habe ich jetzt kein gesetztes
BUSY-Flag, sondern nur BERR und STOPF, also eine empfangene
STOP-condition.
Sobald ich jedoch wieder die Pull-Ups anschließe, erhalte ich mein
BUSY-flag und ich lande in der loop. Neuinitialisierung nach einer
bestimmten Zeit in der Schleife bringt auch nichts.
Allerdings: sobald ich das START-bit setze, schaltet das BUSY-flag um
und wird auch nicht mehr gecleared. Dafür wird das STOPF-flag gecleart.
Aber wie gesagt, das alles nur bei offenen Pins.
Allerdings konnte ich jetzt auch irgendwie dabei nicht noch einmal
reproduzieren, dass SB gesetzt wird. Auch START in CR1 bleibt jetzt
gesetzt.
Es ist doch zum Verzweifeln. :|
huehoet schrieb:> Als Anmerkung noch:
Du siehst schon, dir antwortet wohl kaum einer da du schwarze
Magie betreibst.
huehoet schrieb:> zwischen SCL/VCC und SDA/VCC besteht> allerdings keinerlei Verbindung.
Warum sollte das der Fall sein? Ich sehen keinen Grund dafür.
Du kannst an einem Halbleiter-Eingang keine Aussagekräftigen
Widerstandsmessungen machen. Allerhöchstens könntest du bei
einem Widerstand nahe null Ohm aussagen dass der Eingang
defekt ist.
I2C Unwissender schrieb:> huehoet schrieb:>> Als Anmerkung noch:>> Du siehst schon, dir antwortet wohl kaum einer da du schwarze> Magie betreibst.
?
Das verstehe ich nicht.
> huehoet schrieb:>> zwischen SCL/VCC und SDA/VCC besteht>> allerdings keinerlei Verbindung.>> Warum sollte das der Fall sein? Ich sehen keinen Grund dafür.>> Du kannst an einem Halbleiter-Eingang keine Aussagekräftigen> Widerstandsmessungen machen. Allerhöchstens könntest du bei> einem Widerstand nahe null Ohm aussagen dass der Eingang> defekt ist.huehoet schrieb:> am Display
Ich messe zwischen den Anschlusspins des Displays um entscheiden zu
können, ob da nicht sogar vllt. schon ein Pullup vorhanden ist. Aber mir
fällt auch gerade auf, dass das eigentlich nichts zu bedeuten hat, da es
mit einem AVR ja funktionierte. Auch mit Pull-Ups.
Keine Angst, ich kam nicht auf die Idee, VCC/GND gegenüber SCL/SDA am µC
zu vermessen.
huehoet schrieb:> huehoet schrieb:>> am Display
Meinst du das Display ist kein Halbleiter? Was sonst?
huehoet schrieb:> Keine Angst, ich kam nicht auf die Idee, VCC/GND gegenüber SCL/SDA am µC> zu vermessen.
Schon die Ausdrucksweise und die Gedanken dahinter lassen
daran denken
I2C Unwissender schrieb:> da du schwarze Magie betreibst.
I2C Unwissender schrieb:> huehoet schrieb:>> huehoet schrieb:>>> am Display>> Meinst du das Display ist kein Halbleiter? Was sonst?
Die Anschlusspins. Wäre ein Pull-Up auf der Display-Platine, so wäre
dies vor dem Halbleiter.
Das ist aber auch vollkommen egal. Mir geht es um I2C und nicht um den
Widerstand.
> I2C Unwissender schrieb:>> da du schwarze Magie betreibst.
Wie genau kommst du auf diese Idee?
Hallo
Das hier:
I2C1->CR2: 0x24 (frequency at 36MHz (SYSCLK=72MHz))
heisst doch hoffentlich nicht dass der Bus auf 36MHz getaktet ist?
Als I2C Master musst Du den Takt auf ca. 250kBit einstellen - schau was
das Display kann...
Stefan G. schrieb:> Hallo> Das hier:>> I2C1->CR2: 0x24 (frequency at 36MHz (SYSCLK=72MHz))>> heisst doch hoffentlich nicht dass der Bus auf 36MHz getaktet ist?> Als I2C Master musst Du den Takt auf ca. 250kBit einstellen - schau was> das Display kann...
Es geht gerade erst einmal darum, dass die I2C-Communication überhaupt
funktioniert und die Bits von der Hardware passend gesetzt werden (siehe
z.B. das SB-bit).
Und nein, das ist der Takt von APB1. Das Maximum da ist 36MHz, ich habe
es aber auch schon mit 8MHz ausprobiert, keine Veränderung.
Siehe Ausgangspost ist der Bus auf 100kHz getaktet:
> /* frequency for SCL (clk); SM mode, 100kHz */> I2C1->CCR &= ~(I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR);> I2C1->CCR |= 0x28;
Noch etwas:
Wenn ich den Workaround aus dem Errata Sheet unter 2.13.7 verwende, dann
kriege ich es hin, dass die Bits nach dem Versenden der Start condition
richtig gesetzt werden (SB high, START cleared, MSL high). Aber es wird
schon wieder nicht das BUSY-flag gecleared, sodass das schon wieder auf
1 ist und bleibt. Es kann doch nicht sein, dass ich diesen Workaround
nach jedem Byte oder jeder Condition anwenden muss, oder? Kennt da noch
jemand eine andere Lösung?
Hallo huehoet,
ich bin gerade in einer ganz ähnlichen Situation wie du, ich versuche
mich auch gerade zum ersten mal an der I2C Schnittstelle des STM32. Also
eins muss ich mal mal sagen: Bei AVR ist das deutlich einfacher.
Die Prozedur im Referenzhandbuch wurde durch die Application Note AN2824
ergänzt. Leider widersprechen sich die beiden Dokumente ein wenig, und
in der AN wird ein Byte zu wenig ausgelesen. Die zahlreichen Tutorials
im Internet machen es noch komplizierter, wie sie so wie du ständig das
Busy Flag abfragen, was aber weder im Referenzhandbuch noch in der AN
empfohlen wird.
Jedenfalls habe ich es nun endlich erfolgreich hinbekommen, und zwar
indem ich primär nach dem Referenzhandbuch vorgegangen bin und dann die
Workarounds aus der AN hinzugefügt habe.
Das Ergebnis habe ich hier veröffentlicht:
Beitrag "Re: STM3103RBT6 ist mein I²C Master mit CMSIS so korrekt?"
Ich glaube es ist eine gute Idee, meine Code mit deinem zu vergleichen.
Ich habe aber gerade keinen Nerv mehr dazu, muss mal was anderes machen.
Programmieren strengt an.