mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32F4 USART1 Probleme


Autor: Lutz (Gast)
Datum:

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.


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

   while(1)
   {
   while(!(USART_SR & USART_SR_TXE));
   USART->DR = 55;
   }


Autor: Mw E. (Firma: fritzler-avr.de) (fritzler)
Datum:

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.

Autor: Dr. Sommer (Gast)
Datum:

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.

Autor: Lutz (Gast)
Datum:

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

•

RCC->APB2ENR |=  RCC_APB2ENR_USART1EN;
USART1->CR1 = USART_CR1_UE | USART_CR1_TE;
USART1->BRR = (16000000 / 115200);
while(1)
{
 while(!(USART1->SR & USART_SR_TXE));
 USART1->DR = 55;
}


Das __DSB() wird nicht erkannt.

Autor: Jan K. (jan_k)
Datum:

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

Autor: Dr. Sommer (Gast)
Datum:

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:
__asm__ volatile ("dsb");

Autor: TrollJäger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: TrollJäger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
BTW: NUTZE CMSIS!

Autor: TrollJäger (Gast)
Datum:

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...

Autor: TrollJäger (Gast)
Datum:

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...

Autor: Mw E. (Firma: fritzler-avr.de) (fritzler)
Datum:

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?

Autor: Lutz (Gast)
Datum:
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)

•
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.

•
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 ?

 •
  //für 100 MHz APB2
   GPIOA_AFRH |= 0x00000770;     //Alternate Functions AF7 für PA9 und PA10
   APB2_USART1 |= 0x00000010U;   //Peripherie Bus Clock Enable
   USART_CR1   |= 0x00002008U;   //USART Enable
   USART_CR2   |= 0x00000000U;   //1 Stop Bit  
   USART_BRR = 0x00000364;        //54,25  
 
  while(1)
   {
   USART1->DR = 'z';
   while( (USART_SR & 0x00000040 ) != 64  ); //Warte, bis TC gesetzt wurde
   }

Autor: Dr. Sommer (Gast)
Datum:

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...

Autor: Mw E. (Firma: fritzler-avr.de) (fritzler)
Datum:

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

Autor: Lutz (Gast)
Datum:

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.

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