Datum:
|
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; } |
Datum:
|
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.
Datum:
|
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.
Datum:
|
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.
Datum:
|
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"); |
Datum:
|
https://www.st.com/en/embedded-software/stm32snippets.html?querycriteria=productId=LN1898 dort findest du auch ein paar Beispiele für UART
Datum:
|
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...
Datum:
|
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...
Datum:
|
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?
Datum:
|
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 } |
Datum:
|
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...
Datum:
|
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.