Hallo, ich möchte ein LCD-Display über SPI an mein Nucleo-64 (STM32F303RET6) anschliessen. Ich habe die Initialisierung entsprechend Referenzmanual Seiten 962-1004 ausgeführt (init_io.c). Wenn ich im main.c ein Testbyte über SPI ausgebe, sehe ich auf dem LA kein Signal an SCK und MOSI. Die Steuerbits in den Registern CR1 und CR2 habe ich mit dem Debugger überprüft und sie entsprechen init_io.c Wo liegt der Denkfehler ? Danke und Gruss Werner
Du sendest nur ein einzelnes Datenbyte, wirst also nur wenige Clock-Impulse erhalten. Hast du eventuell erwartet, dass da ein fortlaufendes Taktsignal erzeugt wird?
Stefan ⛄ F. schrieb: > Du sendest nur ein einzelnes Datenbyte, wirst also nur wenige > Clock-Impulse erhalten. Hast du eventuell erwartet, dass da ein > fortlaufendes Taktsignal erzeugt wird? Nein, ich erwarte genau 8 Taktsignale entsprechend 8-Datenbits, die ich mit dem Logicanalysor aufzeichne. Sowohl SCK als auch MOSI sind bei Ausgabe des Datenbytes permanent High. Gruss Werner
hast du es mal mit cuve mx und den dort vorhanden HAL-Funktionen versucht?
dummschwaetzer schrieb: > hast du es mal mit cuve mx und den dort vorhanden HAL-Funktionen > versucht? Nein, habe ich nicht, ich bin kein Freund von HAL, ich will verstehen was ich mache, Scheitern inbegriffen. Gruss Werner
Gibt es ein Datasize Register (in CR2)? Wenn ja, konfigurieren! Für 8-bit: SPI1->CR2 |= (0b0111ul << 8); Ggf. musst du eine Fifo auf 0 setzen, falls vorhanden? SPI1->CR2 |= SPI_CR2_FRXTH; Nur als Hinweis, was auf manchen Controllern gemacht werden muss:
1 | uint8_t send(const uint8_t cVal) { |
2 | uint8_t u8Result; |
3 | |
4 | *(volatile uint8_t*) &SPI1->DR = cVal; |
5 | while (!(SPI1->SR & SPI_SR_RXNE)); |
6 | u8Result = SPI1->DR; |
7 | |
8 | return u8Result; |
9 | }
|
Und zum Testen eignet sich immer in Dauerschleife zu senden.
:
Bearbeitet durch User
Ben S. schrieb: > Gibt es ein Datasize Register? Ja, im Controlregister CR2 Bit's 8..11 DS[3:0]= 0x7 > > Ggf. musst du eine Fifo auf 0 setzen, falls vorhanden? > SPI1->CR2 |= SPI_CR2_FRXTH; Habe es soeben ausprobiert, bringt leider keinen Erfolg. > > Nur als Hinweis, was auf manchen Controllern gemacht werden muss:uint8_t > send(const uint8_t cVal) { > uint8_t u8Result; > > *(volatile uint8_t*) &SPI1->DR = cVal; > while (!(SPI1->SR & SPI_SR_RXNE)); > u8Result = SPI1->DR; > > return u8Result; > } Genau diesen Vorschlag habe ich auch in der STM-Community gefunden und damit begonnen aber ohne Erfolg. Trotzdem danke für die Hinweise. Gruss Werner
Takte für Port, SPI, .. sind an? Kannst du die verwendeten Ports schalten? ggf HighSpeed im Speed-Register?
Die Hal ist aber auch kein Hexenwerk. Da könntest du mal schauen wie CUBE-MX den Port und die SPI initialisiert und mit deinenm vergleichen.
dummschwaetzer schrieb: > Takte für Port, SPI, .. sind an? Ja, siehe die ersten zwei Anweisungen in init_io.c. > Kannst du die verwendeten Ports schalten? Ja, ich kann das Signal CSB(NSS) eindeutig messen > ggf HighSpeed im Speed-Register? Habe ich schon probiert, bringt nichts, wäre bei 125KHz-SPI-Takt auch verwunderlich. Gruss Werner
dummschwaetzer schrieb: > Die Hal ist aber auch kein Hexenwerk. Da könntest du mal schauen wie > CUBE-MX den Port und die SPI initialisiert und mit deinenm vergleichen. Es gibt ja auch in CubeMX die Möglichkeit die "althergebrachten" Low-Level-Treiber zu verwenden. Der Sinn es Ganzen (eine genormte Schittstelle zu verwenden) wäre dass man keine Bits irgendwo vergisst zu initialisieren, sofern man die üblichen Initialisierungen von Clock-System, Peripherieclock, Peripherie-Enables, Ports, Alternativ-Funktionen (usw.) explizit aus dem höheren Level aufruft bzw. ausführt. Da es hier im Forum keinen schnell auffindbaren Link gibt, zeig ich mal einen von der "Konkurrenz": https://stackoverflow.com/questions/47972831/how-to-use-ll-low-level-drivers-in-cubemx-stm32
Beo Bachta schrieb: > Es gibt ja auch in CubeMX die Möglichkeit die "althergebrachten" > Low-Level-Treiber zu verwenden. > > https://stackoverflow.com/questions/47972831/how-to-use-ll-low-level-drivers-in-cubemx-stm32 Ich versuche gerade CubeMX zu installieren, Installation wird wegen falscher Java-Version abgebrochen. Muss mich zuerst schlau machen, wegen "richtiger" Java-Version.
Werner R. schrieb: > Ich versuche gerade CubeMX zu installieren Nachdem du darauf angesprungen bist, hier noch ein Beispiel (aus der Anwendung der älteren Standard Peripheral Library) wie ich das mache. Alle Initialisierungen in einer Funktion. Nicht ganz vollständig da die Bezüge (*.h) fehlen, aber man sieht wo es lang geht. In der CubeMX-Libt heissen die Aufrufe natürlich gerigfügig anders. Auffällig ist für mich jetzt dass man auch für die alternativen Peripherie-Funktionalitäten ein zusätzliches Clock Enable braucht.
Beo Bachta schrieb: > Auffällig ist für mich jetzt dass man auch für die > alternativen Peripherie-Funktionalitäten ein zusätzliches > Clock Enable braucht. Die von Dir beigefügte Inititialisierungsroutine ist identisch mit meiner, mit Ausnahme des Statements RCC_APB2PeriphClockCmd (RCC_APB2Periph_AFIO, ENABLE); Im Referenzmanual des STM32F1xx Seite 146 ist das Flag AFIOEN im Register RCC_APB2ENR (Bit0) beschrieben. Im Referenzmanual meines STM32F303 gibt es dieses Flag AFIOEN nicht, aber im Register RCC_APB2ENR (Bit0) steht dafür das Flag SYSCFGEN (System Configuration Controller). Ich habe SYSCFGEN gesetzt aber ohne Erfolg. Mit dem Flag SYSCFGEN und einem weiteren Flag SPI1_TX_DMA_RMP kann man DMA-Kanäle ummappen. Gruss Werner
Werner R. schrieb: > Nein, ich erwarte genau 8 Taktsignale entsprechend 8-Datenbits, > die ich mit dem Logicanalysor aufzeichne. Sowohl SCK als auch MOSI sind > bei Ausgabe des Datenbytes permanent High. Dann bleibt natürlich noch die Fehlerquelle dass du aus diesem singulärem Ereignis es nicht schaffst deine Aufzeichnung darauf zu triggern. Entweder du triggerst gar nicht oder die Software des Oszilloskops schafft es nicht das Ereignis "einzufangen". Eine Loop im 100usec-Takt würde helfen durch die Wiederholung Ereignisse aufzufangen bzw. die Triggerart und -Level richtig einzustellen.
Beo Bachta schrieb: > Dann bleibt natürlich noch die Fehlerquelle dass du aus diesem > singulärem Ereignis es nicht schaffst deine Aufzeichnung darauf > zu triggern. Entweder du triggerst gar nicht oder die Software > des Oszilloskops schafft es nicht das Ereignis "einzufangen". > > Eine Loop im 100usec-Takt würde helfen durch die Wiederholung > Ereignisse aufzufangen bzw. die Triggerart und -Level richtig > einzustellen. Ich habe jetzt Mal eine do-while Schleife in main.c mit 100us Delay programmiert. Sowohl das Speicher-Oszi als auch der SALEA Logicanalysor eingestellt auf SPI-Protokoll zeichnen jetzt SCK- und MOSI-Signale auf. Das Problem ist und war folgendes: Ich habe bisher immer im Einzelschritt (F5) das Programm getestet und immer HIGH auf SCK und MOSI erhalten, obwohl Oszi und LA getriggert haben. Durch die do-while Schleife in main.c habe ich das Programm durchlaufen lassen und siehe da SCK und MOSI erscheinen an PA5 und PA7. D. h. die SPI-Schnittstelle verhält sich im Einzelschritt anders als im Durchlauf. Das beigefügte Bild zeigt einen Einzelshot mit SCK (gelb) und MOSI (magenta). Dein Hinweis mit der Schleife war letztlich Gold wert und hat zur Problemlösung geführt. Nochmals Danke für Deine Ausdauer. Gruss Werner
Werner R. schrieb: > Das Problem ist und war folgendes: Verstehe die Symptome zwar nicht ganz, aber danke für die vorbildliche Rückmeldung!
Beo Bachta schrieb: > Werner R. schrieb: >> Das Problem ist und war folgendes: > > Verstehe die Symptome zwar nicht ganz, aber danke für die > vorbildliche Rückmeldung! Einfach formuliert im Einzelschritt gibt die SPI-Schnittstelle beim Befehl SPI1->DR = val; keine SCK- und MOSI-Signale aus im normalen Programmdurchlauf (selbst bei einmaligem Durchlauf, keine Schleife) erscheinen die Signale SCK und MOSI. Frag mich bitte nicht warum. Übrigens in dem Oszi-Bild das ich angehängt hatte werden 16 Takte für ein Byte ausgegeben. Wenn ich den Befehl SPI1->DR = val; durch *(volatile uint8_t*) &SPI1->DR = val; ersetze sind es genau 8 Takte bei einem Byte als Ausgabe. Gruss Werner
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.