Forum: Mikrocontroller und Digitale Elektronik STM32F407 UART, PuTTY, USB to TTL FTDI adapter. Probleme


von Al3ko -. (al3ko)


Angehängte Dateien:

Lesenswert?

Hi

Ich bin mir gerade unsicher, welchen Fehler ich beim UART begehe. 
Verwendet wird der STM32F407 zusammen mit einem FTDI FT232RL Klon und 
PuTTY. Der Code ist sehr simpel: Es soll beim Starten des uC lediglich 
ein einzelnes Byte vom uC zum PC gesendet werden. Was ich jedoch aufm 
Terminal bekomme, ist nur Murks, und immer derselbe Murks unabhängig vom 
Byte, das gesendet werden soll. Anbei Code und Aufbau.

uC_TX -> FT232RL_RX
uC_GND -> FT232RL_GND

Kann jemand sehen, wo mein Fehler liegt?

Gruß,
1
#include "stm32f4xx.h"
2
3
//  UART1 is used. Sits on APB2 bus
4
//  GPIOA sits on AHB1 bus. USART1 is AF7 for PA9 and PA10
5
//  PA9:  USART1_TX
6
//  PA10:  USART1_RX
7
//  Baudrate: 9600
8
9
void funcGPIOInit();
10
void funcUARTInit();
11
void funcUARTSend();
12
13
int main(void)
14
{
15
  funcGPIOInit();
16
  funcUARTInit();
17
  funcUARTSend();
18
  for(;;)
19
  {
20
21
  }
22
}
23
24
void funcGPIOInit()
25
{
26
  // Enable AHB1 bus. Set PA9 and PA10 to AF,
27
  RCC->AHB1ENR |= (1<<RCC_AHB1ENR_GPIOAEN_Pos);
28
  GPIOA->MODER |= (2<<GPIO_MODER_MODER9_Pos);
29
  GPIOA->MODER |= (2<<GPIO_MODER_MODER10_Pos);
30
  GPIOA->OTYPER &= ~(1<<GPIO_OTYPER_OT9_Pos);
31
  GPIOA->OTYPER &= ~(1<<GPIO_OTYPER_OT10_Pos);
32
  GPIOA->OSPEEDR &= ~(3<<GPIO_OSPEEDR_OSPEED9_Pos);
33
  GPIOA->OSPEEDR &= ~(3<<GPIO_OSPEEDR_OSPEED10_Pos);
34
  GPIOA->PUPDR &= ~(3<<GPIO_PUPDR_PUPD9_Pos);
35
  GPIOA->PUPDR &= ~(3<<GPIO_PUPDR_PUPD10_Pos);
36
  GPIOA->AFR[1] |= (7<<GPIO_AFRH_AFSEL9_Pos);
37
  GPIOA->AFR[1] |= (7<<GPIO_AFRH_AFSEL10_Pos);
38
}
39
40
void funcUARTInit()
41
{
42
  // Enable APB2 bus.
43
  RCC->APB2ENR |= (1<<RCC_APB2ENR_USART1EN_Pos);
44
  // TxTxBaud = 9600. fck=16MHz. Oversampling by 8: USARTDIV=16MHz/(8*9600)=208.3333.
45
  // Mantissa = 208. Fraction = 0.33
46
  // 0.3333*8=2.667 = 3
47
  // 208dec = 0xD0
48
  USART1->BRR = 0xD03;
49
  USART1->CR1 |= (1<<USART_CR1_TE_Pos);  // Transmitter enable
50
  USART1->CR1 &= ~(1<<USART_CR1_PCE_Pos);  // Parity control disabled
51
  USART1->CR1 &= ~(1<<USART_CR1_M_Pos);  // 8bit word length
52
  USART1->CR1 |= (1<<USART_CR1_OVER8_Pos);  // Oversampling by 8
53
  USART1->CR2 &= ~(3<<USART_CR2_STOP_Pos);  // 1 stop bit
54
55
  USART1->CR1 |= (1<<USART_CR1_UE_Pos);  // Enable UART1
56
}
57
58
void funcUARTSend()
59
{
60
  USART1->DR = 120;
61
}

von jo mei (Gast)


Lesenswert?

Al3ko -. schrieb:
> Kann jemand sehen, wo mein Fehler liegt?

Wer deine Bare-Metal Kreation überprüfen will muss sich die
gleiche Arbeit machen wie du (falls du das überhaupt selbst
geschrieben hast). Alle Bits mühselig zusammensuchen, prüfen
und treilweise auch nachrechnen.

Da du keine "genormte" Programmierschnittstelle verwendest
macht das wirklich keinen Spass das nachzuvollziehen.
Vielleicht findet sich jemand.

Dabei wär's so einfach mit dem LL-Driver was nachzuvollziehen.

Das einzige was mir auf die Schnelle mühelos einfällt ist dass
du keinerlei Taktkonfiguration programmierst. Dann wird es auch
mit der Baudrate "schwierig".

von Al3ko -. (al3ko)


Lesenswert?

Hi jo mei
jo mei schrieb:
> Wer deine Bare-Metal Kreation überprüfen will muss sich die
> gleiche Arbeit machen wie du (falls du das überhaupt selbst
> geschrieben hast). Alle Bits mühselig zusammensuchen, prüfen
> und treilweise auch nachrechnen.
Ja, das stimmt leider. Es steht auf meiner ToDo list, in Zukunft LL zu 
lernen.
>
> Da du keine "genormte" Programmierschnittstelle verwendest
> macht das wirklich keinen Spass das nachzuvollziehen.
> Vielleicht findet sich jemand.
Ja hoffentlich. Wäre interessant zu sehen, welches Bit ich falsch 
gesetzt habe.

> Das einzige was mir auf die Schnelle mühelos einfällt ist dass
> du keinerlei Taktkonfiguration programmierst. Dann wird es auch
> mit der Baudrate "schwierig".
Was meinst du mit Taktkonfiguration? Der Standardtakt beim STM32F407 ist 
der interne RC mit 16MHz. Das ist der Standardwert nach Reset.

Gruß,

EDIT:
Wobei ich schon mal froh bin, dass du an meinem Aufbau nicht gemeckert 
hast. Ich bin/war mir nämlich nicht sicher, ob die 3.3V vom 
Discoveryboard an die 3.3V vom FT232RL müssen, oder ob RX & GND 
ausreichen.

: Bearbeitet durch User
von jo mei (Gast)


Lesenswert?

Al3ko -. schrieb:
> Ich bin/war mir nämlich nicht sicher, ob die 3.3V vom
> Discoveryboard an die 3.3V vom FT232RL müssen, oder ob RX & GND
> ausreichen.

Nö der FTDI versorgt sich selber, das sieht man ja schon an der LED.

Aber Tx hättest schon noch verdrahten können, oder war das zuviel
Arbeit?

von jo mei (Gast)


Lesenswert?

Al3ko -. schrieb:
> Der Standardtakt beim STM32F407 ist
> der interne RC mit 16MHz. Das ist der Standardwert nach Reset.

Aber kannst du auch sicher sein dass dieser Takt an der
Peripherie ankommt? Nö.

von jo mei (Gast)


Lesenswert?

Al3ko -. schrieb:
> Wobei ich schon mal froh bin, dass du an meinem Aufbau nicht gemeckert
> hast.

Du bist hier im Forum seit 11 Jahren angemeldet und hast über
1000 Beiträge geschrieben.

Was hast du in diesen 11 Jahren gemacht? Nur vor dich
hingewurschtelt und nichts gelernt?

von Al3ko -. (al3ko)


Lesenswert?

jo mei schrieb:
> Was hast du in diesen 11 Jahren gemacht? Nur vor dich
> hingewurschtelt und nichts gelernt?

Die Liebe meines Lebens gesucht ;) :D

von Bauform B. (bauformb)


Lesenswert?

Für mich sieht die Initialisierung gut aus, ich hätte höchstens für den 
ersten Versuch auf den /8-Mode verzichtet. Also ein paar theoretische 
Ideen:
Al3ko -. schrieb:
> FTDI FT232RL Klon
Stimmt die Beschriftung, ist RX wirklich mit TX verbunden?

Kann man die UART-Register sofort benutzen oder muss man dazwischen 
einige wenige Taktzyklen warten?
1
RCC->APB2ENR |= (1<<RCC_APB2ENR_USART1EN_Pos);
2
USART1->BRR = 0xD03;

Darf man ins DR schreiben ohne vorher das SR zu lesen? Normalerweise 
muss man immer erst das TXE-Flag abfragen?

Und noch ganz was obskures, eine meiner uart_init() endet so:
1
   uart->UE = 1;
2
   delay_us (1000); // ??? FIXME
3
   uart->RE = 1;
4
   uart->TE = 1;

von Norbert R. (nretro)


Lesenswert?

Zumindest bei einem F103 müsste noch die Clock für den AFIO-Bereich 
gesetzt werden, also RCC_APB2ENR_AFIOEN. Komischt kommt mir auch vor, 
dass beide Pins gleich konfiguriert werden. Sollte nicht einer Input und 
einer Output sein? Aber wie gesagt, hab' bisher nur mit F103 gespielt.

von Al3ko -. (al3ko)


Lesenswert?

Moin Bauform und Norbert,

vielen Dank für eure beiden Beiträge.

Ich habe den Fehler gefunden. PA9 und PA10 auf dem verwendeten Discovery 
board waren bereits für andere Zwecke hardwareseitig belegt. Ich 
verwende den USART1 jetzt über andere, freie Pins (PB6 und PB7) und 
siehe da, es wird ohne Probleme das richtige Zeichen gesendet. :)

Vielleicht wird es langsam Zeit, von den Discovery boards Abstand zu 
nehmen...

Gruß,

von pegel (Gast)


Lesenswert?

Al3ko -. schrieb:
> Vielleicht wird es langsam Zeit, von den Discovery boards Abstand zu
> nehmen...

Nö.
Die Verschaltung auf dem Board ansehen genügt, oder gleich in CubeMX 
nachsehen.

von m.n. (Gast)


Lesenswert?

Al3ko -. schrieb:
> Vielleicht wird es langsam Zeit, von den Discovery boards Abstand zu
> nehmen...

Die Zeit ist schon längst vorbei. Nucleo-Boards bieten mehr Freiraum für 
eigene Schaltungen.

von Johannes S. (Gast)


Lesenswert?

Auch auf den Nucleos kann man in diese Falle tappen, eine serielle ist 
auf den virtuellen COM Port vom angeflanschten STLink geführt. Die 
Header sind n.c. wenn man das nicht über die fieselig kleinen Lötjumper 
ändert.
Könnte beim Disco auch sein das die auf den STLink gehen, habe den 
Schaltplan nicht angesehen.

von ... (Gast)


Lesenswert?

m.n. schrieb:
> Al3ko -. schrieb:
>> Vielleicht wird es langsam Zeit, von den Discovery boards Abstand zu
>> nehmen...
>
> Die Zeit ist schon längst vorbei. Nucleo-Boards bieten mehr Freiraum für
> eigene Schaltungen.

Die sind unbrauchbar, denn bei denen stehen die Portnummern nicht mehr 
auf der Platine.
Dafür sind die unbrauchbaren Dummduino Header beschriftet, aber 
unbrauchbar in "D1", "D2" statt "PA12".
(Nucleo 32+64 als abschreckendes Beispiel, bei dem 144er steht das 
wenigstens unten, aber die Pinleiste ist nicht bestückt)

Was soll der Unsinn?

Bei den Discoverys ist der erste Schritt das Ablöten von MEMS und co, 
dann ist es perfekt.

von Johannes S. (Gast)


Lesenswert?

... schrieb:
> Die sind unbrauchbar, denn bei denen stehen die Portnummern nicht mehr
> auf der Platine.

das soll ein K.O. Kriterium sein? Da drucke ich bei Bedarf die eine 
Seite aus dem User Manual aus oder nehme die bunten Anschlussbilder von 
Mbed/Arduino.
Die Nucleos haben den Firlefanz gar nicht erst drauf und sowas wie die 
serielle Schnittstelle ist eine kleine Ausnahme, die ja aber auch durch 
Jumper geändert werden kann.

von pegel (Gast)


Lesenswert?

Ihr dürft nur nicht vergessen, dass die Jungs ihre neuen Bauteile 
vorstellen wollen.

Nur deshalb sind die so günstig.

Sonst hinge da sicher (wie bei einigen anderen Herstellern) noch 
mindestens eine Null am Preis.

von ... (Gast)


Lesenswert?

Johannes S. schrieb:
> das soll ein K.O. Kriterium sein? Da drucke ich bei Bedarf die eine
> Seite aus dem User Manual aus oder nehme die bunten Anschlussbilder von
> Mbed/Arduino.

JA!
(Das bunte Bild kam auf der Pappe sogar mit)

Discovery:
Du ließt PA12 und steckst da das Kabel rein, fertig.

Nucleo:
Auf dem Bildchen ist auch PA12 zu finden, aber musst danach erst einmal 
den passenden Pin am Nucleo abzählen.
Das ist durchaus Mehraufwand und fehleranfällig.

Ich bin an die Sache Nucleo vs Discovery voreingenommen rangegangen, 
aber das hat sich schnell als Fehlschlag erwiesen.
Da ist man andauernd am Pin suchen.

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.