Hallo Freunde :-) Ich bin ein Anfänger mit STM32. Ich benutze CubeMX und OpenSTM32 AC6 zum Programmieren. Mein erstes Projekt ist ein OLED-Display (ssd1306) auf dem Nucleon F411RE-Board. Ich möchte die Header und Source Files für das Oled Display in OpenSTM32 importieren. Kann aber keine Import-Funktion finden. Kann mir jemand sagen wie das geht. Danke für die Hilfe. Rolf PS: LD2 blinkt schon ;)
Gast
#5960460
Du musst die *.h und *.c Dateien einfach ins src Verzeichnis legen. Wenn du magst, kannst du die *.h Dateien ins inc Verzeichnis legen. Ich mache das aber nicht so. Bei mir sind alle Quelltexte (außer HAL und CMSIS) im src Verzeichnis. Welche konkrete Bibliothek willst du denn verwenden?
Reicht es aus, wenn ich die Files mit dem Dateimanager in das entsprechende Verzeichnis kopiere ? Oder muss ich das in OpenSTM32 machen ?
Gast
#5960512
Rolf D. schrieb: > Reicht es aus, wenn ich die Files mit dem Dateimanager in das > entsprechende Verzeichnis kopiere ? Ja sicher. Falls die IDE die neuen Files nicht direkt anzeigt, markiere den Ordner (in der IDE) und drücke F5.
Hab noch Probleme mit der typdef struct
// Enumeration for screen colors
typedef enum {
Black = 0x00, // Black color, no pixel
White = 0x01, // Pixel is set. Color depends on OLED
} SSD1306_COLOR;
Error in der main.c: void ssd1306_Fill(Black);
Gast
#5960527
Rolf D. schrieb: > Hab noch Probleme mit der typdef struct Welche Probleme? Zitiere bitte die ganze Fehlermeldung.
Der Compiler zeigt error in der main.c "conflicting typs in ssd1306_Fill(Black)"
Gast
#5960543
Dann ist das Black wohl nicht eindeutig. Hier ist ein Lösungsansatz in C++: https://stackoverflow.com/questions/34319637/how-solve-compiler-enum-redeclaration-conflict In C würde ich die enums einfach durch #define ersetzen, weil mir dazu keine elegantere Lösung einfällt.
Danke für den Tip. Werde ich wohl so machen, da ich in C programmiere.
Rolf D. schrieb: > Der Compiler zeigt error in der main.c "conflicting typs in > ssd1306_Fill(Black)" Ich tippe mal du hast eine Funktion wie void ssd1306_Fill(unsigned somecolor) Wenn du jetzt dieser Funktion ein enum übergibst welches du per typedef zu einem Typ propagierst, dann meckert der Compiler zu recht, das die Typen nicht passen. Du hast zwei Möglichkeiten: Entweder du schreibst deine Funktion um, so dass sie den Typ "SSD1306_COLOR" akzeptiert, d.h. die Signatur wäre void ssd1306_Fill(SSD1306_COLOR somecolor) oder du führst einen Typecast durch wenn du die Funktion aufrufst, in etwa ssd1306_Fill((SSD1306_COLOR)Black)
Hab die Funktionen erst mal für eine normale int Var umgeschrieben.
Jetzt meckert der Compiler aber bei einer Funktionen fürs Display, als
ob das Header File nicht vorhanden wäre.
"Description Resource Path Location Type
undefined reference to `ssd1306_WriteCommand' ssd1306.c /Oled/Src
line 70 C/C++ Problem"´
// Send a byte to the command register
void ssd1306_WriteCommand(uint8_t byte) {
HAL_I2C_Mem_Write(&SSD1306_I2C_PORT, SSD1306_I2C_ADDR, 0x00, 1, &byte,
1, HAL_MAX_DELAY);
}
Gast
#5960601
>Jetzt meckert der Compiler aber bei einer Funktionen fürs Display, als >ob das Header File nicht vorhanden wäre. > >"Description Resource Path Location Type >undefined reference to `ssd1306_WriteCommand' ssd1306.c /Oled/Src undefined reference bekommt man immer wenn die Funktion vom Linker nicht gefunden wurde. Ist ssd1306_WriteCommand wirklich der Funktionsname? Buchstabe für Buchstabe richtig? Steht im Header ein Prototyp für void ssd1306_WriteCommand(uint8_t byte); ? Stimmt uint8_t für den Parameter? byte als Parametername würde ich sofort ändern.
Ich verwende diese Files: https://github.com/afiskon/stm32-ssd1306/tree/master/ssd1306
Gast
#5961139
Da fehlt ein -DSSD1306_USE_I2C in den Compiler Optionen.
Gast
#5961156
Ok. Danke. Werde es heute Abend mal ausprobieren.
Wo und wie genau trage ich das ein ?
Hab jetzt mal einen Test mit dem Anlegen eines neuen Header Files gemacht. Das merkwürdiger dabei ist, dass beim Anlegen eines neuen h.Files in AC6 das vorhandene Inc Verzeichnis nicht angezeigt wird und man keine Möglichkeit hat, ein neues Header File in diesem Verzeichnis anzulegen. Stattdessen habe ich das Source Verzeichnis benutzt und danach das Header File manuell in das Inc Verzeichnis verschoben.
Gast
#5961601
Ich habe jetzt nicht alles gelesen, aber hast Du AC6 mal seinen Index erstellen lassen? Index Rebuild
Gast
#5961702
Rolf D. schrieb: > Das merkwürdiger dabei ist, dass beim Anlegen eines neuen > h.Files in AC6 das vorhandene Inc Verzeichnis nicht angezeigt wird und > man keine Möglichkeit hat, ein neues Header File in diesem Verzeichnis > anzulegen. Die gehören da auch nicht hin. In ein include Verzeichnis gehören die Header von Libraries, die im Binärformat (ohne Quelltext) vorliegen. Das ist im µC Umfeld aber eine sehr seltene Ausnahme. Pärchen aus C-Quelltext und C-Header gehören ins src Verzeichnis, wenn sie nicht Bestandteil einer umfangreicheren Bibliothek sind, die außerhalb des Projektes liegt.
- index Rebuild: Kein Erfolg - Header nach Source verschoben: Kein Erfolg - clean und neu debug: Kein Erfolg Fehler "undefined reference.. " in der main
Gast
#5962309
Rolf D. schrieb: > Fehler "undefined reference.. " in der main Das ist doch ein Linkerfehler.
ja. Ich vermute dass es daran liegt, wie ich die h-files anlege. Da es keine Import-Funktion für Source- u. Header-Files gibt, habe ich leere c-Files u. h-Files über die Menü-Funktion in AC6 erzeugt und den Code für das Oled einfach hinein kopiert.
Gast
#5962326
Kann man einfacher über Drag and drop machen. Ist im main.c auch das nötige include drin? Bekommst du vorher beim kompilieren schon eine implicit declaration angemeckert?
Gast
#5962327
>Ich vermute dass es daran liegt, wie ich die h-files anlege.
Nein. Mein Post von 14:46 sagt was fehlt. Also tauch in die Untiefen
deiner
IDE und suche nach der Stelle wo man ein define für den Compiler
hinzufügen kann.
Da gibst du dann ein SSD1306_USE_I2C ein.
Die folgende Fehlermeldung ignorierst du einfach und bastelst da an den
völlig falschen Stellen rum:
#error "You should define SSD1306_USE_SPI or SSD1306_USE_I2C macro!"
Hab das hier probiert (Bild)... Aber keinen Erfolg !?
Gast
#5962385
Das Command-Line Pattern sollte normalerweise so aussehen:
> ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
Definitionen setzt bei Preprocessor unter "Defined Symbols (-D)"
Hab ich auch schon probiert !? Ergebnis: Fehlermeldungen (siehe Bild)
Gast
#5962414
Da nicht. Geh mal 2 tiefer, auf Preprocessor. Da sind schon welche. Kannst deins ohne -D einfach hinzufügen.
Gast
#5962422
Rolf D. schrieb: > Hab ich auch schon probiert !? Du hast dein Command-Line Pattern versaut. Ich habe Dir oben den richtigen String zitiert.
Gast
#5962426
"Restore Defaults" könnte das noch retten.
Ok. Hab das Command-Line Pattern wieder hergestellt und den Eintrag "SSD1306_USE_I2C" im Preprocessor gemacht. Jetzt gibt es keine Fehlermeldungen mehr. Da soll ein "STM32 Beginner" drauf kommen ;) Aber man lernt ja nie aus. Vielen dank für die tolle Unterstützung :) Gruß Rolf aus Wuppertal
Gast
#5962950
Hallöchen.. Ein kleines Problem gibt es noch. Nachdem ich das Projekt über Run gestartet habe tut sich auf dem ic2 Bus leider nichts. Pullups (1K) sind vorhanden. Oled ist richtig angeschlossen. Auf dem Scop ist wärend der Initialisierung und im Betrieb auf SDA und SCL kein Signal zu sehen.
Gast
#5962961
Dann musst Du wohl vergleichen, ob die Bezeichnung der Pins in der SSD1306 die Gleiche wie in allen für I2C zuständigen Quellen passt. I2C starten nicht vergessen.
Gast
#5963083
Was meinst du mit i2c starten. In der Main wird i2c init aufgerufen
Rolf D. schrieb: > Da soll ein "STM32 Beginner" drauf kommen Das hat nichts mir "STM32-Beginner"³ zu tun sondern mit "Eclipse CDT Beginner"² und vielleicht sogar mit "C-Beginner"¹. __ ¹,²,³) Es baut halt eines auf dem anderen auf, und zwar in der Reihenfolge der Fußnotennumerierung. Jetzt kämpfst Du halt an 3 Baustellen gleichzeitig.
Gast
#5963095
Ich fürchte mit Stichworten ist jetzt nichts mehr zu machen. Jetzt muss man die Quellen Schritt für Schritt durchgehen. Zur Not solltest Du das erst einmal mit einem funktionierenden I2C Beispiel vergleichen. Ist vermutlich nur ein kleiner Fehler wie Clock Enable, Pin Namen ....
Gast
#5963101
Ok. Vielen Dank für die Tips. Ich versuchs heute Abend noch einmal. Nie aufgeben ist meine Devise ?
Gast
#5963183
Rolf D. schrieb: > Da soll ein "STM32 Beginner" drauf kommen ;) Aber > man lernt ja nie aus. Das sind Grundlagen der Programmiersprache. Deswegen empfehle ich immer, die Sprache und die Entwicklungstools erstmal auf einem PC ohne Mikrocontroller kennen zu lernen. Selbst dieser Einstellungsdialog ist nicht für die IDE spezifisch. Jede andere IDE hat einen ganz ähnlichen Dialog, weil er letztendlich dazu dient, die Kommandozeilenparameter für den gcc zusammen zu basteln.
Hallo Stefanus.. Kleine Info über mich. Ich komme aus der Atmel Ecke und habe jahrelang mit Atmel Studio in C im Bereich der Musikelektronik gearbeitet. Mein größtes Projekte war der Degenerator. (Link: http://cczwei-forum.de/cc2/thread.php?threadid=5878&threadview=0&hilight=&hilightuser=0&page=34). So fremd ist mir das Ganze also nicht. Ich will erst einmal die Entwicklungsumgebung und die ARM Prozessoren kennen lernen und mit kleinen Projekten beginnen. Gruß Rolf
Ich komme nicht weiter. Auf dem i2c Bus rührt sich immer noch nix. SCL(D15) und SDA(D14) sind auf dem Nucleo-Board mit Pullups von 1.2K auf +3.3V angeschlossen. Slave Adresse vom Display (0x78) ist defeniert. Um Fehler auszuschließen, nutze ich die SSD1306 Lib vorerst nicht. Hab noch einmal ein neues Projekt mit IC2 in CubeMX generiert. Fürs senden von Daten benutze ich den HAL_I2C_Master_Transmit.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | |
198 | |
199 | |
200 | |
201 | |
Gast
#5964775
Rolf D. schrieb: > Ich komme nicht weiter. Auf dem i2c Bus rührt sich immer noch nix. Wie äussert sich das? Wenn du keinen I2C Slave der passenden Adresse angeschlossen hast ist nach dem ersten Byte das der Master sendet Funkstille. Ganz normal, denn der Master wartet nach der Adresse auf ein Ack vom Slave. Poste mal dein ganzes Projekt, ich versuche es dann mal auf einem Discovery-Board von mir anzuschauen.
Gast
#5964777
STM Unterstützer schrieb: > Poste mal dein ganzes Projekt Bitte auch das *.ioc File dazupacken.
Mmm.. Das OLED hat die Adresse 0x78 ! und ist angeschlossen. Auf dem Scope ist kein Signal zu erkennen. Auch wären der Initialisierung kein Signal. Alles bleibt auf High.
Hier mein Projekt..
Gast
#5964785
Rolf D. schrieb: > #define SLAVE_ADD_7BIT 0x78 > #define SLAVE_ADD_8BIT 0x78 << 1 Ich schaetze mal, hier ist wieder der beliebte i2c-Adresse-Fehler. Ich hab fuer mein Adafruit SSD1306 128x64 die Adresse 0x3C, also die Haelfte. leo
Adresse 0x3C kann nicht sein. In meinem Atmel Projekt funktioniert das Display mit Adresse 0x78. Aber ich teste es mal..
Die HAL-Funktionen erwarten die Adresse in den oberen 7 Bit. Ist also richtig so. Allerdings gibts auch Displays die auf 0x7a hören. Das kann man an den meisten Displays "umjumpern".
Nö.. kein Erfolg. Hätte mich auch gewundert ;)
Gast
#5964794
leo schrieb: > Ich schaetze mal, hier ist wieder der beliebte i2c-Adresse-Fehler. Ja, die OLED-Adresse 0x78 ist bereits die geshiftete Version.
Harry L. schrieb: > Die HAL-Funktionen erwarten die Adresse in den oberen 7 Bit. > Ist also richtig so. Aber er schiftet die 0x78 noch ein weiteres mal bevor ers ans HAL übergibt!
Hab die Adresse jetzt mal direkt benutzt. Aber ohne Erfolg.
1 | |
Aber auf den IC2 Leitungen müsste sich doch prinzipiell was tun. Auch wenn die Adresse nicht stimmt !?
Gast
#5964801
Rolf D. schrieb: > Hab die Adresse jetzt mal direkt benutzt. Aber ohne Erfolg. Nochmal meine Frage: STM Unterstützer schrieb: > Wie äussert sich das? Und versuche das mal genau zu beschreiben. Ein einzelnes Byte auf dem Bus mag für "den Anfänger" schwierig zu detektieren sein.
Wenn ich vor dem Problem stehe daß ich aus der Doku einer Hersteller-Library (z.B. HAL) nicht schlau werde und auch nicht die Nerven habe die Doku des eigentlichen Controllers Bit für Bit wieder rückwärts nach HAL zu übersetzen (ein nervenaufreibender Vorgang) dann versuch ich als nächstes einfach mal einen *funktionierenden Beispielcode* irgendwo aufzutreiben der die fragliche Peripherie in Betrieb nimmt und den dann zu verstehen und nachzuvollziehen.
Hab ein Digital Scope mit guten Trigger Eigenschaften ;)
Gast
#5964805
Rolf D. schrieb: > Aber auf den IC2 Leitungen müsste sich doch prinzipiell was tun. Auch > wenn die Adresse nicht stimmt !? STM Unterstützer schrieb: > Wenn du keinen I2C Slave der passenden Adresse angeschlossen > hast ist nach dem ersten Byte das der Master sendet Funkstille. Heisst also dass du pro HAL_I2C_Master_Transmit-Versuch genau ein Byte sehen könntest, aber auch nicht mehr.
Sind an den entsprechenden Pins schon die richtigen Alternate-Funktionen konfiguriert? Ist irgendwie schwer zu erkennen in dem ganzen HAL-Gestrüpp wo das passiert sein soll.
Gast
#5964808
Rolf D. schrieb: > auf dem Nucleon F411RE-Board. Du hast in deinem *.ioc File das falsche Board bzw den falschen Controller (nämlich STM32F103RBTx) gewählt.
Macht doch CubeMX automatisch oder ?
Gast
#5964813
Rolf D. schrieb: > Macht doch CubeMX automatisch oder ? Nein, alles Denken nimmt es einen nicht ab.
Hab aber in CubeMX Nucleo-F103RB ausgewählt
Rolf D. schrieb: > Hab aber in CubeMX Nucleo-F103RB ausgewählt Du hast aber geschrieben du hättest ein Nucleo-F411RE
Gast
#5964820
Rolf D. schrieb: > Hab aber in CubeMX Nucleo-F103RB ausgewählt Rolf D. schrieb: > dem Nucleon F411RE-Board. Willst du mich jetzt verarschen?
Das habe ich auch. Zur Zeit benutze ich aber das Nucleo-F103RB
Gast
#5964822
Rolf D. schrieb: > Macht doch CubeMX automatisch oder ? Rolf D. schrieb: > Hab aber in CubeMX Nucleo-F103RB ausgewählt Noch so eine Verarschung. Entweder automatisch oder ausgewählt .....
Gast
#5964826
Rolf D. schrieb: > Das habe ich auch. Zur Zeit benutze ich aber das Nucleo-F103RB Und das sollen wir riechen? Das ist das erste Mal dass du davon berichtest.
Gast
#5964828
Bei solcher Verarschung bin ich dann mal weg.
???? Um es noch einmal klar zu stellen. Ich benutze das Nucleo-F103RB.
Gast
#5964831
Rolf D. schrieb: > Um es noch einmal klar zu stellen. Um es einmal klar zu stellen: Eine Spur von Bedauern deinerseits könnte nicht schaden. Aber scheinbar hast du nichts falsch gemacht, nur wir haben nicht pingelig genug deine Salami-Scheiben abgefragt. Der Fehler liegt also nur bei uns ....
Hab m Rolf D. schrieb: > Macht doch CubeMX automatisch oder ? Ich hab mich da wohl etwas falsch ausgedrückt. Ich bitte um Entschuldigung. Was ich mit automatisch meine, ist das die Codegenerierung für die benutzen Chip-Funktionen die in CubeMX automatisch erstellt werden.
Rolf D. schrieb: > Was ich mit automatisch meine, ist das die Codegenerierung für die > benutzen Chip-Funktionen die in CubeMX automatisch erstellt werden. Und Du benutzt PB6 und PB7, ist das zutreffend?
Hier ist das von CubeMX erzeugte I2C.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
Ich hab mir deinen Code mal angeschaut. Was soll sowas?
1 | |
2 | |
3 | |
4 | |
Erwartest du, daß du deinem Display Klartext schicken kannst? Du kannst erstmal nur Pixel setzen/löschen. Das ist auch völliger Unfug:
1 | |
2 | |
3 | |
4 | |
0x78 ist bereits die 8bit-Version der Adresse. Die 7bit-Adresse ist 0x3c Wenn du unbedingt solche Defines bauen willst, dann bitte so:
1 | |
2 | |
3 | |
Und was hast Du getan um zu verifizieren daß sich an den Pins "nichts tut"? Hast Du die Pullups angeschlossen? Hast Du ein Oszilloskop angeschlossen mit beiden Kanälen auf SCL und SDA und auf fallende Flanke getriggert? Was hast Du gemessen? Bitte detailliert beschreiben oder Oszi-Screenshot beifügen!
Ich habe den Fehler gefunden. Die automatische Zuweisung von Pin PB6 und PB7 für I2C1 ist in CubeMX nicht richtig. Es müssen PB8 und PB9 sein. Habe die Zuweisung in CubeMX manuell geändert und schon läufts problemlos. @Bernd.K. Danke für deinen Hinweis. Im Anhang aktuelle Hardware Konfiguration in CubeMx und Scope Signale Vielen Dank an alle :)
Gast
#5964913
Vorab: Ich habe kaum Erfahrung mit Cube MX und HAL. Ich habe dein Programm auf meinem Nucleo Board (nur mit Pull-Up Widerständen und Logic Analyzer) ausprobiert und kann bestätigen, dass sich an den I²C Pins nichts tut. Die Initialisierung der I²C Schnittstelle geht noch, aber die Kommunikation bricht mit einer Fehlermeldung ab, die ich im angehängten Screenshot sichtbar gemacht habe. Es scheint sich um einen Kommunikationsfehler zu handeln. > SCL(D15) und SDA(D14) Das sind die Arduino Bezeichnungen. Die "richtigen" STM32 Port Nummern findest du auf der Papp-Karte, die in der Verpackung des Nucleo Boardes lag (und natürlich auch in der PDF Bedienungsanleitung). Jedenfalls sind das aus Sicht des Mikrocontrollers die Pins PB8 und PB9, die als alternative Funktion "I2C1 remap" haben. In deinem *.ioc File sehe ich allerdings nichts für diese Pins. Insofern bin ich ziemlich sicher, dass du die falschen Pins benutzt. Ich denke, du solltest dein Display an die Pins PB6 und PB7 anschließen. Das würde mit dem *.ioc File überein stimmen:
1 | |
2 | |
3 | |
4 | |
Dein nächstes Problem ist, dass die Funktion HAL_I2C_Master_Transmit() fehlschlägt, weil im Register I2C1.SR2 das busy Flag High ist. Im Referenzhandbuch steht dazu "Set by hardware on detection of SDA or SCL low". Jetzt habe ich mir mal die komplette Konfiguration in den Registern angesehen: CR1 = 1 Peripheral enabled CR2 = 100100 Peripheral Clock Frequency is 36 Mhz OAR1 = 100000000000000 "Should always be kept at 1 by software." OAR2 = 0 Ok DR = 0 Ok SR1 = 0 Keine Störung SR2 = 10 Communication ongoing on the bus Set by hardware on detection of SDA or SCL low, cleared by hardware on detection of a Stop condition. CCR = 1000000000011110 Fast mode, die unteren Bits habe ich nicht geprüft TRISE = 1011 habe ich nicht geprüft Bis hierhin habe ich noch keinen Fehler erkannt, bis auf dieses Busy Flag. Deswegen habe ich zur Probe mal die folgenden Befehle direkt vor die while Schleife eingefügt:
1 | |
2 | |
3 | |
Und siehe da: Es läuft (der angehängte Screenshot von PulseView beweist es). Ich vermute, dass beim Initialisieren ein Timing-Problem besteht oder die Hardware in der falschen Reihenfolge initialisiert wird. Denn wenn ich die while Schleife mal leer mache, so dass nur die Peripherie initialisiert wird, sehe ich die beiden Pins flackern. Das sollte schon nicht der Fall sein. Siehe angehängter Screenshot. Ich denke, diese Pulse bringen den Bus zum Blockieren. Dazu habe ich bei meinen eigenen bare-metal Programmierversuchen vor einigen Monaten Programmierversuchen etwas herausgefunden: Und zwar muss man zuerst den I²C initialisieren und erst dann die I/O Pins. Nur dann startet er sauber ohne falsche Impulse. Wenn ich in deinem Code die beiden Zeilen tausche, klappt es aber trotzdem nicht:
1 | |
2 | |
Ich denke, dass der eigentliche Fehler (mal wieder) in der HAl steckt, und zwar in der Funktion HAL_I2C_Init(). Diese ruft nämlich zuerst
1 | |
2 | |
auf, und initialisiert danach den I²C Controller. Das ist genau die falsche Reihenfolge - jedenfalls beim STM32F103. Beim STM32F303 wäre diese Reihenfolge Ok, nur mal so nebenbei bemerkt. Damit habe ich dein Problem noch nicht gelöst, aber zumindest eine Richtung zur weiteren Analyse gegeben. Ich hoffe es bringt Dich weiter. Nachtrag: Falls sich meine Antworten mit vorherigen überlappen, bitte ich um Entschuldigung. Ich habe eine ganze Weile gebraucht, um das Problem zu analysieren.
Hallo Stefanus. Vielen Dank für deine Hilfe. Du hattest natürlich recht. Mich hat CubeMX etwas in die Irre geführt. Grüße aus Wuppertal. Rolf
Gast
#5964923
Du hast ja jetzt erfolgreich andere Pins verwendet als ich. Ich würde trotzdem nochmal prüfen, ob die Initialisierung (mit leerer while-Schleife) korrekt abläuft. Auf den beiden Pins dürfen dann keine Impulse sichtbar sein. Falls doch, wirst du früher oder später wieder Probleme bekommen. Ich erinnere mich, dass dies hier öfters diskutiert wird. Irgendein Busteilnehmer blockiert bei Reset (oder Einschalten der Stromversorgung) sporadisch, dann sucht man sich einen Wolf. Ich bin ziemlich sicher, dass die Initialisierungsreihenfolge der HAL hier fehlerhaft ist.
Stefanus F. schrieb: > Ich bin ziemlich sicher, dass die Initialisierungsreihenfolge der HAL > hier fehlerhaft ist. Cube und HAL hat doch in erster Linie die Maker als Zielgruppe, da sind so Feinheiten doch nicht weiter tragisch.
Gast
#5964932
Das war übrigens mein fünfter Kontakt zur HAL, vier davon sind wegen nachweislicher Bugs fehlgeschlagen, nur einer war erfolgreich.
Dummerweise sind bei meinem "noName" Oled-Display auch noch die Bezeichnungen SDA und SCL vertauscht. Das Clock-Signal liegt auf SDA und die Datenleitung auf SCL. Blöde Sache.. ;)
Gast
#5964939
Stefanus F. schrieb: > HAL, vier davon sind wegen > nachweislicher Bugs fehlgeschlagen Du kannst die schon geshiftete I2C-Adresse auch dazuzaehlen. Das ist einfach ein Bloedsinn. leo
Das sind die "einfachen" Code Beispiele aus dem Internet die nie richtig funktionieren. Aber man lernt halt draus. Das finde ich wichtig :) Link: https://github.com/afiskon/stm32-ssd1306/tree/master/examples/i2c/stm32f1
Gast
#5964972
Ich wüsste auch gerne mal, warum die Platine mit den möchtegern Arduino kompatiblen Funktionen beschriftet ist, anstatt mit den "richtigen" Pinbezeichnungen des STM32. Oder: Warum gibt es keinen USB Anschluss für das Target? Für den niedrigen Preis sind das ja ganz nette Boards, aber ein paar kleine Details finde ich einfach nur gaga. Ich würde vorschlagen, das nächste Problem in einem neuen Thread zu diskutieren. Von der ursprünglichen Frage sind wir ja inzwischen schon weit entfernt.
Hallöchen.. Spaßeshalber hab ich mal die I2C Datenübertragung vom Nucleo-F103RB Bord (Master) zum Oled-Display (Slave) mit dem Scope überprüft. Die Übertragungsgeschwindigkeit ist im Test auf den Standartmode (100KHz) eingestellt. Maximal sind im Fastmode aber 400KHz möglich. Zur Info: Das SDA-Signal ist gelb und das SCL-Signal violett. Im 1.Bild ist nach der Übermittlung der Slave-Adresse (7 Bit) und dem ReadWrite-Bit (8.Bit) das Acknowledge-Bit (9.Bit) zu erkennen. Als Bestätigung für die richtige Adresse legt der Slave die Datenleitung auf low und signalisiert dem Master das er jetzt mit dem Senden eines Datenbyte beginnen kann. Im 2.Bild übertrage ich eine andere Adresse an den Slave. Das Acknowledge-Bit bleibt high und der Master stoppt die Übertragung zum Slave.
Gast
#5965544
Sieht gut aus. Ich denke, du kannst die Pull-Up Widerstände ruhig etwas hochohmiger machen.
Gast
#5965569
Die sind auf 4.7K
Gast
#5965593
Rolf Degen schrieb: > Die sind auf 4.7K Ok, würde ich so lassen.
Hallöchen.. Das Oled Display lebt ;) Hab den Code von afiscon in dem ssd1306.h File etwas anpassen müssen, weil Fehler beim compilieren auftraten. Aber sonst läufts prima :) Link zur benutzten Oled Lib: https://github.com/afiskon/stm32-ssd1306 Gruß Rolf
Hallöchen.. Macht richtig Spaß mit den kleinen ARM MCUs. Auf jeden Fall schneller als die AVRs. Hab mal eine kleines Audio Scope programmiert. Der komplette Projekt Ordner im Anhang. Link: https://youtu.be/3xvXjU5WA7M
Gast
#6002378
Hallo Rolf, der Audio Scope sieht gut aus. Im cc2 Forum fand ich den Artikel (STM32)über CubeMX sehr gut erklärt. Aber beim "SW4STM32 System Workbench" hätte ich einige Fragen: 1.Welche einstellungen sind zu treffen damit mann über die SWD den code übertragen kann (habe nur Cpu STM32f103 und v-link) ? 2. Wie ist die Ordnerstruktur ? <Wohin (ORDNER) SW4STM32 installieren > <Wohin (ORDNER) Projekt > <Wohin (ORDNER) SPL,HAL etc.> 3. Wie importiere ich ein fertiges Projekt zb. "OLEDScope" ? MFG Ali
Gast
#6002469
ali schrieb: > Welche einstellungen sind zu treffen damit mann über die SWD den code > übertragen kann Guck Dir das an: http://stefanfrings.de/stm32/system_workbench.html http://stefanfrings.de/stm32/stm32f1.html > Wie ist die Ordnerstruktur ? Ziemlich egal, weil du in der IDE in den Projekteinstellungen die ganzen Pfade konfigurieren kannst. Für Arbeiten mit HAL generiert Cube MX komplette Projekte mit passender Verzeichnisstruktur und Konfiguration. Für Projekte ohne HAL generiert die IDE selbst (File/New Project) die grundsätzliche Verzeichnisstruktur. Ich hab hier http://stefanfrings.de/mikrocontroller_buch2/Einblick%20in%20die%20moderne%20Elektronik.pdf ab Kapitel 9 einiges zur Verzeichnis-Struktur und der Konfiguration geschrieben. > Wie importiere ich ein fertiges Projekt zb. "OLEDScope" ? Steht auch in dem PDF. Schau dich mal im File Menü um, da findest du ganz viele spannende Funktionen, die zu deinen Fragen passen.
Gast
#6003455
Hallo Stefan,vielen Dank für die Links.
Habe Sie kurz überflogen,werde Sie aber noch genauer anschauen.
Ich finde die Tutorials sind sehr gut gelungen. {TOP 5 STERNE}
Frage zur : 9.1 Projektvorlage kopieren
Behandelt die IDE das kopierte Projekt „Test1“ danach als neues
eigenständiges Projekt?
Frage zur : 9.2 Projekt-Struktur
Wenn ich meinem Freund den Projekt-Ordner „Test1“ übergebe,müsste Es bei
Ihm genauso funktionieren.
{Denn da ist ja Alles drinn !!!}
Reicht Es wenn ER „Test1“ importiert ?
MFG
Ali
Gast
#6003651
Ali schrieb: > Behandelt die IDE das kopierte Projekt „Test1“ danach als neues > eigenständiges Projekt? Ja. > Wenn ich meinem Freund den Projekt-Ordner „Test1“ übergebe,müsste > Es bei Ihm genauso funktionieren. {Denn da ist ja Alles drinn !!!} Ja. Ich habe ja schließlich auch nur diesen einen Ordner (im ZIP Format) bereit gestellt, damit man ein fertiges Projekt zum Anfangen hat. > Reicht Es wenn ER „Test1“ importiert ? Ja
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.













