Forum: Mikrocontroller und Digitale Elektronik STM32F1 HAL UART Senden nicht


von Martin K. (dschadu)


Angehängte Dateien:

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 :)

von ... (Gast)


Lesenswert?

Um dem UART Zeichen zu entlocken, muss man ca. 5 bis 6 Register setzen.
Wenn du dazu nicht selber in der Lage bist...

von Klaus W. (mfgkw)


Lesenswert?

... schrieb:
> Um dem UART Zeichen zu entlocken, muss man ca. 5 bis 6 Register setzen.

Er hat eine MX_USART3_UART_Init().
Macht die was falsch?

Martin K. schrieb:
> Was übersehe ich? Fehlt was? Warum wird nichts gesendet?

Bist du sicher, daß dein Programm überhaupt geladen wird und läuft?

Kannst du reinsteppen?

von Martin K. (dschadu)


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.

von Phantomix X. (phantomix)


Lesenswert?

Du musst die Clock der UART irgendwo anschalten, passiert das?

bspw (weiß nicht ob das auf dem F1 auch so ist, bei dem H7 den ich 
aktuell am Wickel habe sieht das so aus):
1
__HAL_RCC_USART3_CLK_ENABLE();

: Bearbeitet durch User
von Martin K. (dschadu)


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.

von Klaus W. (mfgkw)


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.

von dummschwaetzer (Gast)


Lesenswert?

zeig mal deine MX-Einstellungen (die erzeugte pdf)

von Martin K. (dschadu)


Angehängte Dateien:

Lesenswert?

@Klaus:
Das Board schein i.O., ein anderes Programm für WS2812 LEDs gibt sauber 
Signale raus, auch das stepper-Programm (wofür ich die UART 
Schnittstelle brauche) gibt die Stepper-Pulse aus.

Im Anhang der gewünschte Report.

von Klaus W. (mfgkw)


Lesenswert?

Ich sehe da irgendwie keinen Fehler.

Du bist sicher, daß du am richtigen Pin misst?
(PC10, nicht PC11?)

Außerdem gibst du nur einmalig am Anfang aus, das ist vielleicht etwas 
schwer zu erwischen.
In der Schleife hättest du viel Zeit, etwas zu sehen.

von Martin K. (dschadu)


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.

von Klaus W. (mfgkw)


Lesenswert?

Wenn du auf dem Scope 2 Sekunden siehst, sind die 5 Byte aber ziemlich 
kurz im Vergleich dazu bei 115200 baud.
Das ist schon ein sehr dünner Strich...

von Stefan F. (Gast)


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.

von Martin K. (dschadu)


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.

: Bearbeitet durch User
von Harry L. (mysth)


Lesenswert?

Der String:
1
char data[5] = "test\n";

belegt 6 Zeichen im Speicher und nicht 5!
Am Ende hängt noch eine 0 als Terminierung.
Der Rest sieht korrekt aus.

von Johannes S. (Gast)


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?

von Johannes S. (Gast)


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.

von Peter D. (peda)


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.

von Johannes S. (Gast)


Lesenswert?

der Code sendet 5 Byte weil das so fix im Transmit drin steht, egal was 
er in dem String findet.

von W.S. (Gast)


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.

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.