Forum: Mikrocontroller und Digitale Elektronik STM32F4 I2C ACK bei 1.5V


von Reginald L. (Firma: HEGRO GmbH) (reggie)



Lesenswert?

Hallo!

Bin jetzt schon seit zwei Tagen vergeblich dabei, eine I2C-Verbindung zu 
dem TouchPanel Controller FT5206 aufzubauen.
Ich benutze die internen PullUps vom STM32. Sobald ich Send7BitAddres() 
losschicke, bekomme ich die in den Bildern ersichtlichen ACKs vom 
FT5206. Ich habe auch mal die Beschaltung mit hochgeladen. Wenn ich die 
Spannung zwischen 3.0V und 3.5V hin und herziehe, läuft der ACK dieser 
Differenz hinterher. Beachtenswert ist auch der kurze Peak zu Anfang des 
ACKs
Habt ihr eine Ahnung woran das liegt? Bin am Verzweifeln, habe sogar 
schon per Google (->Übersetzer) chinesische Foren durchsucht, aber sogar 
dort konnte ich nichts finden :>

Danke schonmal!

Grüße
Reggie

von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> Habt ihr eine Ahnung woran das liegt?

Ich kenn das von den kleinen zweizeiligen LCD-Controllern, die haben 
relativ hochohmige I²C-anschlüsse. Das einzige das Du tun kannst ist die 
Pullups größer zu machen.

So wie das auf dem Oszilogrammen aussieht kannst Du sie noch ganz 
erheblich vergrößern, erst wenn die aufsteigenden Flanken allzusehr 
verschliffen werden ist es zuviel. Bei Dir sind das noch richtig 
knackige Rechtecke, der Bus ist also noch sehr viel straffer als 
notwendig aufgehängt.

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Vielen Dank für die schnelle Antwort, ich werde es gleich mal 
ausprobieren.

von Bernd K. (prof7bit)


Lesenswert?

Ich bin mir übrigens nach kurzem Betrachten des geposteten Schaltplans 
auch noch nicht ganz sicher ob das Ding nun mit 5V oder mit 3.3V 
betrieben werden will.

Das ist wieder so ein typischer unsäglicher "Malen nach Zahlen"-Plan zum 
selber ausfüllen, extra unübersichtlich gemacht, das bereitet 
Kopfschmerzen. Irgendwo seh ich da 5V rumschwirren und der VDD3 (klingt 
schonmal nach drei (Volt?)) hängt an einem VDD_IO und das wiederum kommt 
von außen?

Wenn das ganze Ding auf 5V-Pegel ausgelegt ist dann wird das etwas 
umständlicher, dann kommst Du um irgend ne Mimik zum bidirektionalen 
Pegelumsetzen nicht umhin. Will das Ding 5V oder 3.3? Kannst Du das 
ausschließen?

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Also irgendwie tut sich da gar nix. Kann allerdings auch ein 
handwerklicher Fehler meinerseits sein, komme eigentlich aus der 
Maschinenbauecke.

Wenn ich einfach so einen Widerstand an 3.3V und I2C Data ranhänge, wird 
der Gesamtwiderstand ja niedriger (PullUp vom STM). Also habe ich die 
GPIOs auf GPIO_NOPULL gestellt. Da tut sich aber absolut nichts, dem 
Oszillogramm nach. Widerstände 10k - 100k bewirken auch rein gar nichts. 
Also habe ich den GPIO_Otype auf OpenDrain gestellt. Jetzt habe ich 
ausschließlich 0V aufm Oszi. Die Widerstände bewirken auch hier rein gar 
nichts.

Was ist eigentlich der Unterschied zwischen OpenDrain und 
GPIO_PushPull->NO_PULL?

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Bernd K. schrieb:
> Irgendwo seh ich da 5V rumschwirren und der VDD3 (klingt
> schonmal nach drei (Volt?)) hängt an einem VDD_IO und das wiederum kommt
> von außen?
>
> Wenn das ganze Ding auf 5V-Pegel ausgelegt ist dann wird das etwas
> umständlicher, dann kommst Du um irgend ne Mimik zum bidirektionalen
> Pegelumsetzen nicht umhin. Will das Ding 5V oder 3.3? Kannst Du das
> ausschließen?

Siehst ja woher das Sheet kommt ;)
Also nach dem Datasheet ist Versorgungs- und IC2-Spannung auf 2.8 - 3.6V 
ausgelegt. Die 5V sind für das TFT.

von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> Wenn ich einfach so einen Widerstand an 3.3V und I2C Data ranhänge, wird
> der Gesamtwiderstand ja niedriger (PullUp vom STM). Also habe ich die
> GPIOs auf GPIO_NOPULL gestellt.

Verwendest Du irgendein software-i²c oder das hardware-i²c Gerät im 
Controller? Denn wenn Du das per Bitbanging in Software machst musst Du 
natürlich den High-Pegel durch Abschalten der Treiber und Umschalten auf 
Eingang erzeugen, also emulation eines Open-Collector-Ausgangs, nicht 
durch Setzen des Ausgangs auf High.

Wenn Du allerdings die Hardware-I²C des Controllers verwendest dann 
sollte das mit der korrekten Konfiguration der Ausgangstreiber 
automatisch geschehen. Lies aber sicherheitshalber nochmal das Reference 
Manual des Controllers, vielleicht hast Du was übersehen, kann man beim 
STM32F4 nicht die Ausgänge explizit auf Open-Collector konfigurieren 
oder verwechsel ich da was? hab das Manual grad nicht da und wenig Zeit. 
Für interne Pullups alleine sieht das fast schon zu kräftig auf high 
gezogen aus, und wenn Du die internen Pullups abschaltest und trotzdem 
alles gleich bleibt dann sind da doch noch irgendwo anders Pullups am 
I²C-Bus.

Hängt sonst noch was an dem Bus?

Der Display-Controller versucht die Leitung beim ACK auf Low zu ziehen, 
schafft es aber nicht ganz. Er hat eventuell nur sehr schwächliche 
Treiber an den I²C-Leitungen oder noch Widerstände in Serie. Deshalb 
muss man es ihm so leicht wie möglich machen die Leitung weit genug auf 
Low ziehen zu können damit es zuverlässig als Low erkannt wird. Deshalb 
die schwächeren Pullups.

: Bearbeitet durch User
von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Bernd K. schrieb:
> Wenn Du allerdings die Hardware-I²C des Controllers verwendest dann
> sollte das mit der korrekten Konfiguration der Ausgangstreiber
> automatisch geschehen. Lies aber sicherheitshalber nochmal das
> Datenblatt. Für interne Pullups alleine sieht das ast schon zu kräftig
> aus und wenn Du sie abschaltest und trotzdem alles gleich bleibt dann
> sind da doch noch irgendwo Pullups am I²C-Bus.
Ich verwende den Hardware-I2C, habe mal kurz ins BitBanging 
reingeschnuppert und was aufm Oszi gesehen aber...wie gesagt, 
Maschinenbauer halt ;) Ich schau nochmal ins ReferenceManual, aber wie 
gesagt, hocke da schon seit zwei Tagen dran, keine Ahnung wie oft ich da 
schon reingeschaut habe.

Bernd K. schrieb:
> Hängt sonst noch was an dem Bus?
Also den techn. Zeichnungen nach, nein. Ich werde noch versuchen mit 
Jumpelkabeln zu überbrücken, vertraue den FFCs noch nicht so ganz.

Bernd K. schrieb:
> Der Display-Controller versucht die Leitung beim ACK auf Low zu ziehen,
> schafft es aber nicht ganz. Er hat eventuell nur sehr schwächliche
> Treiber an den I²C-Leitungen oder noch Widerstände in Serie. Deshalb
> muss man es ihm so leicht wie möglich machen die Leitung weit genug auf
> Low ziehen zu können damit es zuverlässig als Low erkannt wird. Deshalb
> die schwächeren Pullups.
Aaaah OK, so etwas habe ich mir schon gedacht. Warum macht er aber zu 
Anfang so nen knackigen Sprung auf 3.3V um sofort auf 1.8V zu hüpfen? 
Müsste es dann nicht eher so in Richtung e-Funktion aussehen?

von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> Ich verwende den Hardware-I2C, habe mal kurz ins BitBanging
> reingeschnuppert und was aufm Oszi gesehen aber...wie gesagt,
> Maschinenbauer halt ;) Ich schau nochmal ins ReferenceManual, aber wie
> gesagt, hocke da schon seit zwei Tagen dran, keine Ahnung wie oft ich da

Hast Du GPIO_OType_OD gesetzt für die beiden Pins? Kann sein dass das 
notwendig ist (OD = Open-Drain).

von Dr. Sommer (Gast)


Lesenswert?

Du musst definitiv SCL und SDA auf Open Drain stellen, sonst kann das 
nicht funktionieren! Beim STM32 geht das über OType (auch wenn man 
Software I²C machen würde). Wenn der STM32 auf "1" zieht und das Display 
beim ACK auf "0", erhälst du genau deine Spannung zwischen 0 und 1... 
Mit etwas Pech hast du dadurch auch das Display oder den I/O vom STM32 
gegrillt, denn das ist ja quasi ein Kurzschluss.
Normalerweise würde ich auch zu kleineren Pullups raten, wie 4.7kΩ. Zu 
große Pullups erkennt man an sehr runden steigenden Flanken.

Reginald L. schrieb:
> Aaaah OK, so etwas habe ich mir schon gedacht. Warum macht er aber zu
> Anfang so nen knackigen Sprung auf 3.3V um sofort auf 1.8V zu hüpfen?

Weil der STM32 erst auf 1 zieht, und ganz kurz danach das Display 
beginnt, auf 0 zu ziehen...

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Bernd K. schrieb:
> Hast Du GPIO_OType_OD gesetzt für die beiden Pins? Kann sein dass das
> notwendig ist (OD = Open-Drain).

Nee, jetzt mit Hardware I2C immer mit PP (keine Änderung zwischen 
PullUp/PullDown/NoPull). Natürlich habe ich OD auch ausprobiert, aber da 
tut sich gar nichts auf dem Bus, auch nicht mit externen 
PullUp-Widerständen.


Maaaan, das is mein 3. TFT, endlich einer mit dem ich zufrieden bin, 
kapazitives Touch hat und jetzt zickt I2C rum. Wenn diese Controller 
nicht so verdammt klein wären, hätte ich mir schon einen anderen 
bestellt und draufgelötet.

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Dr. Sommer schrieb:
> Weil der STM32 erst auf 1 zieht, und ganz kurz danach das Display
> beginnt, auf 0 zu ziehen...

Das Display hat mit dem ganzen aber nix am Hut, meinst du den TouchPanel 
Controller?

von Dr. Sommer (Gast)


Lesenswert?

Reginald L. schrieb:
> Natürlich habe ich OD auch ausprobiert, aber da
> tut sich gar nichts auf dem Bus, auch nicht mit externen
> PullUp-Widerständen.
Das heißt, permanent low? Dann hast du einen Kurzschluss. Mit PushPull 
kann es nicht funktionieren!

Reginald L. schrieb:
> Das Display hat mit dem ganzen aber nix am Hut, meinst du den TouchPanel
> Controller?
Äh ja natürlich, hab falsch gelesen, lies "Display" in meinem Post als 
I²C-Slave :)

Reginald L. schrieb:
> kapazitives Touch hat und jetzt zickt I2C rum
Die I²C-Einheit von den alten STM32, inkl. dem STM32F4, kann einem enorm 
viel Spaß generieren. Wenn du noch leicht wechseln kannst, wäre es 
empfehlenswert, einen neuen STM32 (STM32F3, F0, ...) zu nehmen mit der 
verbesserten I²C-Peripherie, die ist einfacher zu benutzen...

von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> Natürlich habe ich OD auch ausprobiert, aber da
> tut sich gar nichts auf dem Bus, auch nicht mit externen
> PullUp-Widerständen.

Probiers nochmal, bezw stell das ein und lass es so, OpenDrain ist 
definitiv die einzige korrekte Einstellung.

Ohne Pullups wäre der Pegel dann immer 0. Daran siehst Du dass die 
Einstellung gewirkt hat.

Und dann bringst Du Die Pullups ins Spiel und dann wird es anfangen zu 
funktionieren (und zwar externe Pullups), 4k7 ist ein guter erster 
Anfang, Du siehst dann am Oszi-Bild ob sie zu klein sind (ACK-Pegel zu 
hoch bei schwächlichen Slaves) oder ob sie zu gross sind (aufsteigende 
Flanken zu sehr verschliffen weil sie nicht mehr gegen die kapazitive 
Last ankommen). Aber 4.7k ist schonmal ne gute Schätzung für den Anfang.

: Bearbeitet durch User
von Reginald L. (Firma: HEGRO GmbH) (reggie)


Angehängte Dateien:

Lesenswert?

Dr. Sommer schrieb:
> Das heißt, permanent low? Dann hast du einen Kurzschluss. Mit PushPull
> kann es nicht funktionieren!

Das war der entscheidende Tritt den ich gebraucht habe -> OpenDrain -> 
PullUp -> siehe Bild. Das sieht für mich als Maschinenbauer schon viel 
angenehmer aus als diese gezackten Rechtecke ;)

Tausend Dank erstmal!! Bussi :)

Dr. Sommer schrieb:
> Wenn du noch leicht wechseln kannst, wäre es
> empfehlenswert, einen neuen STM32 (STM32F3, F0, ...) zu nehmen mit der
> verbesserten I²C-Peripherie, die ist einfacher zu benutzen...

Ich benutze einen F429IGT. F3, F0 sind für meine Anwendung nach 
Daumenpeilung zu langsam. Sind die F3 und F0 nicht schon älter?


Vielen Dank nochmals an alle (vorerst)!!
Mein Problem in 2Std gelöst, echt Top!

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Bernd K. schrieb:
> Aber 4.7k ist schonmal ne gute Schätzung für den Anfang.

Ja, je nach Clock, Kapa und Hardware, habe ich gelesen?

von Dr. Sommer (Gast)


Lesenswert?

Reginald L. schrieb:
> Das war der entscheidende Tritt den ich gebraucht habe -> OpenDrain ->
> PullUp -> siehe Bild.

Öh, ist das rote dein Takt? Sollte der nicht "High" sein im Ruhezustand? 
Und sind 10 Flanken nicht eine zu viel?

Reginald L. schrieb:
> Sind die F3 und F0 nicht schon älter?
Nö, neuer. Die Zahl gibt lediglich die Leistung an, nicht das Alter...

Reginald L. schrieb:
> F3, F0 sind für meine Anwendung nach Daumenpeilung zu langsam.
Sicher?? Die F3 sind auch Cortex-M4, nur der Takt ist niedriger. Es 
braucht schon ne ziemlich dicke Anwendung, um die auszureizen! Was ich 
vergessen hab: Die neuen F7 haben noch viel mehr Leistung als die F4, 
und haben die neue I²C-Peripherie.

von Bernd K. (prof7bit)


Lesenswert?

Dr. Sommer schrieb:
> Öh, ist das rote dein Takt? Sollte der nicht "High" sein im Ruhezustand?
> Und sind 10 Flanken nicht eine zu viel?

Doch das passt. Fast.

Am Anfang ist der Bus in irgend nem komischen Zustand, als ob er busy 
wäre. Dann kommt (ohne vorheriges Stop) ein Start (die erste fallende 
blaue Flanke). Dann kommen 9 aufsteigende rote Flanken. Danach bleibt 
der Bus busy (Takt low, Daten High).

Vermutlich ist seine Software noch nicht fertig und er sendet nur zum 
Test  immerfort ein Start gefolgt von einer Adressierung, aber noch kein 
Stop.

: Bearbeitet durch User
von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Dr. Sommer schrieb:
> Öh, ist das rote dein Takt? Sollte der nicht "High" sein im Ruhezustand?
> Und sind 10 Flanken nicht eine zu viel?

Das frage ich mich schon seit ich den Takt zum ersten mal gesehen habe! 
Und nein, es sind 9 Takte, der erste lange ist für den Start.

Dr. Sommer schrieb:
> Sicher?? Die F3 sind auch Cortex-M4, nur der Takt ist niedriger. Es
> braucht schon ne ziemlich dicke Anwendung, um die auszureizen! Was ich
> vergessen hab: Die neuen F7 haben noch viel mehr Leistung als die F4,
> und haben die neue I²C-Peripherie.

Ich benutze sogar noch einen F407 der nur für die Datenaufzeichnung 
verantwortlich ist und zwischendurch die Daten auf den F429 
rüberschiebt. Dieser ist nur für Ethernet, GUI und UART verantwortlich.
Da ich erst seit knapp einem Jahr in Elektronik und Programmierung 
eingestiegen bin, brauche ich Leistung. Bin doch Maschinenbauer ;)

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Bernd K. schrieb:
> Vermutlich ist seine Software noch nicht fertig und er sendet nur zum
> Test  immerfort ein Start gefolgt von einer Adressierung, aber noch kein
> Stop.
1
    Delay(250);
2
    I2C_GenerateSTART(I2C1, ENABLE);
3
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {};
4
    I2C_Send7bitAddress(I2C1, 0x70, I2C_Direction_Transmitter);

TOP! :)

EDIT: Im übrigen, bekomme ich jetzt ein ACK, das Kabel war im letzten 
Oszigram nur nicht angesteckt ;)

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> EDIT: Im übrigen, bekomme ich jetzt ein ACK, das Kabel war im letzten
> Oszigram nur nicht angesteckt ;)

Wenn Du da durch bist und Deinen Displaytreiber komplett fertig hast 
(ich schätze mal morgen früh kurz vor dem Morgengrauen) wirst Du mit 
allem I²C-Wassern gewaschen sein und kannst dem nächsten weiterhelfen 
der I²C-Probleme hat ;-)

von Dr. Sommer (Gast)


Lesenswert?

Bernd K. schrieb:
> Doch das passt. Fast.

Okay, aber ACK ist jetzt High, d.h. der Slave akzeptiert die Adresse 
nicht...

Reginald L. schrieb:
> Ich benutze sogar noch einen F407 der nur für die Datenaufzeichnung
> verantwortlich ist und zwischendurch die Daten auf den F429
> rüberschiebt.
Äääh...

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Also ohne die Einstellung "PullUp" geht gar nichts, entweder er hängt 
auf low oder auf high rum (je nach Widerstand). Auch wenn ich den 
gleichen Widerstand nehme, der im STM intern angelegt wird, tut sich 
nichts. Wenn ich allerdings auf "PullUp" stelle, kann ich die Flanken 
noch schön eckig (bäh) bekommen.

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> Also ohne die Einstellung "PullUp" geht gar nichts, entweder er hängt
> auf low oder auf high rum (je nach Widerstand). Auch wenn ich den
> gleichen Widerstand nehme, der im STM intern angelegt wird, tut sich
> nichts. Wenn ich allerdings auf "PullUp" stelle, kann ich die Flanken
> noch schön eckig (bäh) bekommen.

Eben hast du doch geschrieben es geht und sogar ein schönes 
Oszillogramm davon gepostet??

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Angehängte Dateien:

Lesenswert?

Bernd K. schrieb:
> Eben hast du doch geschrieben es geht und sogar ein schönes
> Oszillogramm davon gepostet??

Ja, ich blick durch die GPIO_OTypes irgendwie nicht durch. Habe bisher 
immer gedacht, sobald ich Push/Push reinmache, wird jedes mal einer der 
internen Widerstände angeknippst. Wenn ich in GPIO_OTypes OpenDrain 
einschalte, bekomme ich ohne Push/Pull aber gar nichts zu sehen, obwohl 
ich selber externe Pullups dran habe.

EDIT: Ach und noch was:
Kann ich per Oszi überhaupt sagen, ob ich jetzt die richtigen PullUps 
einsetze? Die Leitungen hauen doch auch wieder Kapa in den Bus?
Bekomme bei 50kHz immer noch Peaks. Habe 800Ohm an der Clock und 4,7kOhm 
an SDA.

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> sobald ich Push/Push reinmache, wird jedes mal einer der
> internen Widerstände angeknippst. Wenn ich in GPIO_OTypes OpenDrain
> einschalte, bekomme ich ohne Push/Pull aber gar nichts zu sehen, obwohl
> ich selber externe Pullups dran habe.

Also nochmal ganz langsam:

Push-Pull

Zwei Transistoren, einer high-side, einer low-side, abwechselnd 
geschaltet. Er wird die Leitung also immer entweder aktiv auf low oder 
aktiv auf high ziehen, mit aller Kraft die er hat, würdest Du also ein 
High ausgeben und der Slave würde gleichzeitig die Leitung auf Low 
ziehen (was zum Beispiel bei ACK passiert oder auch auf der Taktleitung 
beim Clock-Stretching) wäre das ein glatter Kurzschluss. Nicht gut.

I²C ist designed als "wired AND" auf beiden Leitungen, wenn ausnahmslos 
alle Teilnehmer eine 1 ausgeben wird der Bus 1, wenn auch nur ein 
einziger eine 0 ausgibt ist der Bus 0. Das bedeutet es muss so 
verschaltet sein daß das keinen Kurzschluss ergibt. Mit Push-Pull geht 
das nicht!

Die Lösung ist so simpel wie genial: der 1-Zustand wird nur von einem 
Widerstand nach + erzeugt, der 0-Zustand indem irgendwer den Bus aktiv 
auf 0 zieht. Jetzt kann jeder oder keiner oder irgendeiner den Bus auf 0 
ziehen wenn er eine 0 ausgeben will oder den Bus einfach nicht auf 0 
ziehen wenn er eine 1 ausgeben will. Wenn also alle eine 1 ausgeben 
(also keiner die Leitung nach unten zieht) dann ist der Bus 1, wenn auch 
nur einer zieht ist die Leitung 0. Aber es gibt keine Kurzschluss, denn 
keiner zieht jemals aktiv auf 1. Das ist "wired AND".

Open Drain

Der High-side Transistor fällt weg (oder wird per Konfiguration komplett 
deaktiviert) und stattdessen bringt man irgendwo am einer Stelle einen 
Pullup nach + an der high macht wenn kein anderer low machen will. 
Schon kannst Du "wired-AND" machen wenn alle Teilnehmer so 
konfiguriert sind.

Die Einstellung GPIO_OType_OD konfiguriert den Pin als Open-Drain.

> Kann ich per Oszi überhaupt sagen, ob ich jetzt die richtigen
> PullUps einsetze? Die Leitungen hauen doch auch wieder Kapa
> in den Bus? Bekomme bei 50kHz immer noch Peaks. Habe 800Ohm
> an der Clock und 4,7kOhm an SDA.

Das Oszi-Bild sieht eigentlich ziemlich gut aus. Es ist klar zu erkennen 
daß jetzt OpenDrain verwendet wird und es funktioniert.

Bitte poste mal die genauen Einstellungen die Du da verwendet hast als 
dieses Bild entstanden ist, den kompletten Code für die Initialisierung, 
der scheint nämlich laut Oszillogramm einwandfrei zu funktionieren. Du 
schreibst andauernd daß OpenDrain nicht geht und die Pullups nicht 
gehen, aber dann postest Du Bilder auf denen klar zu sehen ist dass 
OpenDrain verwendet wird und die Pullups das tun was sie sollen und daß 
Dein I²C-Bus sehr wohl funktioniert. Das ist widersprüchlich.

Warum verwendest Du unterschiedliche Werte für die beiden Leitungen? 
Wenn 4.7k bei SDA gehen dann geht der selbe Wert auch an SCL. 800 Ohm 
ist schon grenzwertig, warum so klein ohne Not? Und vor allem warum 
unterschiedlich? das ergibt keinen Sinn.

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> Wenn ich in GPIO_OTypes OpenDrain
> einschalte, bekomme ich ohne Push/Pull aber gar nichts zu sehen

Dieser Satz ergibt keinen Sinn.

* Entweder Push-Pull (falsch für I²C, tödlich geradezu)
* oder Open-Drain im Zusammenspiel mit externem Pullup (richtig)

Diese beiden oben genannten Alternativen schließen sich gegenseitig aus, 
insofern ergibt der zitierte Satz keinen Sinn, hast Du Dich vertippt?

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Klasse, dass du das so ausführlichst erklärst :) Bedeutet das, dass bei 
Push-Pull (GPIO_OType = GPIO_OType_PP) im Falle I2C ACK (Master High, 
Slave Low) die Spannung an diesen Transistoren abfällt? So ganz begreife 
ich es dann aber auch nicht: Nehmen wir an:

1
h_gpio.GPIO_OType = GPIO_OType_PP;
2
h_gpio.GPIO_PuPd = GPIO_PuPd_UP;
3
GPIO_SetBits(GPIOB, GPIO_Pin_4);
-> kein Kurzschluss?

1
h_gpio.GPIO_OType = GPIO_OType_PP;
2
h_gpio.GPIO_PuPd = GPIO_PuPd_UP;
3
GPIO_ResetBits(GPIOB, GPIO_Pin_4);
-> Kurzschluss?

Für den umgekehrten Fall, GPIO_PuPd_DOWN, genau anders herum? Und bei 
GPIO_PuPd_NOPULL -> kein Kurzschluss möglich? Ich bin schon so ein Vogel 
:>

Zu meinen Einstellung:

1
h_gpio.GPIO_OType = GPIO_OType_OD;
2
h_gpio.GPIO_PuPd = GPIO_PuPd_UP;
Funktioniert, wie auf dem letzten Oszigramm zu erkennen, mit und ohne 
zusätzliche externe PullUps. Ist auch meine aktuelle Einstellung.

1
h_gpio.GPIO_OType = GPIO_OType_OD;
2
h_gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
Funktioniert nicht, auch nicht mit zusätzlichen externen PullUps.


Hier die Initialisierung:
1
  // Clocks
2
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
3
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
4
5
  // Pins
6
  GPIO_InitTypeDef h_gpio;
7
  ZEROINIT(h_gpio);
8
  h_gpio.GPIO_Mode = GPIO_Mode_AF;
9
  h_gpio.GPIO_OType = GPIO_OType_OD;
10
  h_gpio.GPIO_PuPd = GPIO_PuPd_UP;
11
  h_gpio.GPIO_Speed = GPIO_High_Speed;
12
  h_gpio.GPIO_Pin =
13
    GPIO_Pin_6 |    // I2C CLK
14
    GPIO_Pin_7;      // I2C DATA
15
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
16
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
17
  GPIO_Init(GPIOB, &h_gpio);
18
19
  // Interrupts
20
  NVIC_SetPriority(I2C1_EV_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_4, 0, 0));
21
  NVIC_EnableIRQ(I2C1_EV_IRQn);
22
  NVIC_SetPriority(I2C1_ER_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_4, 0, 0));
23
  NVIC_EnableIRQ(I2C1_ER_IRQn);
24
25
  // I2C
26
  I2C_DeInit(I2C1);
27
  I2C_InitTypeDef h_i2c;
28
  h_i2c.I2C_Ack = I2C_Ack_Enable;
29
  h_i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
30
  h_i2c.I2C_ClockSpeed = 50000;
31
  h_i2c.I2C_DutyCycle = I2C_DutyCycle_2;
32
  h_i2c.I2C_Mode = I2C_Mode_I2C;
33
  h_i2c.I2C_OwnAddress1 = 0;
34
  I2C_Init(I2C1, &h_i2c);
35
36
  I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
37
  I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);
38
  I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);
39
40
  I2C_Cmd(I2C1, ENABLE);

Bernd K. schrieb:
> Warum verwendest Du unterschiedliche Werte für die beiden Leitungen?
> Wenn 4.7k bei SDA gehen dann geht der selbe Wert auch an SCL. 800 Ohm
> ist schon grenzwertig, warum so klein ohne Not? Und vor allem warum
> unterschiedlich? das ergibt keinen Sinn.
Durch die 800Ohm wird die Clock schöner. Reicht es die Widerstände so zu 
wählen, dass die Spannung des SDA kurz vor dem nächsten SCK auf high 
steht?

Bernd K. schrieb:
> Reginald L. schrieb:
>> Wenn ich in GPIO_OTypes OpenDrain
>> einschalte, bekomme ich ohne Push/Pull aber gar nichts zu sehen
>
> Dieser Satz ergibt keinen Sinn.
>
> * Entweder Push-Pull (falsch für I²C, tödlich geradezu)
> * oder Open-Drain im Zusammenspiel mit externem Pullup (richtig)
>
> Diese beiden oben genannten Alternativen schließen sich gegenseitig aus,
> insofern ergibt der zitierte Satz keinen Sinn, hast Du Dich vertippt?
Fast, damit meinte ich schon INKLUSIVE meinen externen PullUps aber mit 
h_gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> Zu meinen Einstellung:
>
> h_gpio.GPIO_OType = GPIO_OType_OD;
> h_gpio.GPIO_PuPd = GPIO_PuPd_UP;
> Funktioniert, wie auf dem letzten Oszigramm zu erkennen, mit und ohne
> zusätzliche externe PullUps. Ist auch meine aktuelle Einstellung.

Ok, die internen Pullups werden kaum schaden, die haben so um die 
50kOhm, deren Einfluss verschwindet gegenüber den um ne Größenordnung 
kleineren externen.

Wichtig ist die Einstellung GPIO_OType_OD. bei GPIO_OType_PP hättest Du 
einen Kurzschluss. Der Kurzschluss wird durch PP verursacht, die Pullups 
können keinen Kurzschluss machen, sind ja relativ große Widerstände, die 
sind ja genau dafür da daß man das eine Ende auf low ziehen kann ohne 
daß ein nennenswerter Strom fließt.

Anders wäre es bei PP, da prügelt die eine Seite aktiv auf high (push) 
und die andere Seite aktiv auf low (pull) -> Kurzschluss.

OD hingegen könnte man wenn man so will auch als "pull only, never push" 
bezeichnen wenn man im direkten Vergleich bei dem gedanklichen Bild mit 
dem Ziehen und Drücken bleiben will.

> h_gpio.GPIO_OType = GPIO_OType_OD;
> h_gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
> Funktioniert nicht, auch nicht mit zusätzlichen externen PullUps.

Das ist überraschend. Die externen Pullups sollten an die Stelle der 
internen treten und genau das selbe tun.

Ist vielleicht im Reference-Manual irgendwo eine entsprechende 
kleingedruckte Fußnote versteckt oder eine Erwähnung in irgendeinem 
Errata die dieses höchst überraschende Nichtfunktionieren mit einem 
bedauerlichen konstruktiven Mißgeschick und demzufolge ungeplantem 
Verweigerungshaltung der kompletten Hardware unter diesen Umständen 
erklärt?

von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> Reicht es die Widerstände so zu
> wählen, dass die Spannung des SDA kurz vor dem nächsten SCK auf high
> steht?

Es sind mehrere Dinge zu beachten:

Erstens (und wichtigstens) der im Datenblatt eines jeden Slaves der an 
dem Bus hängt angegebene maximale Strom den das jeweilige Gerät an den 
I²C-Pins versenken kann wenn es auf Low zieht, also betrachte von allen 
Slaves denjenigen mit dem geringsten erlaubten Strom, das gibt Dir 
zusammen mit der Betriebsspannung und dem Ohmschen Gesetz schonmal den 
kleinsten Widerstand der noch zu verkraften ist. Da hast Du schonmal 
eine Grenze nach unten.

Dann kommen Sachen ins Spiel die  gerne auf Chinesischen Datenblättern 
verschwiegen werden und erst im praktischen Betrieb auffallen, zum 
Beispiel (selbst erlebt) irgendwelche Displays mit Leiterbahnen auf Glas 
aufgedampft die diesen oben genannten erlaubten Strom bei weitem nicht 
treiben können und das im datenblatt keiner Erwähnug für nötig befinden, 
das sieht man dann auf dem Oszi, das kann die untere Grenze für den 
Widerstandswert nochmal nach oben rücken.

Dann kommen noch angestrebte Taktrate (oder die ernüchternd maximal noch 
mögliche unter diesen Umständen) bei gegebener Leitungskapazität hinzu, 
das kannst Du experimentell ermitteln, bei mir persönlich wäre Schluss 
wenn pi-mal-Daumen die Rundung oben links länger sichtbar ist als eine 
viertel Taktperiode.

Irgendwo in dem verbleibenden Raum suchst Du Dir dann den kleinsten noch 
tolerierbaren Widerstandswert und eine Taktrate mit der Du leben kannst.

von Bernd K. (prof7bit)


Lesenswert?

>> Reginald L. schrieb:
>>> Wenn ich in GPIO_OTypes OpenDrain
>>> einschalte, bekomme ich ohne Push/Pull aber gar nichts zu sehen

> Fast, damit meinte ich schon INKLUSIVE meinen externen PullUps aber mit
> h_gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;

Ha! Ich glaube ich weiß woher Deine Verwirrung kommt:


Da sind die Begriffe Push, Pull,
aber auch Pull Up und Pull Down.

Verwechslungsgefahr:

Push/Pull: aktiv: Push macht aktiv high, pull macht aktiv low. Also 
niederohmig, mit jeweil nem durchgeschalteten Transistor. Push: nach 
oben, high side, pull: nach unten, low side.

Pull-Up, Pull-Down Widerstand: Passiv, weich, schwach, mit nem 
Widerstand im Kiloohm-Bereich! Nicht zu verwechseln mit dem kräftigen 
aktiven Push oder Pull (ohne Widerstand) einer aktiven Push/Pull-Stufe.

Eigentlich müsste der Pull-up-Widerstand Push-Up Widerstand heißen um 
konsistent mit der Namensgebung einer aktiven Push/Pull-Stufe zu bleiben 
aber aus irgendeinem Grund hat man das nicht so genannt, bei 
Widerständen wird sprachlich gesehen nur gepullt. Ist sowieso nur eine 
Metapher, so oder so, Metaphern funktioniert immer nur bis zu nem 
gewissen Punkt und dann wirds verwirrend

: Bearbeitet durch User
von Reginald L. (Firma: HEGRO GmbH) (reggie)


Angehängte Dateien:

Lesenswert?

Bernd K. schrieb:
> Da sind die Begriffe Push, Pull,
> aber auch Pull Up und Pull Down.

Aaaaah ok, so weit so gut. Aber aus dem Blockdiagramm im ReferenceManual 
werde ich immer noch nicht schlau: Die AlternateFunction setzt doch mit 
der OutputControl entweder VDD oder VSS, der Strom läuft dann doch immer 
über den Transistor? Gott, bin ich froh nicht Elektrotechnik zu 
studieren, das wäre eine Schande für jeden leidenschaftlichen 
E.-Techniker da draußen :)

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Angehängte Dateien:

Lesenswert?

So schauts aus, wenn ich mit 100kHz I2C Clock fahre und je 4.7kOhm 
Widerstände dranhabe. Also zufrieden bin ich ja nicht :/

Was ist eigentlich der Vorteil von I2C? Ausser die wenigen Leitungen? 
I2C ist doch saulangsam. Mit SPI ist man doch besser bedient eigentlich, 
zumindest, wenn man die 1-2 Leitungen mehr Platz hat?

von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> OutputControl entweder VDD oder VSS, der Strom läuft dann doch immer
> über den Transistor?

OutputControl kann aber auch darauf verzichten den oberen Transistor 
jemals zu verwenden, und in der Tat geschieht das, je nachdem wie es 
konfiguriert ist oder was Du mit dem Pin machen willst.

Es kann entweder gar keinen der beiden Transistoren einschalten (zum 
Beispiel wenn Du den Pin als Eingang konfiguriert hast) oder immer 
jeweils einen von beiden anwechselnd (wenn es als Push/pull-Ausgang 
konfiguriert ist) oder immer nur den unteren (wenn es als open-drain 
konfiguriert ist) und es ist auch eine Konfiguration denkbar bei der nur 
der oberen Transistor genutzt wird. Da man das alles entweder direkt 
einzeln ansteuern kann über die vielen GPIO-Register wenn man will, oder 
auch vorgefertigte Konfigurationen wie "Open-Drain" oder "Push/Pull" 
oder "Eingang" verwenden kann ist so ein GPIO-Pin tatsächlich für fast 
jeden Zweck zu gebrauchen.

von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> So schauts aus, wenn ich mit 100kHz I2C Clock fahre und je 4.7kOhm
> Widerstände dranhabe. Also zufrieden bin ich ja nicht :/

Ja, das ist so grad an der Grenze, viel verschliffener würd ich sie auch 
nicht mehr sehen wollen. Wenn das Datenblatt des Slave sagt daß er mehr 
als 1mA treiben kann (z.B. 3mA ist meist so das Limit) dann kannst Du 
noch etwas runter gehen mit den Pullup-Widerständen.

von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> Was ist eigentlich der Vorteil von I2C? Ausser die wenigen Leitungen?
> I2C ist doch saulangsam. Mit SPI ist man doch besser bedient eigentlich,
> zumindest, wenn man die 1-2 Leitungen mehr Platz hat?

SPI wird ein bisschen unhandlich wenn mehr als ein Slave angesprochen 
werden soll. Aber wenn es von vornherein nur der eine Slave ist (oder 
der Microcontroller genug SPI-Einheiten besitzt und genug Platz auf der 
Platine ist) und Du die Wahl hast zwischen SPI und I²C dann nimm SPI.

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

Bernd K. schrieb:
> Es kann entweder gar keinen der beiden Transistoren einschalten
Und woher kommt dann der Arbeitsstrom?

Bernd K. schrieb:
> Ja, das ist so grad an der Grenze, viel verschliffener würd ich sie auch
> nicht mehr sehen wollen. Wenn das Datenblatt des Slave sagt daß er mehr
> als 1mA treiben kann (z.B. 3mA ist meist so das Limit) dann kannst Du
> noch etwas runter gehen mit den Pullup-Widerständen.
Haha, Slavedatenblatt, zur Belustigung hier mal der Link :)
Absolute Maximum Ratings auf Seite 8. Einzig der Stromverbrauch des 
Gerätes ist angegeben.
http://www.hpinfotech.ro/FT5206.pdf
Kann ich das mit dem Amperemeter messen, oder macht das aufgrund der 
zusätzlichen Kapa gar keinen Sinn?

Bernd K. schrieb:
> SPI wird ein bisschen unhandlich wenn mehr als ein Slave angesprochen
> werden soll.
Meinst du aufgrund der zusätzlichen Leitungen?

von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> Bernd K. schrieb:
>> Es kann entweder gar keinen der beiden Transistoren einschalten
> Und woher kommt dann der Arbeitsstrom?

Das ist doch nur ein Blockschaltbild, das dient nur dazu grob zu zeigen 
was von was angesteuert wird, da ist nur das Nötigste eingezeichnet um 
das nachvollziehen zu können. Dass die einzelnen Funktionsblöcke 
natürlich intern mit noch sehr viel mehr Transistoren vollgestopft sind 
und irgendwoher auch ihren Strom bekommen wird der Einfachkeit halber 
nicht hingemnalt (es sei denn es hätte was besonderes damit auf sich auf 
das man hinweisen will).

In dem konkreten Fall sind nur die beiden Ausgangstransistoren explizit 
hingemalt und angesteuert werden sie einzeln von $irgendwas und das 
einzige was hier interessant ist ist die Tatsache dass dieses $irgendwas 
tatsächlich zwei getrennte Ausgänge hat um die Transistoren einzeln 
ansteuern zu können wenn es Lust dazu hat.

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Reginald L. schrieb:
> Bernd K. schrieb:
>> SPI wird ein bisschen unhandlich wenn mehr als ein Slave angesprochen
>> werden soll.
> Meinst du aufgrund der zusätzlichen Leitungen?

Naja, entweder jeder Slave bekommt seine eigene chip-select Leitung 
hingelegt  (und man hofft dass MISO auch brav bei jedem hochohmig wird) 
oder man macht komplett getrennte SPI-Anschlüsse für jeden einzelnen 
oder in ganz wenigen Fällen (z.B. simple Schieberegister) oder wenn man 
die Slaves selber konstruiert hat kann man auch eine Daisy-Chain bauen 
(MISO des einen ist MOSI des nächsten) aber das geht nur in speziellen 
Fällen, das bietet sich nicht immer an oder ist meist gar nicht möglich.

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
Noch kein Account? Hier anmelden.