Forum: Mikrocontroller und Digitale Elektronik STM32F4 USART1 Probleme


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Lutz (Gast)


Bewertung
-2 lesenswert
nicht 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
   }

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
1 lesenswert
nicht lesenswert
Dein Code ist nicht übersichtlich sondern kompletter Murks!
"0x00002008U"
Bits haben Namen, ich drösel das jetzt garanriert nicht auf um dir 
helfen zu können.

von Dr. Sommer (Gast)


Bewertung
2 lesenswert
nicht 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.

von Lutz (Gast)


Bewertung
-2 lesenswert
nicht 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.

von Jan K. (jan_k)


Bewertung
0 lesenswert
nicht lesenswert
Das brr ist doch Quatsch oder?

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Lutz schrieb:
> Das __DSB() wird nicht erkannt.

Das ist auch in der CMSIS drin, der du dich ja anscheinend verweigerst.

Dann halt:
1
__asm__ volatile ("dsb");

von TrollJäger (Gast)


Bewertung
0 lesenswert
nicht lesenswert

von TrollJäger (Gast)


Bewertung
0 lesenswert
nicht lesenswert
BTW: NUTZE CMSIS!

von TrollJäger (Gast)


Bewertung
2 lesenswert
nicht lesenswert
Lutz schrieb:
> Das Reference dazu habe ich nicht verstanden, so dass
> ich
> mich mit den 100000000/115200 begnügt habe.

Nimm doch einen Wert aus der Tabelle, steht doch im RefMan...

von TrollJäger (Gast)


Bewertung
0 lesenswert
nicht 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...

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
1 lesenswert
nicht 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?

von Lutz (Gast)


Angehängte Dateien:

Bewertung
-2 lesenswert
nicht 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
   }

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Lutz schrieb:
> while( (USART_SR & 0x00000040 ) != 64  ); //Warte, bis TC gesetzt
> wurde

Du musst auf TXE und nicht auf TC warten, so wie du es im 
Ausgangsposting schon richtig gemacht hattest...

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
2 lesenswert
nicht lesenswert
Schonwieder Magic Numers.
Ich bin raus, du willst keine Hilfe...

von Lutz (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
> Lutz schrieb:
>> while( (USART_SR & 0x00000040 ) != 64  ); //Warte, bis TC gesetzt
>> wurde
>
> Du musst auf TXE und nicht auf TC warten, so wie du es im
> Ausgangsposting schon richtig gemacht hattest...

Besten Dank.

So läuft nun.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.