STM32F1 HAL UART Senden nicht

OP #6776885
Lesenswert?

Hi,

aktuell bin ich ein Projekt mit der HAL von STM am umsetzen. Das Ding 
treibt mich gerade aber in den Wahnsinn... Ich habe ein simples neues 
Projekt in CubeMX angelegt um den Fehler zu reproduzieren / 
einzugrenzen.
Debug: Serial Wire
RCC -> High Speed Clock (HSE): Crystal/Ceramic Resonator
HCLK auf 72 MHz
USART -> Mode: Asynchronous
1
/* USER CODE BEGIN 2 */
2

3
  char data[5] = "test\n";
4
  HAL_UART_Transmit(&huart3, (uint8_t *)data, 5, 100);
5
  
6
  /* USER CODE END 2 */

Mehr Code habe ich dem generiertem Code von CubeMX nicht hinzugefügt.
Getestet wurde mit allen drei UART Schnittstellen, gemessen jeweils mit 
einem Oszi direkt am IC Pin (Für UART3 wurden die alternativen Pins 
genutzt). Der Pin ist High (3,3 V), aber es passiert sonst nichts. 
Erwarten würde ich einige High/Low Flanken. Am anderen Ende vom Pin 
hängt nichts.
Entstanden ist das ganze aus einem größeren Projekt wo ich den UART 
brauche. Das ging dann mal plötzlich (Signal auf dem Oszi beobachtet), 
nach einer Änderung wars aber vorbei damit. Änderung Rückgängig gemacht, 
Pin bleibt stur auf 3,3 V.
Was übersehe ich? Fehlt was? Warum wird nichts gesendet?

Programmer: ST-LINK/V2
IC: STM32F103RBT6
Board: Olimex P103 https://www.olimex.com/Products/ARM/ST/STM32-P103/
https://www.olimex.com/Products/ARM/ST/STM32-P405/resources/STM32-P103_P405_sch.pdf
Programmierumgebung: Visual Studio 2019 mit VisualGDB 5.5R5
build system: Ninja

Sollten noch Infos fehlen, reiche ich die gerne nach! Danke für eure 
Hilfe :)
Angehängte Dateien:
OP #6776923
Lesenswert?

Ich geh schon davon aus dass das Programm korrekt übertragen wird - 
hatte das Oszi vor dem Programmieren schon immer an dem entsprechenden 
Pin, da war er Low. Nach dem aufspielen ist der dann auf High gegangen.
Durch das Programm kann ich steppen. HAL_UART_Transmit kommt zurück mit 
HAL_OK. Die Fehler (HAL_BUSY oder HAL_TIMEOUT) werden nicht ausgelöst.
OP #6776937
Lesenswert?

Das passiert in der void HAL_UART_MspInit(), aufgerufen durch 
HAL_UART_Init(). Bin auch schonmal die Initialisierung durchgegangen wie 
sie in der HAL Doku angegeben ist. Das sieht soweit alles gut aus.
Andere Funktionen wie z.b. Timer im Output Compare, mit DMA oder Timer 
PWM mit DMA funktionieren auch tadellos. Nur der UART hat so gar keine 
Lust.
#6776944
Lesenswert?

Da würde ich vielleicht mal schnell ein anderes Programm generieren 
lassen (geht ja fix mit CubeMX) und damit nur den GPIO blinken lassen. 
Dann sieht man schon mal, ob es HW-mäßig geht.
Ich kenne dein Board nicht, mit den nucleos und anderen Dev-Boards hatte 
ich da bisher keine Probleme.
OP #6776968
Lesenswert?

Ja, messe an PC10. PC11 ist low. Ich hab das Scope auf Single-Shot 
gestellt und auf steigende Flanke die beim Reset entsprechend ausgelöst 
wird. Der TX Pin geht im Reset auf Low. In den 2sek danach ist nichts 
auf dem Bild zu sehen. Werde das aber mal in die Schleife packen und mit 
einem 200ms delay immer neu senden.
Gast #6776978
Lesenswert?

Packe das mal in die while() Schleife damit ein sich wiederholendes 
Signal erzeugt wird. Damit kommt dein Oszilloskop vermutlich besser 
klar.

Falls das klappt, können wir die korrekten Einstellungen deines 
Oszilloskopes besprechen, bzw. ob es diesbezüglich Schwachpunkte hat.
OP #6776981
Lesenswert?

Großer Speicher und scrollen machts möglich :)

Aber es geht jetzt... auch mit dem einzelnen gesendeten string. Mit dem 
Originalcode von oben. Ich glaube irgendwas stimmt in meiner Toolchain 
nicht. Entweder das Programm wird nicht sauber übertragen, oder der 
Flash nicht sauber gelöscht, oder sonst was läuft schief. Keine Ahnung.

Nachdem jetzt die anderen Programme nochmal drauf waren ist das Signal 
jetzt so wie es soll. Welch ein Spaß...


Ich danke euch! Jetzt hab ich die Bestätigung dass der Code korrekt ist 
und der Fehler irgendwo anders liegen muss.

Edit: Nochmal wegen dem Scope: Ich habe auf 500ms/div aufgezeichnet und 
dann auf 500µs rein gezoomt. 24M Speicher helfen da so ein einzelnes, 
wenn auch kurzes, Signal zu finden.
Gast #6777000
Lesenswert?

Auf dem Board sind ja noch UART1/2 rausgeführt, sind die belegt? Ich 
mache als erstes immer eine Ausgabe per seriell auf ein 
Terminalprogramm, da kann man auch eine Versionsnummer reinsetzen um 
Änderungen zu sehen. Wobei das Buildsystem natürlich schon zuverlässig 
sein sollte. Werden die Quelldateien vor dem kompilieren evtl. nicht 
automatisch gespeichert?
Gast #6777004
Lesenswert?

Harry L. schrieb:
> belegt 6 Zeichen im Speicher und nicht 5!

mit 4+1 komme ich schon auf 5 :)
Aber üblich ist es die Länge da wegzulassen und in der Ausgabe ein 
sizeof() zu verwenden. Auch bei Quick and Dirty.

ok, 5+1 wg \n.
Compiler können trotzdem besser zählen, gerade wenn man Tomaten auf den 
Augen hat.
#6777015
Lesenswert?

Harry L. schrieb:
> Der String:char data[5] = "test\n";
>
> belegt 6 Zeichen im Speicher und nicht 5!
> Am Ende hängt noch eine 0 als Terminierung.

Das Nullbyte wird nur angehängt, wenn noch Platz dafür ist.
Die Ausgabe rennt also weiter, bis irgendwann eine 0 gefunden wird.
Es kann aber auch sein, daß eine Exception erfolgt und der Code 
terminiert.
D.h. es wird nichts gesendet.
Gast #6778099
Lesenswert?

Ein recht verrückter Gedanke dazu:
Bei manchen neueren UART-Cores mit Fifo wird erst mit Senden begonnen, 
wenn der Fifo wenigstens einmal einen Stand von 2 Zeichen enthalten hat. 
Ist mir vor einiger Zeit bei einem LPC untergekommen und ich hatte mir 
einen Wolf gesucht nach einem Fehler meinerseits. Erst als ich diesen 
Umstand in einem Nebensatz im RefManual entdeckt und beim Setup 
berücksichtigt hatte, ging alles wie geschmiert.

Vielleicht hat ST den gerade in diesem Chip verbauten UART-Core von dem 
gleichen Core-Lieferanten bezogen wie NXP und das nicht ausreichend in 
seinen Setup-Routinen berücksichtigt.

Ja, ich weiß, es ist erstmal ne verrückte Vermutung.

W.S.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren