Kommunikation zwischen mController und PC

OP #7338458
Lesenswert?

Hallo,

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

Hierfür nutze ich ...

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.

Gast #7338494
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.

Gast #7338496
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.

Angehängte Dateien:
Gast #7338505
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).

Gast #7338544
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.

Beitrag #7338586 wurde von einem Moderator gelöscht.
OP #7338588
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
> 
12
>

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.

OP #7338597
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?

Gast #7338775
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.

Gast #7338856
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.

Gast #7338934
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.

OP #7339008
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.

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