STM32F4 USART1 Probleme

Gast #5584287
Lesenswert?

Hallo,

ich habe Probleme den USART1 des STM32F413 zu nutzen. Am PC kommt nichts 
an. Beim Debugging wird das USART_DR = USARt1_DR Register auch nicht 
befüllt. Dazu habe ich allerdings gelesen, dass es u.U sofort ins Shift 
Register übertragen wird und somit der Debugger Probleme hat, den 
Zustand zu erfassen.
Mein Code ist recht übersichtlich. Vielleicht ist das Register zur 
Baudrate falsch? Das Reference dazu habe ich nicht verstanden, so dass 
ich
mich mit den 100000000/115200 begnügt habe.

Über den ein oder anderen Tipp wäre ich dankbar.


•
1
//APB2 bus clock  100 MHz
2
   APB2_USART1 |= 0x00000010U;       //Peripherie Bus Clock Enable
3
   USART_CR1   |= 0x00002008U;       //USART Enable
4
   USART_CR2   |= 0x00000000U;       //1 Stop Bit 
5
   USART_BRR    =(100000000/115200); //Baudrate
6

7
   while(1)
8
   {
9
   while(!(USART_SR & USART_SR_TXE));
10
   USART->DR = 55;
11
   }
Gast #5584294
Lesenswert?

Lutz schrieb:
> APB2_USART1 |= 0x00000010U;       //Peripherie Bus Clock Enable
>    USART_CR1   |= 0x00002008U;       //USART Enable

Müssen es unbedingt eigene Registernamen sein? Wenn du die aus der 
stm32f4xx.h nutzen würdest, könnte man dir leichter helfen. Nach 
aktivieren des Peripherie-Takts und vor erster Nutzung der 
Peripherie-Register muss ggf. ein __DSB() erfolgen.
Gast #5584318
Lesenswert?

Kann ihn auch so posten.
PA9+PA10 laufen in "Alternate Functions" Modus und GPIOA clock ist auch 
an.

•
1
RCC->APB2ENR |=  RCC_APB2ENR_USART1EN;
2
USART1->CR1 = USART_CR1_UE | USART_CR1_TE;
3
USART1->BRR = (16000000 / 115200);
4
while(1)
5
{
6
 while(!(USART1->SR & USART_SR_TXE));
7
 USART1->DR = 55;
8
}

Das __DSB() wird nicht erkannt.
Gast #5584414
Lesenswert?

Lutz schrieb:
> Das Reference dazu habe ich nicht verstanden

Eigentlich ganz einfach: das BRR stellt nicht nur einen ganzzahligen 
Teiler bereit (AVR-like), sondern man kann auch "Bruchzahlen" im 2er 
System darstellen. D.h. die erste Stelle nach dem Komma hat die 
Wertigkeit 0.5, die zweite 0.25, die dritte 0.125 usw...

Also suchst du dir den Teiler, der deine Eingangsfrequenz so runterteilt 
dass du in die Nähe der benötigten Baudrate kommst bzw. es exakt 
erreichst.

Kann man wunderbar in Code formulieren...
(Firma: fritzler-avr.de) #5585028
Lesenswert?

Der Teiler ist so schon in Ordnung.
Der UART hat eine 16fach Überabtastung des Signals (Dieser Takt muss ins 
BRR).
Aber die UART PLL hat 4 Nachkommastellen = 16 als Zahl.
Daher reichts da ne Ganzzahl reinzuwerfen.

Nur wirds jetzt in dem Thread hier inkonsistent wenn der APB einmal 
100MHz hat und einmal 16MHz.
Wie soll man da helfen?

Lutz schrieb:
> Kann ihn auch so posten.

Soll heßen, dass das jetzt nicht mehr der Code ist, der auf dem ARM 
läuft, sondern was zusammenkopiertes?
Gast #5585143
Lesenswert?

Mw E. schrieb:
> Der Teiler ist so schon in Ordnung.
> Der UART hat eine 16fach Überabtastung des Signals (Dieser Takt muss ins
> BRR).
> Aber die UART PLL hat 4 Nachkommastellen = 16 als Zahl.
> Daher reichts da ne Ganzzahl reinzuwerfen.
>
> Nur wirds jetzt in dem Thread hier inkonsistent wenn der APB einmal
> 100MHz hat und einmal 16MHz.
> Wie soll man da helfen?
>
> Lutz schrieb:
>> Kann ihn auch so posten.
>
> Soll heßen, dass das jetzt nicht mehr der Code ist, der auf dem ARM
> läuft, sondern was zusammenkopiertes?

Also, ich hatte zwei Varianten probiert. Einmal 16 MHZ Clock APB2 und 
100 MHz Clock APB2, daher die Verwirrung.

Ich hatte folgendes vergessen:
Es muss im Alternative Function Register zunächst noch eingestellt 
werden, welche alternative Funktion auf den Pin laufen soll. Das steht 
im Reference auf Seite 189. Bei mir ist das AF7 (SPI, USART1...3)

•
1
GPIOA_AFRH |= 0x00000770; //Alternative Funktion AF7 für PA9+PA10

Dann habe ich die Baudrate jetzt auch von Hand eingestellt.
100000000/115200/16 = 54,25347
Wobei nur 54,25 in das Register passt.

•
1
USART_BRR = 0x00000364; //= 54,25

Jedenfalls sendet TX nun. Hier der Code, falls es jmd interessiert.
Leider bekomme ich in unregelmäßigen Abständen falsche Zeichen 
übermitelt.
Vielleicht hat da ja jmd eine Idee ?

 •
1
  //für 100 MHz APB2
2
   GPIOA_AFRH |= 0x00000770;     //Alternate Functions AF7 für PA9 und PA10
3
   APB2_USART1 |= 0x00000010U;   //Peripherie Bus Clock Enable
4
   USART_CR1   |= 0x00002008U;   //USART Enable
5
   USART_CR2   |= 0x00000000U;   //1 Stop Bit  
6
   USART_BRR = 0x00000364;        //54,25  
7
 
8
  while(1)
9
   {
10
   USART1->DR = 'z';
11
   while( (USART_SR & 0x00000040 ) != 64  ); //Warte, bis TC gesetzt wurde
12
   }
Angehängte Dateien:

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