Forum: Mikrocontroller und Digitale Elektronik Assemblerprogramm zur Ausgabe eines Zeichens auf UART3


von Christoph K. (chriskuku)


Angehängte Dateien:

Lesenswert?

Ich rauf mir seit einigen Tagen die Haare ob eines kleinen Programms 
bzw. der Verifizierung meines Aufbaus hinsichtlich bluepill UART am 
macOS. Ich hänge das Assemblerprogramm mal an. Habe es auch direkt auf 
dem DISCO board laufen lassen und bekomme kein Zeichen aus dem PB10 des 
DISCO resp. DIYMORE Targets. Ist da ein Fehler im Programm? Baudrate? 
Clock? Eigentlich sollte doch ein 'X' auf der Leitung erscheinen, wenn 
ich in das DR schreibe. Da es das erste Zeichen ist, muß ich ja nicht 
auf RDY warten.

von PittyJ (Gast)


Lesenswert?

STM bietet mit CubeStm ein wunderschöne IDE. Darin kann man das Programm 
fast schon zusammenklicken.
Mach das doch einfach, und vergleiche dann das Kompilat mit deinem 
Asssembler-Code.

Ich glaube, bis auf C-Hater, wird hier kaum noch einer den STM in 
Assembler programmieren. Also warte auf C-Hater, dann wird dir geholfen.

von Christoph K. (chriskuku)


Lesenswert?

PittyJ schrieb:
> STM bietet mit CubeStm ein wunderschöne IDE. Darin kann man das Programm
> fast schon zusammenklicken.
> Mach das doch einfach, und vergleiche dann das Kompilat mit deinem
> Asssembler-Code.
>
> Ich glaube, bis auf C-Hater, wird hier kaum noch einer den STM in
> Assembler programmieren. Also warte auf C-Hater, dann wird dir geholfen.

Ich will natürlich nicht den Eindruck erwecken, also sitze ich in der 
Sonne und habe mein Programmierproblem mal auf den Backburner (aka 
µC.net) verschoben, um es von der cloud debuggen zu lassen. Habe den 
Fehler gefunden. Eigentlich wollte ich den Eintrag schon löschen, aber 
da Du jetzt geantwortet hast, geht es nicht mehr. Der Fehler war in 
dieser Zeile:

@ Turn on the clock for USART3.
  ldr r1, = RCC_APB1ENR
    mov r0, #0x00040000 @ USART3EN
@  movs r0, #0x00400000 @ USART3EN

Ich habe die Frage hier sicher nicht gepostet, um mich einem 
Assembler->C Bekehrungsversuch unterziehen zu wollen. Es geht um ein 
FORTH-System, das ich portiere bzw. portiert habe. Und das ist gänzlich 
in Assembler, FORTH und LISP geschrieben. Und an dieser Stelle hakte es. 
Weiß nicht, wie das movs da reingerutscht ist.


Was aber vielleicht bei dieser Gelegenheit noch interessant ist, zu 
beobachten: bevor das eigentliche 'X' ausgegeben wird, spuckt die 
Leitung noch ein '?' aus. D.h. die Initialisierung des UART erfolgt 
nicht ganz "lautlos". Eigentlich ist das nicht gewünscht und ich wüßte 
gerne, wie man es unterdrücken könnte. Vielleicht die Reihenfolge des 
Einschaltens der Register ändern?

Ich benutze das STM32CubeIDE übrigens zum Debuggen der 
Assemblerprogramme.

Habe mal versucht, aus den vorhandenen Bibliotheken ein Beispiel 
auszuwählen, das, was Du als "Zusammenklicken" bezeichnest. Das ist ja 
das totale Grauen, bis man da ein Beispiel gefunden hat und dann 
funktioniert das GUI auf einmal nicht, um es einzulesen.

Also danke erst mal und ein schönes Wochenende.

: Bearbeitet durch User
von Kevin M. (arduinolover)


Lesenswert?

Christoph K. schrieb:
> Habe mal versucht, aus den vorhandenen Bibliotheken ein Beispiel
> auszuwählen, das, was Du als "Zusammenklicken" bezeichnest. Das ist ja
> das totale Grauen, bis man da ein Beispiel gefunden hat und dann
> funktioniert das GUI auf einmal nicht, um es einzulesen.

Du nimmst CubeMX konfigurierst den UART, erzeugst den Code, fügst genau 
eine Zeile Code hinzu und er sendet dir das Zeichen....

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Christoph K. schrieb:
> Was aber vielleicht bei dieser Gelegenheit noch interessant ist, zu
> beobachten: bevor das eigentliche 'X' ausgegeben wird, spuckt die
> Leitung noch ein '?' aus.

Nö, eigentlich ist sowas zum einen nicht wirklich interessant und zum 
anderen ist es relativ leicht erklärlich: Wenn man einen UART aktiviert, 
ist nicht grundsätzlich der Sendepuffer leer und auch der momentane 
Zustand der Leitung und des Pins können irgendeinen Pegel haben. Deshalb 
sollte es nicht verwundern, wenn direkt nach dem Aktivieren noch irgend 
ein Glitch auf der Leitung ist, der dann eventuell als '?' vom 
Terminalprogramm im PC angezeigt wird. Also kein Grund zur Aufregung.

W.S.

von Christoph K. (chriskuku)


Lesenswert?

W.S. schrieb:
> Christoph K. schrieb:
>> Was aber vielleicht bei dieser Gelegenheit noch interessant ist, zu
>> beobachten: bevor das eigentliche 'X' ausgegeben wird, spuckt die
>> Leitung noch ein '?' aus.
>
> Nö, eigentlich ist sowas zum einen nicht wirklich interessant und zum
> anderen ist es relativ leicht erklärlich: Wenn man einen UART aktiviert,
> ist nicht grundsätzlich der Sendepuffer leer und auch der momentane
> Zustand der Leitung und des Pins können irgendeinen Pegel haben. Deshalb
> sollte es nicht verwundern, wenn direkt nach dem Aktivieren noch irgend
> ein Glitch auf der Leitung ist, der dann eventuell als '?' vom
> Terminalprogramm im PC angezeigt wird. Also kein Grund zur Aufregung.
>
> W.S.

Kann dem nicht zustimmen. Es muß definierte Anfangsbedingungen geben. 
Warum sollte nach einem RESET der Sendepuffer nicht gecleart sein? Es 
ist ja schon ein stationärer Zustand eingetreten, wenn das Programm 
gestartet wird. Ist ja nicht so, daß da der 380KV Strombügel angefahren 
wird. Der Glitch tritt ja auch auf, wenn die die Anwendung im IDE 
durchstarte.

von PittyJ (Gast)


Lesenswert?

Kevin M. schrieb:
> Christoph K. schrieb:
>> Habe mal versucht, aus den vorhandenen Bibliotheken ein Beispiel
>> auszuwählen, das, was Du als "Zusammenklicken" bezeichnest. Das ist ja
>> das totale Grauen, bis man da ein Beispiel gefunden hat und dann
>> funktioniert das GUI auf einmal nicht, um es einzulesen.
>
> Du nimmst CubeMX konfigurierst den UART, erzeugst den Code, fügst genau
> eine Zeile Code hinzu und er sendet dir das Zeichen....

So war es bei mir auch.
Und auf die HAL möchte ich auch nicht mehr verzichten, ich spreche keine 
Hardware-Register direkt an, das macht alles die HAL für mich.
Die Jungs von STM wissen recht gut, wie ein Uart anzusteuern ist. Da 
brauch ich die Arbeit nicht nochmals machen.

von Christoph K. (chriskuku)


Lesenswert?

Kevin M. schrieb:
> Christoph K. schrieb:
>> Habe mal versucht, aus den vorhandenen Bibliotheken ein Beispiel
>> auszuwählen, das, was Du als "Zusammenklicken" bezeichnest. Das ist ja
>> das totale Grauen, bis man da ein Beispiel gefunden hat und dann
>> funktioniert das GUI auf einmal nicht, um es einzulesen.
>
> Du nimmst CubeMX konfigurierst den UART, erzeugst den Code, fügst genau
> eine Zeile Code hinzu und er sendet dir das Zeichen....

Ja, ok. Kann ich auch mit CubeIDE machen. Ich dachte jetzt nur an diese 
Riesenbibliothek, wo man die Targets (Hersteller, etc. erst auswählen 
muß)

von Bauform B. (bauformb)


Lesenswert?

Christoph K. schrieb:
> bevor das eigentliche 'X' ausgegeben wird, spuckt die
> Leitung noch ein '?' aus. D.h. die Initialisierung des UART erfolgt
> nicht ganz "lautlos".

Der "lautlos"-Pegel am TX-Pin ist 3.3V. Während und nach dem Reset ist 
der TX-Ausgang hochohmig. Ohne externen Pull-Up floatet der theoretisch 
in die falsche Richtung.

Ist das '?' überhaupt ein 0x3F oder meint das PC-Programm "da kam 
irgendwas rein"? Ein echtes '?' sieht ja so aus ‾‾_‾‾‾‾‾‾__‾‾‾, das 
erzeugt man doch nicht mit Initialisierung in falscher Reihenfolge? Ein 
einzelnes Startbit bei 115200 könnte man damit erzeugen und deine 
Initialisierung erzeugt undefinierte Zustände am Pin. Ich hab' keinen 
Beweis, aber einen Verdacht...
1
// seit Reset bis jetzt ist der Pin hochohmig 
2
@ Set PORTB pins 10 and 11 in alternate function mode
3
// das ist erstmal AF0; AF0 ist undefiniert, vielleicht = 0?
4
@ Set alternate function 1 to enable USART3 pins on Port B
5
// jetzt ist es ein TX-Pin, aber das UART hat keinen Clock
6
@ Turn on the clock for USART3.
7
// was macht der Pin jetzt? Der Baudraten-Takt ist noch 0
8
@ Configure BRR by deviding the bus clock with the baud rate
9
// jetzt könnte es immernoch etwas dauern...
10
@ Enable the USART, TX, and RX circuit
11
// das sollte eigentlich keinen Unterschied mehr machen

Christoph K. schrieb:
> Ja, ok. Kann ich auch mit CubeIDE machen.

Warum solltest du? Die Hardware muss du sowieso verstehen, das RM0090 
musst du sowieso lesen und damit kannst du alles machen. HAL ist 
erstmal zusätzlicher Lernaufwand für weniger Möglichkeiten und am Ende 
suchst du zusätzlich noch die Fehler in den "Bibliotheken". Und, CubeMX 
und HAL sind bewegliche Ziele...

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Christoph K. schrieb:
> Kann dem nicht zustimmen. Es muß definierte Anfangsbedingungen geben.

Das ist eigentlich dein Problem, wenn du solche Forderungen erhebst.

W.S.

von Christoph K. (chriskuku)


Lesenswert?

Das Fragezeichen interpretiere ich auch nicht als echtes Zeichen 0x3f 
sondern ein glitch, den der empfangende UART bzw. das Terminalprogram 
'pico' anmeckert. Vielleicht stimmt der frame nicht. Oder es wird als 
Break interpretiert.

von W.S. (Gast)


Lesenswert?

Bauform B. schrieb:
> Ist das '?' überhaupt ein 0x3F oder meint das PC-Programm "da kam
> irgendwas rein"?

Auch ich tendiere zu letzterem. Einen Glitch kann es immer mal geben, 
wenn etwas gestartet wird oder ein Kabel eingesteckt wird.

W.S.

von Christoph K. (chriskuku)


Lesenswert?

Christoph K. schrieb:
> Das Fragezeichen interpretiere ich auch nicht als echtes Zeichen 0x3f
> sondern ein glitch, den der empfangende UART bzw. das Terminalprogram
> 'pico' anmeckert. Vielleicht stimmt der frame nicht. Oder es wird als
> Break interpretiert.

OC-Console unter Windows (mit eingeschalteter HEX-Anzeige) gibt einen 
CODE FF aus. Macht auch Sinn (alles '1').


Ich werde mal einen Versuch mit einem von MX generierten Programm machen 
und schauen, ob es da auch diesen Glitch gibt.

: Bearbeitet durch User
von Malte _. (malte) Benutzerseite


Lesenswert?

Mit einem Oszilloskop solltest du recht genau sehen wann da "Käse" auf 
der Uart Leitung liegt. Falls du keins hast, vermutlich reicht schon ein 
2. ARM der die Leitung schnell mit einem A/D Wandler "überwacht".

von Christoph K. (chriskuku)


Lesenswert?

Malte _. schrieb:
> Mit einem Oszilloskop solltest du recht genau sehen wann da "Käse" auf
> der Uart Leitung liegt. Falls du keins hast, vermutlich reicht schon ein
> 2. ARM der die Leitung schnell mit einem A/D Wandler "überwacht".

Hätte auch noch Pulseview mit einem DLA als Alternative zum Scope. 
Vielleicht schleppe ich das gleich auch noch zu meinem Aufbau. Aber erst 
nach dem CubeMX-Test.

von c-hater (Gast)


Lesenswert?

Christoph K. schrieb:

> Ich werde mal einen Versuch mit einem von MX generierten Programm machen
> und schauen, ob es da auch diesen Glitch gibt.

Grundsätzlich mußt du bei UART-Kommunikation nach einem Reset oder beim 
Startup deiner Seite IMMER mit einem "Glitch" rechnen. Das hat nix mit 
MX vs. nicht MX oder C/C++ vs. Assembler zu tun, sondern ergibt sich 
schlicht daraus, dass der Peer IMMER senden kann, egal in welchem 
Zustand deine Seite der Kommunikation ist.

Du musst obendrein beachten, dass es zwei Ausprägungen des "Glitch" 
geben kann.

Das eine ist der Glitch auf der Ebene einen Datenworts. Das kann man 
u.U. erkennen, aber nicht 100&ig zuverlässig. Anzeichen sind natürlich 
Frame- oder Parity-Fehler.

Das andere ist ein Glitch auf der Ebene des Anwendungsprotokolls. 
Sprich: du fängst mit Lesen mitten in einer (wie auch immer 
konstruierten) Nachricht des Peers an. Mit ein wenig Pech an einer 
Stelle, an der auf Wort-Ebenen kein Fehler erkennbar wird, das erste 
empfangenen Wort der Nachricht aber trotzdem fehlerhaft ist. Auch dieser 
Fall muss korekt behandelt werden. Das wird um so schwieriger, je 
dümmlicher das Anwendungprotokoll designed wurde.

von Christoph K. (chriskuku)


Angehängte Dateien:

Lesenswert?

Christoph K. schrieb:
>...
> Ich werde mal einen Versuch mit einem von MX generierten Programm machen
> und schauen, ob es da auch diesen Glitch gibt.

Leider klappt es nicht so recht mit der Kompilation des MX 
uarttest-Programms. Habe den .ioc ins STM32CubeIDE eingelesen, aber es 
fehlt im Grunde die Runtimelibrary. Und den Assemblercode (C-Compilat) 
würde ich ja ohnehin nur in der Runtime-Library finden. Ich poste mal 
den .ioc-File. Vielleicht gelingt es jemand, daraus was zu machen. Ich 
hatte als toolchain die STM32CubeIDE-Toolchain angegeben. Da gab es noch 
einen Fehler im .cproject file, und zwar mußte ich noch einen "-" an das 
arm-none-eabi-Präfix anhängen:

<option id="cdt.managedbuild.option.gnu.cross.prefix.752358746" 
name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix" 
value="arm-none-eabi-" valueType="string"/>

von Harry L. (mysth)


Angehängte Dateien:

Lesenswert?

Nach ein paar Korrekturen läuft das mit der .ioc-Datei probelmlos:
1. du hast zwar die Pins dem Uart zugewiesen, aber den UART nicht 
aktiviert
2. Debugging war abgeschaltet - keine gute Idee

Der generierte Code läst sich problemlos und fehlerfrei übersetzen.

Die ioc-Datei in der CubeIDE über File->New->Project from config-file 
(.ioc)

Diekorrigierte Datei hab ich dir mal angehängt.

: Bearbeitet durch User
von Bauform B. (bauformb)


Lesenswert?

Christoph K. schrieb:
> Und den Assemblercode (C-Compilat)
> würde ich ja ohnehin nur in der Runtime-Library finden.

Nicht nur da, natürlich auch im fertigen Programm. Du kannst ganz normal 
ohne Tricks ein CubeMX Projekt in C bauen. Dabei wird am Ende oder kurz 
vorher eine Datei im ELF-Format erzeugt. Die musst du "nur" finden... 
Daraus kannst du lesbaren Assembler-Text erzeugen mit
1
arm-none-eabi-objdump -d -t -C datei.elf > datei.txt
 Falls du die Optimierung irgendwo einstellen kannst: -Os oder notfalls 
-O0 gibt leichter lesbaren Text als höhere Optimierungsstufen.

von Christoph K. (chriskuku)


Lesenswert?

Harry L. schrieb:
> Nach ein paar Korrekturen läuft das mit der .ioc-Datei probelmlos:
> 1. du hast zwar die Pins dem Uart zugewiesen, aber den UART nicht
> aktiviert
> 2. Debugging war abgeschaltet - keine gute Idee
>
> Der generierte Code läst sich problemlos und fehlerfrei übersetzen.
>
> Die ioc-Datei in der CubeIDE über File->New->Project from config-file
> (.ioc)
>
> Diekorrigierte Datei hab ich dir mal angehängt.

Danke. Habe noch mal ein frisches uarttest-Projekt in STM32CubeIDE als
"Projekt aus .ioc file" angelegt.
Muß mir erst mal ein geeignetes Testprogramm suchen, was den UART 
anspricht. Das Hello,World Beispiel war nicht geeignet, weil es stdlib 
(libc) Routinen aufrief.

: Bearbeitet durch User
von Bauform B. (bauformb)


Lesenswert?

Christoph K. schrieb:
> Muß mir erst mal ein geeignetes Testprogramm suchen, was den UART
> anspricht.
1
 USART3->TDR = 'X';
den Rest soll doch CubeMX erzeugen? Oder wie?

von Christoph K. (chriskuku)


Lesenswert?

Bauform B. schrieb:
> Christoph K. schrieb:
>> Muß mir erst mal ein geeignetes Testprogramm suchen, was den UART
>> anspricht.
>
>
1
 USART3->TDR = 'X';
> den Rest soll doch CubeMX erzeugen? Oder wie?

Ich bin in STM32CubeIDE.
Wer liefert die Definitionen?

von Stefan F. (Gast)


Lesenswert?

Christoph K. schrieb:
> Wer liefert die Definitionen?

Meinst du die Namen der Register? Die befinden sich in den CMSIS-core 
Header Dateien, auf die Cube HAL aufbaut.

von Bauform B. (bauformb)


Lesenswert?

Christoph K. schrieb:
> Wer liefert die Definitionen?

#include stm32l031xx.h oder geht das etwa auch nicht? Ich verstehe schön 
langsam nur noch Bahnhof :(

von Christoph K. (chriskuku)


Lesenswert?

Bauform B. schrieb:
> Christoph K. schrieb:
>> Wer liefert die Definitionen?
>
>
> #include stm32l031xx.h oder geht das etwa auch nicht? Ich verstehe schön
> langsam nur noch Bahnhof :(

Ich hatte angenommen, daß einem das generiert wird. Woher soll ich denn 
den Namen stm32l031xx wissen? Ist der Name, so, wie Du ihn da schreibst 
ohne "" richtig?

Ohne die "" bekomme ich "invalid preprocessor directive", mit "" 
"unresolved inclusion : "stm32l031xx.h".

: Bearbeitet durch User
von Bauform B. (bauformb)


Lesenswert?

Christoph K. schrieb:
> Ist der Name, so, wie Du ihn da schreibst ohne "" richtig?

Nein, natürlich nicht. Aber ob < > oder " " muss man auch wieder 
probieren.

Und der Name ist auch falsch - in bin im falschen Thread, du brauchst ja 
stm32f4irgendwas :(

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Richtig ist:
#include "stm32l0xx.h"

Christoph K. schrieb:
> Woher soll ich denn den Namen stm32l031xx wissen?

Indem man sich zuerst mit den Grundlagen befasst, bevor man sich an eine 
komplexe Bibliothek heran wagt, die auf all dem aufbaut.

- Compiler: arm-gcc
- Standard C Bibliothek: newlib-nano
- Standard Header: CMSIS core

All diese sind separat dokumentiert. Dazu kommt dann noch die 
Dokumentation zu deinem konkreten Mikrocontroller, die auf 4 PDF's 
verteilt ist:

- Reference Manual
- Datasheet
- Errata
- Programming Manual

Fange mal damit an: http://stefanfrings.de/stm32/stm32l0.html

Die Seite leitet sich genau dazu an. Wenn du damit (und den verlinkten 
Dokumentationen) durch bist, bist du für die HAL einigermaßen 
vorbereitet.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

In deiner Setup_Clocks wartest du überhaupt nicht darauf dass die 
Sysclock auf den HSE umgeschaltet ist. Das Umschalten ist also eventuell 
erst später fertig, z.B. nach/während der UART-Initialisierung. Dann ist 
es natürlich kein Wunder dass der UART einen "Glitch" sendet... Du 
solltest also nach dem Setzen des "SW0" Bits im RCC_CFGR darauf warten, 
dass die SWS Bits im RCC_CFGR den Wert 01 haben, und erst dann weiter 
machen.

Vielleicht solltest du dem UART einen externen Pull-Up Widerstand 
verpassen. Weil die meisten GPIOs nach dem Reset hochohmig sind, sind 
sie somit direkt "High" und bleiben es auch bis zum Senden des ersten 
Zeichens, ohne Glitch.

Außerdem verwendest du ja gar nicht die PLL. Da kannst du einen 
Performance-Gewinn vom Faktor 21 raus bekommen, mehr als man jemals 
durch manuelle Assembler-Programmierung gewinnt...

Die STM32F1 und F4 haben übrigens ziemlich andere Register, insbesondere 
beim GPIO. Der gezeigte Assembler-Code funktioniert nicht auf dem F1 
(z.B. BluePill), denn die haben gar kein GPIO_AFRH/L Register.

: Bearbeitet durch User
von PittyJ (Gast)


Lesenswert?

Christoph K. schrieb:
> Ich hatte angenommen, daß einem das generiert wird. Woher soll ich denn
> den Namen stm32l031xx wissen? Ist der Name, so, wie Du ihn da schreibst
> ohne "" richtig?
>
> Ohne die "" bekomme ich "invalid preprocessor directive", mit ""
> "unresolved inclusion : "stm32l031xx.h".

Lass es sein mit C. Das #include wird normalerweise in jedem C Buch in 
den ersten 10 Seiten erklärt. Wenn du nicht mal ein Include erzeugen 
kannst, dann bist du bei C komplett falsch.

Ich dachte immer, etwas C Kenntnisse wären bei jedem vorhanden, wenn man 
Assembler und Forth kennt, weil C ja auch über Jahre dominierte. Gerade 
bei Mikrocontroller ist C dominant. Aber da habe ich mich wohl geirrt.
Bleib in der Assembler Welt, C ist ein zu großer Schritt für dich.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Niklas G. schrieb:
> Weil die meisten GPIOs nach dem Reset hochohmig sind, sind
> sie somit direkt "High" und bleiben es auch bis zum Senden des ersten
> Zeichens, ohne Glitch.

PS: Versuche auch mal erst den UART zu aktivieren und erst dann die 
GPIOs zu konfigurieren zum Vermeiden des Glitch.

von Stefan F. (Gast)


Lesenswert?

PittyJ schrieb:
> Bleib in der Assembler Welt, C ist ein zu großer Schritt für dich.

Blödsinn. Zu groß ist nur der Schritt, direkt mit der HAL anzufangen.

von STK500-Besitzer (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Blödsinn. Zu groß ist nur der Schritt, direkt mit der HAL anzufangen.

oder einfach so drauf los "zu prgrammieren".
Die HAL soll den Kram doch vereinfach und ist deswegen auch 
dokumentiert.
Mit der Doku sollte man sich halt mal auseinandersetzen.

von Christoph K. (chriskuku)


Lesenswert?

PittyJ schrieb:
 Lass es sein mit C. Das #include wird normalerweise in jedem C Buch in
> den ersten 10 Seiten erklärt. Wenn du nicht mal ein Include erzeugen
> kannst, dann bist du bei C komplett falsch.
>
> Ich dachte immer, etwas C Kenntnisse wären bei jedem vorhanden, wenn man
> Assembler und Forth kennt, weil C ja auch über Jahre dominierte. Gerade
> bei Mikrocontroller ist C dominant. Aber da habe ich mich wohl geirrt.
> Bleib in der Assembler Welt, C ist ein zu großer Schritt für dich.

Ich kenne C seit 1979 und habe es noch aus dem Kernighan Ritchie 
gelernt.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Statt
1
pop {lr}
2
bx lr

kannst du übrigens auch effizienter
1
pop {pc}

nehmen. Wenn du die Funktionen mit
1
.type Setup_Clocks, %function
2
Setup_Clocks:
3
...

deklarierst tauchen sie im Disassembly und Debugger übersichtlicher auf. 
Wenn du das bei den Interrupt-Handlern machst, werden die "+1" im 
Interrupt-Vektor auch unnötig.

von Stefan F. (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> Die HAL soll den Kram doch vereinfach und ist deswegen auch
> dokumentiert.

Soll sie? Ich denke genau das ist ein verbreiteter Irrtum.

Mal sehen, wie ST die HAL beschreibt: 
https://www.st.com/en/embedded-software/stm32cubel0.html
Das Wort "simple" kommt in dem Text nicht vor.

Der Code Generator (Cube HAL) vereinfacht die initiale Konfiguration der 
Taktversorgung und der Peripherie. Danach wird aber nichts mehr 
einfacher. Allerdings vereinfacht die HAL eine Portierung des darauf 
aufbauenden Codes zu anderen Mikrocontrollern von STM. Das ist der 
eigentliche Zweck der HAL.

Wer eine einfacher programmieren will, der soll besser zu Arduino gehen. 
Da bekommt man dann das komplette Gesamtpaket aus praktischen Boards, 
Shields, IDE, Framework (Core) und Dokumentation. Damit kann man 
wirklich etwas einfacher einsteigen.

Der Arduino Core baut übrigens wieder auf HAL auf, so dass man sich dort 
nicht zwingend einschränken muss.

So oder so kommt man langfristig jedoch nicht um die Grundlagen herum. 
Also besser damit anfangen und sich langsam schrittweise hoch arbeiten. 
Man empfiehlt ja auch nicht, zuerst eine 3-Stöckige Hochzeitstorte zu 
backen, um sich irgendwann später mit einfachem Pizzateig zu befassen.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Stefan ⛄ F. schrieb:
> Allerdings vereinfacht die HAL eine Portierung des darauf
> aufbauenden Codes zu anderen Mikrocontrollern von STM. Das ist der
> eigentliche Zweck der HAL.

Das tut sie aber überhaupt nicht. Die nahezu identische SDIO-Peripherie 
der STM32F4 und F7 wird über die HAL anders angesteuert, weil alle 
Funktionen von SDIO_xx nach SDMMC_xx umbenannt wurden. Die HAL macht 
hier also genau das Gegenteil einer HAL, sie erschwert die Portierung. 
Die unterschiedlichen GPIO-Peripherien zwischen F1 und F4 werden auch 
nicht abstrahiert, der Code muss angepasst werden. Der Name "HAL" ist 
quasi Etikettenschwindel, außer man versteht es als "Hardware Access 
Layer"...

von Stefan F. (Gast)


Lesenswert?

Niklas G. schrieb:
> Das tut sie aber überhaupt nicht.

Ich bin damit auch nicht zufrieden. Aber das ist immerhin der Zweck, den 
STM damit laut eigenen Aussagen verfolgt.

Bevor ich mich tiefer mit der HAL befasse, warte ich lieber auf einen 
Nachfolger, der dieses Ziel wirklich erreicht. Momentan ist Arduino 
näher dran, als die HAL. Wobei Arduino es einfach hat, da es nur einen 
Bruchteil der Hardware-Funktionen nutzt.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Stefan ⛄ F. schrieb:
> Ich bin damit auch nicht zufrieden. Aber das ist immerhin der Zweck, den
> STM damit laut eigenen Aussagen verfolgt.

Den haben sie aber leider überhaupt nicht erfüllt. Ganz zu schweigen von 
den diversen Bugs.

Stefan ⛄ F. schrieb:
> Momentan ist Arduino
> näher dran, als die HAL.

Definitiv. "Normaler" Arduino-Code ist sogar zwischen grundverschiedenen 
Architekturen portabel, STM32-HAL-Code nichtmal zwischen 
unterschiedlichen STM32-Familien.

von Christoph K. (chriskuku)


Lesenswert?

Niklas G. schrieb:
> In deiner Setup_Clocks wartest du überhaupt nicht darauf dass die
> Sysclock auf den HSE umgeschaltet ist. Das Umschalten ist also eventuell
> erst später fertig, z.B. nach/während der UART-Initialisierung. Dann ist
> es natürlich kein Wunder dass der UART einen "Glitch" sendet... Du
> solltest also nach dem Setzen des "SW0" Bits im RCC_CFGR darauf warten,
> dass die SWS Bits im RCC_CFGR den Wert 01 haben, und erst dann weiter
> machen.
>
> Vielleicht solltest du dem UART einen externen Pull-Up Widerstand
> verpassen. Weil die meisten GPIOs nach dem Reset hochohmig sind, sind

Die Frage hatte ich mir und hier irgendwo auch schon gestellt (Pullups)

> sie somit direkt "High" und bleiben es auch bis zum Senden des ersten
> Zeichens, ohne Glitch.
>
> Außerdem verwendest du ja gar nicht die PLL. Da kannst du einen
> Performance-Gewinn vom Faktor 21 raus bekommen, mehr als man jemals
> durch manuelle Assembler-Programmierung gewinnt...

In dem kleinen Beispielprogrmm wurde PLL nicht benutzt. Werde es mal 
umstellen.

>
> Die STM32F1 und F4 haben übrigens ziemlich andere Register, insbesondere
> beim GPIO. Der gezeigte Assembler-Code funktioniert nicht auf dem F1
> (z.B. BluePill), denn die haben gar kein GPIO_AFRH/L Register.

Danke für den Hinweise, aber F103 war auch nicht das Target.
Mir kam es jetzt in der Hauptsache darauf an das Problem mit dem Glitch 
mal zu untersuchen und zu schauen, ob es in einem "offiziellen" Programm 
von ST auch vorkommt.

: Bearbeitet durch User
von J. S. (jojos)


Lesenswert?

Stefan ⛄ F. schrieb:
> Der Code Generator (Cube HAL) vereinfacht die initiale Konfiguration der
> Taktversorgung und der Peripherie. Danach wird aber nichts mehr
> einfacher.

unser tägliches STM gebashe gib uns heute...

Schon die Ressourcenplanung wird mit dem Tool wesentlich vereinfacht und 
übersichtlicher. Auf Knopfdruck wird ein schönes pdf zur Doku 
ausgeworfen. Es gibt aufbauend viele Expansion Packages für Grafik 
(touchGFX, musste man vor der Übernahme durch ST einige k€ für 
bezahlen), Motor Controller, AI, LoRaWAN, Sigfox und viele weitere.

von Stefan F. (Gast)


Lesenswert?

J. S. schrieb:
> unser tägliches STM gebashe gib uns heute...

So nennen es nur Leute, die keine Kritik vertragen. Betrifft dich das 
persönlich, oder warum reagierst du so?

von J. S. (jojos)


Lesenswert?

weil die STM Produkte deutlich professioneller sind als in deiner 
beschränkten Ansicht, solche falschen Aussagen tun weh.

'das Tool kann nicht mehr als' und 'ich kann damit nicht umgehen' sind 
halt ein riesen Unterschied.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

J. S. schrieb:
> Es gibt aufbauend viele Expansion Packages für Grafik (touchGFX, musste
> man vor der Übernahme durch ST einige k€ für bezahlen), Motor
> Controller, AI, LoRaWAN, Sigfox und viele weitere.

Willkommen in der Embedded Welt, wo das Einbinden von Libraries als so 
innovativ wahrgenommen wird dass die eigentliche Qualität der Library 
unwichtig ist, und wo das Einbinden über ein grafisches Tool erfolgen 
muss welches ein geschlossenes System ist 🤡

von J. S. (jojos)


Lesenswert?

Respekt und Glückwunsch das ihr Libs wie touchGFX, SSL, AI, 
Cloudanbindung,... alle besser hinbekommt.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

J. S. schrieb:
> Respekt und Glückwunsch das ihr Libs wie touchGFX, SSL, AI,
> Cloudanbindung,... alle besser hinbekommt.

Nö. Aber in anderen Software-Bereichen braucht man kein 
STM32CubeMX-Äquivalent dazu, und kann Libs über einen dedizierten 
Package-Manager einbinden, wo man auch eigene Libs definieren kann. Und 
nur weil hier der "Package Manager" STM32CubeMX praktisch ist, ist noch 
lange nicht die HAL besonders gut.

von Christoph K. (chriskuku)


Angehängte Dateien:

Lesenswert?

Noch mal zurück zum Thema: nachdem ich ja den Fehler, warum kein Zeichen 
an UART3 (PB10) rauskam, gefunden hatte und von Niklas darauf 
hingewiesen wurde, daß ich ja noch nicht die PLL Clock verwende, habe 
ich das Programm  modifiziert hinsichtlich der Clockinitialisierung und 
lade es in der jetzigen Form noch mal hoch, weil jetzt wieder aus dem 
UART herauskommt. Diesmal dürfte aber die Initialisierung des UARTs in 
Ordnung sein. Es liegt also jetzt wahrscheinlich an der geänderte Clock. 
Ändern sich die Baudrate-Initialisierungswerte oder arbeitet der UART 
weiter mit der internen Clock?

: Bearbeitet durch User
von J. S. (jojos)


Lesenswert?

Tja, jetzt müsste es ein Werkzeug geben das den Clocktree übersichtlich 
darstellt und anzeigt welche Clocks an welchen Bussen/Devices liegen...

von Christoph K. (chriskuku)


Lesenswert?

J. S. schrieb:
> Tja, jetzt müsste es ein Werkzeug geben das den Clocktree übersichtlich
> darstellt und anzeigt welche Clocks an welchen Bussen/Devices liegen...

Nun ja, das gibt's ja. Aber wo steht da, mit welcher Clock die UARTS 
arbeiten? Ist das die APB1/APB2 Clock?

: Bearbeitet durch User
von J. S. (jojos)


Lesenswert?

dann sollte das doch deine Frage beantworten. Natürlich kann man in das 
Datenblatt schauen, aber eben den Code generieren und da reinschauen 
geht für mich mittlerweile schneller. Da wird man dann auch die nötige 
Einstellung für die gewünschte Bitrate finden.

von Stefan F. (Gast)


Lesenswert?

Christoph K. schrieb:
> Ändern sich die Baudrate-Initialisierungswerte oder arbeitet der UART
> weiter mit der internen Clock?

Normalerweise schon. Die PLL stellt den Systemtakt bereit, alle anderen 
Takte sind wiederum davon abgeleitet.

Solche Sachen spiele ich gerne in Cube MX durch, bevor ich es "zu Fuß" 
programmiere. Denn Cube MX zeigt dir an, was geht, und was nicht. Die 
Dokumentation der Register ist da nicht immer so eindeutig, vor allem 
was die nicht funktionierenden Kombinationen angeht.

von Christoph K. (chriskuku)


Angehängte Dateien:

Lesenswert?

Leider macht CubeMX bei mir auf dem Mac Ärger. Wenn ich "Code 
Generieren" klicke, kommt "/User: permission denied"

: Bearbeitet durch User
von J. S. (jojos)


Lesenswert?

Christoph K. schrieb:
> Wenn ich "Code
> Generieren" klicke, kommt "/User: permission denied"

in den ProjektManager Einstellungen steht wo das Projekt liegt, sind da 
keine Schreibrechte?

Die Angabe der Busse ist in der F407 Doku etwas versteckt, ich habe im 
RM0090 auf S. 985:
'Only USART1 and USART6 are clocked with PCLK2. Other USARTs are clocked 
with PCLK1. Refer to the device
datasheets for the maximum values for PCLK1 and PCLK2.'

Vielleicht steht es woanders noch etwas übersichtlicher.
An die Doku zur MCU kommt man übrigends schnell aus CubeMX mit Alt-D.

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Christoph K. schrieb:
> Aber wo steht da, mit welcher Clock die UARTS arbeiten?

Gute Frage, die Antwort habe ich (auf die Schnelle) weder im Reference 
Manual noch in Cube MX gefunden.

Die Ausnahmen für USART2 und LPUART sind klar, aber die anderen?
x

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Christoph K. schrieb:
> habe ich das Programm  modifiziert hinsichtlich der Clockinitialisierung

Du schaltest zwar die PLL ein, benutzt sie aber gar nicht als Sysclock, 
d.h. die bleibt beim HSI... Du musst natürlich auch die APB prescaler 
setzen, sonst läuft der Bus zu schnell (siehe Maximale Busfrequenzen im 
Datasheet).

Christoph K. schrieb:
> Leider macht CubeMX bei mir auf dem Mac Ärger.

Du kannst die von CubeMX berechneten Werte (Prescaler etc.) auch manuell 
in dein Programm übernehmen.

von J. S. (jojos)


Lesenswert?

Im Datasheet ist die Functional overview, da sieht man es auch.

Im Cube sieht man auch den max. Takt für APB1, den Teiler kann man zu 
klein einstellen und damit den Bus übertakten, muss man also auch 
kontrollieren wenn man die Clocks selber einstellt.

: Bearbeitet durch User
von Christoph K. (chriskuku)


Lesenswert?

J. S. schrieb:
> Christoph K. schrieb:
>> Wenn ich "Code
>> Generieren" klicke, kommt "/User: permission denied"
>
> in den ProjektManager Einstellungen steht wo das Projekt liegt, sind da
> keine Schreibrechte?

Das ist beim Mac und neueren Versionen immer mehr abgeschottet. Das 
steht als Project Location: /Users/kuku, also mein Homeverzeichnis. Ich 
könnte es ja mal brutal aufmachen, aber macOS hat ja auch noch sowas wie 
ACLs.
Warte man ab, ob Macspezialisten da noch was zu sagen können.


>
> Die Angabe der Busse ist in der F407 Doku etwas versteckt, ich habe im
> RM0090 auf S. 985:
> 'Only USART1 and USART6 are clocked with PCLK2. Other USARTs are clocked
> with PCLK1. Refer to the device
> datasheets for the maximum values for PCLK1 and PCLK2.'
>
> Vielleicht steht es woanders noch etwas übersichtlicher.
> An die Doku zur MCU kommt man übrigends schnell aus CubeMX mit Alt-D.

von Christoph K. (chriskuku)


Lesenswert?

Stefan ⛄ F. schrieb:
> Christoph K. schrieb:
>> Aber wo steht da, mit welcher Clock die UARTS arbeiten?
>
> Gute Frage, die Antwort habe ich (auf die Schnelle) weder im Reference
> Manual noch in Cube MX gefunden.
>
> Die Ausnahmen für USART2 und LPUART sind klar, aber die anderen?
> x

Dieses Bild mit den UART Clocks habe ich nicht in meinem CubeMX.

von Stefan F. (Gast)


Lesenswert?

Christoph K. schrieb:
> Dieses Bild mit den UART Clocks habe ich nicht in meinem CubeMX.

Hast du das falsche STM32 Modell ausgewählt?

von J. S. (jojos)


Lesenswert?

wie geschrieben, im Datasheet unter Functional overview, in desem Fall 
also Punkt für die Doku.

Bei den komplexeren H7 kann man die Taktquelle wählen, bei denen sieht 
man das dann im Cube clocktree.

Der HAL ist etwas aufwändiger, z.B. wird da das UART device erst 
disabled. Es gibt Config Register die sich nur beschreiben lassen wenn 
man das macht oder bei RTC irgendwelche Freigabe Bits setzt. Da 
funktioniert der einfache Code erst, aber nur solange man die Funktion 
nicht nochmal aufruft.
Sowas findet man auch im Datasheet/Refman, aber teilweise sind so Infos 
über verschiedene Kapitel verstreut. Da braucht man die Erfahrung mit 
den Controllern, die Fehlersuche kann da recht langwierig sein. Oder man 
benutzt eben den HAL...

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

J. S. schrieb:
> wie geschrieben, im Datasheet unter Functional overview, in desem Fall
> also Punkt für die Doku.

Biest du beim falschen Modell? Es geht um einen STM32L031, oder nicht? 
Mir reicht das Diagramm nicht und im Text steht auch nicht mehr.

von Christoph K. (chriskuku)


Lesenswert?

Stefan ⛄ F. schrieb:
> Christoph K. schrieb:
>> Dieses Bild mit den UART Clocks habe ich nicht in meinem CubeMX.
>
> Hast du das falsche STM32 Modell ausgewählt?

Auf meinem Chip in der Pinout View steht STM32F407VGTx

von J. S. (jojos)


Lesenswert?

Stefan ⛄ F. schrieb:
> Biest du beim falschen Modell? Es geht um einen STM32L031, oder nicht?

Christoph K. schrieb:
> Danke für den Hinweise, aber F103 war auch nicht das Target.

bin beim F407, dieses Projekt läuft doch jetzt schon >2 Jahre mit vielen 
vielen Fragen und Beiträgen hier.
Ohne das mal genannt wurde was das ominiöse Forth/Assembler Programm 
überhaupt macht, oder ich habe es überlesen. Wäre ein Neudesign da nicht 
schneller fertig?

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

W.S. schrieb:
> Deshalb
> sollte es nicht verwundern, wenn direkt nach dem Aktivieren noch irgend
> ein Glitch auf der Leitung ist

Das ist Quatsch, da darf kein Glitch entstehen. Nach dem Reset ist ein 
IO-Pin tristate und der Pullup im MAX232 zieht auf high.
Es kann aber sein, daß man den Pin zuerst auf Output setzt und dann wird 
low ausgegeben. Setzt man danach auf UART, hat man den Glitch. Man muß 
also den Pin zuerst auf UART setzen und der Glitch ist weg.

von c-hater (Gast)


Lesenswert?

Peter D. schrieb:

> Das ist Quatsch, da darf kein Glitch entstehen.

Solltest du vielleicht mal darüber nachdenken was der Peer der 
Verbindung in der Zeit macht, in der du deine Kiste startest oder 
rebootest...

von Stefan F. (Gast)


Lesenswert?

Christoph K. schrieb:
> Auf meinem Chip in der Pinout View steht STM32F407VGTx

Ich dachte es geht um den L031. Das erklärt dass du ein ganz anderes 
Bild siehst.

von Christoph K. (chriskuku)


Lesenswert?

c-hater schrieb:
> Peter D. schrieb:
>
>> Das ist Quatsch, da darf kein Glitch entstehen.
>
> Solltest du vielleicht mal darüber nachdenken was der Peer der
> Verbindung in der Zeit macht, in der du deine Kiste startest oder
> rebootest...

Der, die, das Peer ist idle. In other words: die Gegenstelle ist ein 
Empfänger, der im Ruhezustand ist.

Sorry, Anglizismen sind für mich ein Nogo (Torsten Sträter)

: Bearbeitet durch User
von Christoph K. (chriskuku)


Lesenswert?

Was den sog. "Glitch" und den Versuch, ihn zu eliminieren, betrifft, 
fand ich folgenden Satz im RM0090, S.970 (etwa Mitte):

_An idle frame will be sent after the TE bit is enabled._

Und, weiter unten:

_An idle frame transmission will include the stop bits._

Dann muß es wohl so sein, wenn ich das richtig interpretiere.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Christoph K. schrieb:
> An idle frame will be sent after the TE bit is enabled.

Idle-Frames kommen am PC aber nicht als '?' an! Ein Idle-Frame ist 
einfach 'TX-Leitung High'. Ich weiß grad gar nicht ob man das am PC 
überhaupt empfangen kann, schließlich ist die Leitung immer high wenn 
nicht gerade ein Gerät angeschlossen ist und sendet.

von Christoph K. (chriskuku)


Lesenswert?

Niklas G. schrieb:
> Christoph K. schrieb:
>> An idle frame will be sent after the TE bit is enabled.
>
> Idle-Frames kommen am PC aber nicht als '?' an! Ein Idle-Frame ist
> einfach 'TX-Leitung High'. Ich weiß grad gar nicht ob man das am PC
> überhaupt empfangen kann, schließlich ist die Leitung immer high wenn
> nicht gerade ein Gerät angeschlossen ist und sendet.

Das ? ist ja auch nur die spezielle Reaktion des pico Terminalprogramms.
Beim OC-Console (Windows) wird ein ÿ ausgegeben, was 0xFF in der 8-Bit 
„ASCII“-Tabelle entspricht.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Christoph K. schrieb:
> Beim OC-Console (Windows) wird ein ÿ ausgegeben, was 0xFF in der 8-Bit
> „ASCII“-Tabelle entspricht.

Spricht trotzdem nicht für ein Idle-Frame. Sonst müssten ständig 0xFF 
reinkommen...

von Christoph K. (chriskuku)


Lesenswert?

Niklas G. schrieb:
> Christoph K. schrieb:
>> Beim OC-Console (Windows) wird ein ÿ ausgegeben, was 0xFF in der 8-Bit
>> „ASCII“-Tabelle entspricht.
>
> Spricht trotzdem nicht für ein Idle-Frame. Sonst müssten ständig 0xFF
> reinkommen...

Wieso ständig? TE wird doch nur einmal gesetzt in der Initialisierung.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Christoph K. schrieb:
> Wieso ständig? TE wird doch nur einmal gesetzt in der Initialisierung.

Weil die TX-Leitung nunmal high ist wenn man nichts sendet, und TX=High 
ein Idle Frame ist. Wenn du den TX-Pin vom RS232-Kabel offen lässt ohne 
Controller dran, kommen auch ständig Idle-Frames, weil (vermutlich) 
irgendein Pullup die Leitung auf High zieht. Aber im Terminal kommt bei 
offenem Pin keine Flut von 0xFF an.

Der Hinweis im Datenblatt sagt lediglich dass beim Einschalten die 
TX-Leitung für einen kurzen Moment High wird bevor das erste Byte 
gesendet werden kann. Wenn man nichts sendet, bleibt sie High.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Wenn die Leitung schon vor dem Initialisieren auf HIGH war (z.B. durch 
einen Pull-Up) dann "sendet" der Tx Pin gar nichts. Ich denke, das 
möchte der Christoph erreichen.

von Christoph K. (chriskuku)


Lesenswert?

Stefan ⛄ F. schrieb:
> Wenn die Leitung schon vor dem Initialisieren auf HIGH war (z.B. durch
> einen Pull-Up) dann "sendet" der Tx Pin gar nichts. Ich denke, das
> möchte der Christoph erreichen.

Fand übrigens diesen Beitrag in der ST-Community:
https://community.st.com/s/question/0D50X00009XkaduSAB/how-to-stop-the-idle-frame-on-uart

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Christoph K. schrieb:
> Fand übrigens diesen Beitrag in der ST-Community:

Zitat:

IDLE frame is nothing else but the high state of the TX pin kept for at 
least frame length. NO start bit is sent!

Sag ich doch! Und da ist genau der Hinweis mit erst UART initialisieren 
und dann den Pin, und der Pullup wird auch vorgeschlagen.

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.