Forum: Mikrocontroller und Digitale Elektronik Kommunikation zwischen mController und PC


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von RT (mcu-programmer)


Lesenswert?

Hallo,

ich möchte Informationen über UART an meinen PC senden.

Hierfür nutze ich ...
* ein Nucleo-Board mit deem STM32F446RE
* ein UART auf USB Wandler 
(https://www.amazon.de/AZDelivery-UART-TTL-Konverter-Jumperkabel-inklusive/dp/B08T24NML9/ref=sr_1_1?__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91&crid=3KB2S24QL3JXZ&keywords=UART-TTL+USB+Adapter+mit+CH340G+Konverter+f%C3%BCr+3.3V+und+5V+mit+Jumperkabel&qid=1675538528&sprefix=uart-ttl+usb+adapter+mit+ch340g+konverter+f%C3%BCr+3.3v+und+5v+mit+jumperkabel%2Caps%2C68&sr=8-1)
* Windows 10 PC mit der Software Putty oder hercules als serieller 
Monitor

Code:
1
// Task: Kommunikation mit dem PC über UART bzw. USART
2
// Baudrate: 115200 bps
3
// Wortlänge: 8-Bit
4
// Parität: Keine
5
// Stoppbits: 1
6
7
// Standardbibliotheken von C
8
#include <stdint.h>
9
#include <stdbool.h>
10
11
// Bibliotheke des verwendeten Mikrocontrollers
12
#include "stm32f446xx.h"
13
#include "system_stm32f4xx.h"
14
15
int main(void)
16
{
17
  // APB1 entspricht nun Clockfrequenz vom Controller
18
  RCC->CFGR &= ~RCC_CFGR_PPRE1_Msk;
19
20
  // Aktivieren der Clock für GPIO Port A und USART 2 Schnittstelle
21
  RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
22
  RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
23
24
  // Definition von GPIO A Pin 2 und 3 als alternative Funktion und PA5 als Output
25
  GPIOA->MODER |= GPIO_MODER_MODER2_1;
26
  GPIOA->MODER |= GPIO_MODER_MODER3_1;
27
28
  // Definition von GPIO A Pin 2 und 3 als alternative Funktion AF5 (Clock und MOSI für SPI 1)
29
  GPIOA->AFR[0] |= GPIO_AFRL_AFSEL2;
30
  GPIOA->AFR[0] &= ~GPIO_AFRL_AFSEL2_3;
31
32
  GPIOA->AFR[0] |= GPIO_AFRL_AFSEL3;
33
  GPIOA->AFR[0] &= ~GPIO_AFRL_AFSEL3_3;
34
35
  // Alle Pins werden mit der schnellsten Geschwindigkeit betrieben
36
  GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEED2;
37
  GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEED3;
38
  GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEED5;
39
40
  // Aktiviere/Starte USART2
41
  USART2->CR1 |= USART_CR1_UE;
42
43
  // 1 Start-Bit and 8 Databits and n Stopp-Bits
44
  USART2->CR1 &= ~USART_CR1_M;
45
46
  // Oversampling 16
47
  USART2->CR1 &= ~USART_CR1_OVER8_Msk;
48
49
  // Baudrate einstellen:
50
  // BD: Gewünschte Baudrate (Hier: 115.200 bps)
51
  // FP: Prozessor-Frequenz (Hier: 16.000.000 Hz)
52
  // OR: Oversamplin-Rate (Hier: 16 (Default)
53
  //USART2->BRR |= (3<<0) | (104<<4);//0x6B;
54
55
  // Aktiviere/Starte xSender
56
  //USART2->CR1 |= USART_CR1_RE;
57
58
  // Aktiviere/Starte Empfänger
59
  USART2->CR1 |= USART_CR1_TE;
60
61
  while (1)
62
  {
63
    USART2->DR = 'G';
64
    while(!(USART2->SR & USART_SR_TC)){;}
65
  }
66
}

Der Code ist wirklich nur um zu schauen, wieso ich keinen Messwert über 
die Schnittstelle bekomme.

Ziel: Es erscheint ständig ein G im seriellen Monitor.

Ist: Es kommt nichts an ...

Findet da einer den Fehler?

Danke schonmal.

von Thomas W. (Gast)


Lesenswert?

RT schrieb:

ich habe ja keine Ahnung, aber:
1
>   // Baudrate einstellen:
2
>   // BD: Gewünschte Baudrate (Hier: 115.200 bps)
3
>   // FP: Prozessor-Frequenz (Hier: 16.000.000 Hz)
4
>   // OR: Oversamplin-Rate (Hier: 16 (Default)
5
>   //USART2->BRR |= (3<<0) | (104<<4);//0x6B;
6
> 
7
>   // Aktiviere/Starte xSender
8
>   //USART2->CR1 |= USART_CR1_RE;

Sind die zwei Kommentar-Zeilen (line 5 and 8) wirklich gewuenscht?

Th.

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Ich fürchte, dass deine Alternate-Function Einstellung falsch ist.

> // Definition von GPIO A Pin 2 und 3 als alternative Funktion und PA5 als Output

Dein Code stellt nichts für PA5 ein.

> // Definition von GPIO A Pin 2 und 3 als alternative Funktion
> AF5 (Clock und MOSI für SPI 1)

Schau mal in den Anhang, welche Funktion AF5 bei diesen Pins ist. 
Wolltest du nicht den USART2 benutzten? Das wäre AF7. In den folgenden 
Zeilen stellst du AF7 ein.

Falsche Kommentare sind schlimmer als gar keine Kommentare!

Ich gebe dir mal ein Beispiel, wie man den Code für die Konfiguration 
der I/O Pin besser lesbar macht:
1
// PA11 = USB D-, alternate function 14 push/pull
2
MODIFY_REG(GPIOA->AFR[1], GPIO_AFRH_AFRH3, 14UL<<GPIO_AFRH_AFRH3_Pos);
3
MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER11, GPIO_MODER_MODER11_1);

Hier sieht man direkt die Nummer des AF Modus, in diesem Fall 14.

Das MODIFY_REG Marko hat 3 Parameter:
1) Register
2) Bitmaske, legst fest welche Bits du einstellen willst
3) Der konkreten Wert für diese Bits. Wenn du mehrere Bits setzen 
willst, kannst du das wie oben mit der 14 machen, oder indem du mehrere 
Bits mit + oder | kombiniert. Angenommen ich wollte im MODER Register 
Bit 0 und 1 setzen, dann so:
1
MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER11, GPIO_MODER_MODER11_1+GPIO_MODER_MODER11_0);

MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER11, GPIO_MODER_MODER11_1);

Genug klug geschissen.

Die Baudrate musst du schon noch einstellen, auskommentiert kann das 
nicht funktionieren.

> // Prozessor-Frequenz (Hier: 16.000.000 Hz)

Ist das so? Im Schaltplan sehe ich einen 8 MHz Quarz.

Überprüfe das Ausgangssignal mit einem Oszilloskop oder einen Logic 
Analyzer. Dann siehst du sofort, ob die Baudrate stimmt.

von Stefan F. (Gast)


Lesenswert?

RT schrieb:
>   // Aktiviere/Starte xSender
>   //USART2->CR1 |= USART_CR1_RE;

>   // Aktiviere/Starte Empfänger
>   USART2->CR1 |= USART_CR1_TE;

Hier sind auch wieder zwei völlig falsche Kommentare.

RE aktiviert den Receiver (Empfänger)
TE aktiviert den Transmitter (Sender).

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Weist du, dass PA2 und PA3 beim Nucleo64 Board standardmäßig nicht mit 
den Stiftleisten verbunden sind, sondern mit dem ST-Link?

von Leichte Sprache fuer Alle (Gast)


Lesenswert?

> Weist du, dass PA2 und PA3 beim Nucleo64 Board standardmäßig nicht mit
> den Stiftleisten verbunden sind, sondern mit dem ST-Link?

<Loriot>
Ach!
</Loriot>

Vermutlich kann der ST-Link sogar serieller Adapter spielen.

von Stefan F. (Gast)


Lesenswert?

Leichte Sprache fuer Alle schrieb:
> Vermutlich kann der ST-Link sogar serieller Adapter spielen.

Doch der TO verwendet einen weiteren USB-UART Adapter, von dem er 
glaubt, ihn an PA2 und PA3 (also USART2) angeschlossen zu haben.

Beitrag #7338586 wurde vom Autor gelöscht.
von RT (mcu-programmer)


Lesenswert?

Thomas W. schrieb:
> RT schrieb:
>
> ich habe ja keine Ahnung, aber:
>
>
1
> 
2
>>   // Baudrate einstellen:
3
>>   // BD: Gewünschte Baudrate (Hier: 115.200 bps)
4
>>   // FP: Prozessor-Frequenz (Hier: 16.000.000 Hz)
5
>>   // OR: Oversamplin-Rate (Hier: 16 (Default)
6
>>   //USART2->BRR |= (3<<0) | (104<<4);//0x6B;
7
>>
8
>>   // Aktiviere/Starte xSender
9
>>   //USART2->CR1 |= USART_CR1_RE;
10
> 
11
>
>
> Sind die zwei Kommentar-Zeilen (line 5 and 8) wirklich gewuenscht?
>
> Th.

Dort und an einigen anderen Stellen habe ich wohl vergessen die
Kommentare zu löschen ^^ Ich hab viel hin und her gelöscht und
kommentiert. Danke für den Hinweis.

von RT (mcu-programmer)


Lesenswert?

Stefan F. schrieb:
> Ich fürchte, dass deine Alternate-Function Einstellung falsch ist.
>
>> // Definition von GPIO A Pin 2 und 3 als alternative Funktion und PA5 als 
Output
>
> Dein Code stellt nichts für PA5 ein.
>
>> // Definition von GPIO A Pin 2 und 3 als alternative Funktion
>> AF5 (Clock und MOSI für SPI 1)
>
> Schau mal in den Anhang, welche Funktion AF5 bei diesen Pins ist.
> Wolltest du nicht den USART2 benutzten? Das wäre AF7. In den folgenden
> Zeilen stellst du AF7 ein.
>
> Falsche Kommentare sind schlimmer als gar keine Kommentare!
>
> Ich gebe dir mal ein Beispiel, wie man den Code für die Konfiguration
> der I/O Pin besser lesbar macht:
>
1
> // PA11 = USB D-, alternate function 14 push/pull
2
> MODIFY_REG(GPIOA->AFR[1], GPIO_AFRH_AFRH3, 14UL<<GPIO_AFRH_AFRH3_Pos);
3
> MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER11, GPIO_MODER_MODER11_1);
4
>
>
> Hier sieht man direkt die Nummer des AF Modus, in diesem Fall 14.
>
> Das MODIFY_REG Marko hat 3 Parameter:
> 1) Register
> 2) Bitmaske, legst fest welche Bits du einstellen willst
> 3) Der konkreten Wert für diese Bits. Wenn du mehrere Bits setzen
> willst, kannst du das wie oben mit der 14 machen, oder indem du mehrere
> Bits mit + oder | kombiniert. Angenommen ich wollte im MODER Register
> Bit 0 und 1 setzen, dann so:
>
>
1
> MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER11, 
2
> GPIO_MODER_MODER11_1+GPIO_MODER_MODER11_0);
3
>
>
> MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER11, GPIO_MODER_MODER11_1);
>
> Genug klug geschissen.
>
> Die Baudrate musst du schon noch einstellen, auskommentiert kann das
> nicht funktionieren.
>
>> // Prozessor-Frequenz (Hier: 16.000.000 Hz)
>
> Ist das so? Im Schaltplan sehe ich einen 8 MHz Quarz.
>
> Überprüfe das Ausgangssignal mit einem Oszilloskop oder einen Logic
> Analyzer. Dann siehst du sofort, ob die Baudrate stimmt.

Hallo,

erstmal danke für die ausführliche Antwort.

Das mit den Kommentaren war Käse, da daurauf ich nächstesmal.

PA5 können wir erstmal vergessen. Ziel war es PA2 und PA3 als AF7 zu 
konfigurieren für USART2.

Das mit MODIFY_REG ist eine Verbesserung, das behalte ich im Hinterkopf 
für später. Ich möchte erstmal, dass es läuft ^^

Die Baudrate ist drin, trotzdem funktioniert das irgendwie nicht so, wie 
gewollt. Ich habe ein kleines Oszilloskop, welche Pinne müsste ich 
messen, damit ich die Prozessorfrequenz messen kann?

von RT (mcu-programmer)


Lesenswert?

Stefan F. schrieb:
> Weist du, dass PA2 und PA3 beim Nucleo64 Board standardmäßig nicht mit
> den Stiftleisten verbunden sind, sondern mit dem ST-Link?

Sooo du bist der Held des Abends. Das war der Fehler. Ich habe den Code 
geändert auf USART1 und es hat geklappt.

Anscheinend muss man eine Brücke löten, wenn man USART2 nutzen will. 
Vielen Dank.

von STK500-Besitzer (Gast)


Lesenswert?

RT schrieb:
> Anscheinend muss man eine Brücke löten, wenn man USART2 nutzen will.

Das steht so i.d.R. im Manual des NUCLEO-Boards.
SB13/14 und 62/63 laut Kapitel 6.9 von
https://www.st.com/resource/en/user_manual/um1724-stm32-nucleo64-boards-mb1136-stmicroelectronics.pdf
(ggf. nach dem Bestätigen der Cookies noch mal aufrufen).

von Stefan F. (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> Das steht so i.d.R. im Manual des NUCLEO-Boards.
> SB13/14 und 62/63 laut Kapitel 6.9 von

Deswegen habe ich davon schon gestern einen Screenshot gezeigt.

von Stefan F. (Gast)


Lesenswert?

RT schrieb:
> Das war der Fehler. Ich habe den Code
> geändert auf USART1 und es hat geklappt.

Danke für das Feedback.

Nächstes mal zitiere bitte nicht den ganzen Roman. Man kann schließlich 
noch auf den Link klicken, wenn man ihn nochmal lesen will.

von W.S. (Gast)


Lesenswert?

RT schrieb:
> Ich habe den Code
> geändert auf USART1 und es hat geklappt.

Dann ändere ihn lieber noch einmal - und zwar dahingehend, daß du sowas 
wie E/A-Routinen und die dazu nötigen Initialisierungen aus main 
verbannst und sowas in einer separaten Quelle anordnest. Treiber für 
Kommunikationskanäle, Displays, Tasten, I2C und anderes Gedöns solcher 
Art gehören in jeweils separate Dateien und sollen eine gut überlegte 
Schnittstelle haben, damit man beim Programmieren sich nicht in einem 
Code-Urwald verläuft.

Ein gewisses Maß an Ordnung muß sein, auch wenn es dem einen oder 
anderen am Anfang vielleicht als übertrieben erscheint.

W.S.

von Stefan F. (Gast)


Lesenswert?

W.S. schrieb:
> Ein gewisses Maß an Ordnung muß sein

Ja aber doch nicht bei den ersten Geh-Versuchen.

von J. S. (jojos)


Lesenswert?

W.S. schrieb:
> Ein gewisses Maß an Ordnung muß sein, auch wenn es dem einen oder
> anderen am Anfang vielleicht als übertrieben erscheint.

RT schrieb:
> Der Code ist wirklich nur um zu schauen, wieso ich keinen Messwert über
> die Schnittstelle bekomme.

Um Fehler zu reproduzieren und demonstrieren macht man ein 
Minimalbeispiel, und genau das hat der TO gemacht.

von m.n. (Gast)


Lesenswert?

RT schrieb:
> // Alle Pins werden mit der schnellsten Geschwindigkeit betrieben

Nur nebenbei: Alle Pins nach Möglichkeit mit der langsamsten 
Gechwindigkeit betreiben. Geringe Flankensteilheit => geringe 
Störstrahlung.
Hohe Schaltgeschwindigkeit der Ausgangspins wird erst ab dem MHz-Bereich 
notwendig bzw. sinnvoll. Beispielsweise für schnelles SPI oder ext. RAM 
per FSMC.
Genaue Angaben finden sich im Datenblatt.

von RT (mcu-programmer)


Lesenswert?

>
> Ein gewisses Maß an Ordnung muß sein, auch wenn es dem einen oder
> anderen am Anfang vielleicht als übertrieben erscheint.
>
> W.S.

Im nächsten Schritt würde ich das optimieren, danke für den Tipp.

von RT (mcu-programmer)


Lesenswert?

m.n. schrieb:
> RT schrieb:
>> // Alle Pins werden mit der schnellsten Geschwindigkeit betrieben
>
> Nur nebenbei: Alle Pins nach Möglichkeit mit der langsamsten
> Gechwindigkeit betreiben. Geringe Flankensteilheit => geringe
> Störstrahlung.
> Hohe Schaltgeschwindigkeit der Ausgangspins wird erst ab dem MHz-Bereich
> notwendig bzw. sinnvoll. Beispielsweise für schnelles SPI oder ext. RAM
> per FSMC.
> Genaue Angaben finden sich im Datenblatt.

Da muss ich mich wohl noch einlesen.

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.