Forum: Mikrocontroller und Digitale Elektronik STM32F4 USART1 Probleme


von Lutz (Gast)


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)


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)


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)


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)


Lesenswert?

Das brr ist doch Quatsch oder?

von Dr. Sommer (Gast)


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)


Lesenswert?


von TrollJäger (Gast)


Lesenswert?

BTW: NUTZE CMSIS!

von TrollJäger (Gast)


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)


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)


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:

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)


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)


Lesenswert?

Schonwieder Magic Numers.
Ich bin raus, du willst keine Hilfe...

von Lutz (Gast)


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.

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.