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
voidfuncGPIOInit();
10
voidfuncUARTInit();
11
voidfuncUARTSend();
12
13
intmain(void)
14
{
15
funcGPIOInit();
16
funcUARTInit();
17
funcUARTSend();
18
for(;;)
19
{
20
21
}
22
}
23
24
voidfuncGPIOInit()
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
voidfuncUARTInit()
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.
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".
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.
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?
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ö.
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?
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:
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.
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ß,
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.
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.
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.
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.
... 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.
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.
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.