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
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.
Vielen Dank für die schnelle Antwort, ich werde es gleich mal ausprobieren.
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?
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?
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.
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
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?
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).
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...
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.
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?
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...
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
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!
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?
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.
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
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 ;)
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
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 ;-)
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...
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
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??
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
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
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?
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
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?
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.
>> 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
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 :)
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?
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.
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.
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.
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?
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.