Forum: Mikrocontroller und Digitale Elektronik STM32F0 Discovery und UART1


von Michael N. (betonmicha)


Lesenswert?

Hallo hat schon jemand den UART1 des STM32F0 Discovery Board zum laufen 
bekommen?
Der UART selber läuft, es scheint bloß eine falsche Baudrate eingestellt 
zu sein. Läuft auf dem Board irgendwas ungenau?

Meine Initialisierung sieht so aus:

1
void uartInit(void) {
2
  GPIO_InitTypeDef GPIO_InitStruct;
3
  USART_InitTypeDef USART_InitStruct;
4
  NVIC_InitTypeDef NVIC_InitStructure;
5
6
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
7
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
8
9
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // Pins 9 (TX) and 10 (RX) are used
10
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // the pins are configured as alternate function so the USART peripheral has access to them
11
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // this defines the IO speed and has nothing to do with the baudrate!
12
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // this defines the output type as push pull mode (as opposed to open drain)
13
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // this activates the pullup resistors on the IO pins
14
  GPIO_Init(GPIOA, &GPIO_InitStruct);
15
16
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); //
17
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
18
19
  USART_InitStruct.USART_BaudRate = 57600; // the baudrate is set to the value we passed into this init function
20
  USART_InitStruct.USART_WordLength = USART_WordLength_8b; // we want the data frame size to be 8 bits (standard)
21
  USART_InitStruct.USART_StopBits = USART_StopBits_1; // we want 1 stop bit (standard)
22
  USART_InitStruct.USART_Parity = USART_Parity_No; // we don't want a parity bit (standard)
23
  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard)
24
  USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver
25
  USART_Init(USART1, &USART_InitStruct);
26
27
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt
28
  USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // enable the USART1 receive interrupt
29
30
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // we want to configure the USART1 interrupts
31
  NVIC_InitStructure.NVIC_IRQChannelPriority = 0; // this sets the priority group of the USART1 interrupts
32
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART1 interrupts are globally enabled
33
  NVIC_Init(&NVIC_InitStructure); // the properties are passed to the NVIC_Init function which takes care of the low level stuff
34
35
  // finally this enables the complete USART1 peripheral
36
  USART_Cmd(USART1, ENABLE);
37
}

Die Baudrate ist mit 57600 eingestellt. Ich benutze das gleiche Beispiel 
mit dem STMF4 Discovery, natürlich ein bisschen abgeändert.

An der Initialisierung dürfte es nicht liegen, also vermute ich das die 
Frequenzeintsellungen falsch sind. Ich hab aber auch schon die grüne LED 
blinken lassen und diese blinkt dann auch mit 1 Sekunde so wie 
eingestellt.
Für den Prozessor scheint ja kein Quarz verbaut zu sein. Wird da die 
interne Taktgenerierung benutzt? Ist die zu ungenau für die Baudrate?
Ich benutze die system_stm32f0xx.c aus der CMSIS.

Wenn ich "TEST" schicke kommt "TusW" zurück. Der STM32F0 empfängt und 
sendet das gleiche. Es gibt also schon beim Empfang Probleme.

{EDIT]
Ich habe jetzt ein 4 MHz Quarz eingelötet. Hat aber keine Besserung 
gebracht. Wie gesagt, bereits beim Empfang werden Fehler erzeugt.
Mein Interrupt sieht so aus:
1
void USART1_IRQHandler(void) {
2
  // check if the USART1 receive interrupt flag was set
3
  if (USART_GetITStatus(USART1, USART_IT_RXNE)) {
4
    writeToRxBuf(USART1->RDR);
5
  }
6
7
  if (USART_GetITStatus(USART1, USART_IT_TXE)) {
8
    uartTX();
9
  }
10
}

Das RDR wird direkt in ein Puffer gespeichert.

: Bearbeitet durch User
von Jim M. (turboj)


Lesenswert?

Zur Abweichung vom Quarz (oder dem internen Oszillator) kommt noch die 
Abweichung bei der Bautraten-Generierung dazu. Nähres sollte man dann im 
Manual nachlesen können.

Eventuell lohnt es sich auszurechnen, wie genau der Baudratengenerator 
bei 4 Mhz die 57600 Baud überhaupt treffen kann. Genauer gehts mit einen 
Baudratenquarz.

von Mehmet K. (mkmk)


Angehängte Dateien:

Lesenswert?

Anbei meine Routinen, mit denen ich die USART1 im STM32F0 initialisiere.
Eine meiner beliebtesten Fallen, in die ich regelmaessig hineintappe: 
die PLL Werte nicht an den verwendeten Quarz anpassen.

MfG

von Michael N. (betonmicha)


Lesenswert?

Im Datenblatt steht ein Fehler von ca. 0,02% bei 57600 baud. Ich 
probiere jetzt mal andere Baudraten aus. Wo der Fehler gleich 0 ist.

Danke für deine Routine Mehmet, hat leider auch nicht geholfen. Muss ich 
noch tiefer graben.

von Mehmet K. (mkmk)


Lesenswert?

Michael, hast Du in der init auch die Baudrate angespasst?
Wenn meine Routine nicht funktioniert hat (die Routine laeuft auf 
mehreren Geraeten) dann ist sicherlich Deine PLL falsch eingestellt.

von Sepp (Gast)


Angehängte Dateien:

Lesenswert?

Zur PLL Einstellung sehr zu empfehlen!
Ist für den STM32F2xx
Soll aber ein Denkanstoß sein.

von Michael N. (betonmicha)


Angehängte Dateien:

Lesenswert?

Ich hab jetzt auf USART2 umgestellt, genau das gleiche Problem. Sieht 
für mich also immer noch nach Baudratenproblem aus.

Hier ist mal meine system_stm32f0xx.c, vielleicht findet jemand einen 
Fehler. Ich komm irgendwie nicht weiter. Für heute ist Schluss.

[EDIT]
Sorry die erste Datei ist die falsche. Bitte die zweite ansehen!

: Bearbeitet durch User
von Mehmet K. (mkmk)


Angehängte Dateien:

Lesenswert?

Michael, das ist aber nicht die system_stm32f0xx.c vom STM32F0.

Ich haenge mal meine Benutzten hier an.
Ist zwar Vers. 1.0.0 und nicht 1.1.0, der Unterschied ist aber minimal.
Versuch's mal damit.

von Michael N. (betonmicha)


Lesenswert?

Hallo Mehmet,

das ist eine generierte vom Clock Configuration Tool für den STM32F0. 
Ich hab deine Initialisierung und den Startupcode von dir benutzt, ich 
habe nur die HSE Frequenz in 4 MHz geändert und den PLL Multiplikator 
von 6 auf 12 gesetzt. Immer noch das gleiche Problem.

Ich hab schon fast die Vermutung, das der STM32F0 defekt ist. Es sind 
auch keine zufälligen Fehler, es kommt immer der gleiche falsche String 
zurück. Ich setze gleich nochmal eine neues Projekt auf, villeicht hab 
ich noch einen anderen Fehler. Das kann ich mir nicht vorstellen, denn 
das Programm funktioniert auf einem STM32F4 einwandfrei.

von Mehmet K. (mkmk)


Lesenswert?

Deiner letzten Post entnehme ich, dass Du ein 4MHz Quarz an die MCU 
angeschlossen hast.

Frage:
Hast Du
- die Jumper SB20 und SB21 entfernt
- die Kondensatoren C16 und C15 eingesetzt
- die Jumper R24 und R25 eingesetzt?

von Michael N. (betonmicha)


Lesenswert?

Genau ich hab einen 4 MHz Quarz (X2) eingesetzt. 8 MHz hatte ich gerade 
nicht zur Hand.

Ich hab im Datenblatt nachgesehen und dort steht das SB16, SB17 und SB18 
offen sein sollen. Die Kondensatoren C13 und C14 sind gesetzt. R22 und 
R23 sind überbrückt. Die Jumper und Kondensatoren die du genannt hast, 
sind doch für X3 oder sehe ich das falsch?

von Mehmet K. (mkmk)


Angehängte Dateien:

Lesenswert?

Bitte vielmals um Entschuldigungen. Die Werte die ich nannte, gelten für 
den 32kHz Quarz.
Hier mal meine Notizen für den STM32F0-Discovery, wobei ich bei denen 
immer den ST-Link demontiere und direct mit dem SW arbeite.

- 8MHz Quarz X1 entfernen und als X2 einlöten
- C14, C13: 20pf
- R22, R23: 0R
- JP2: kurzschliessen
- D2 : kurzschliessen

- SB6, SB8, SB10, SB12 entfernen
- SB16, SB17 SB18, SB19 entfernen
- LD2 entfernen

Falls 32,768kHz Quarz X3 eingesetzt wird:
 - SB20, SB21 entfernen
 - R24, R25: R0

Falls VBAT benutzt wird: SB1 enternen

von Mehmet K. (mkmk)


Lesenswert?

Ich habe Deine PLL Einstellung in der 2. Datei kontrolliert: die ist 
korrekt.
Ne dumme Frage: hast Du in der stm32f0xx.h Datei den HSE_VALUE Wert auf 
4MHz gesetzt?

von Michael N. (betonmicha)


Lesenswert?

Ja hab ich auch auf 4000000 eingestellt. Langsam hab ich echt das Gefühl 
das irgendwas am Board nicht passt.
Ich glaub ich habe noch ein 16 MHz Quarz. Ich werd das mal tauschen und 
schauen ob es damit funktioniert. Ansonsten bin ich echt ratlos.

von Michael N. (betonmicha)


Lesenswert?

So ich habe es jetzt geschafft.
Der Fehler lag ganz woanders. Ich habe das Projekt vom STM32F4 Discovery 
aufs STM32F0 Discovery portiert. Das war auch alles richtig. Der Fehler 
lag aber im Startup des F4 Discovery. Dort war (ich weiß nicht mehr 
wieso) der HSE Wert mit 24 MHz angegeben. Verbaut ist aber nur ein 8 MHz 
Quarz. Deshalb hat es dort mit 57600 baud funktioniert. Durch die 
falsche Angabe lief das F4 Discovery also 3 mal langsamer und hatte 
statt 57600 baud nur 19200 baud. Nachdem ich den HSE Wert auf 8 MHz 
geändert habe und 19200 baud eingestellt habe, hat alles funktioniert. 
Das F0 Discovery läuft jetzt auch mit 19200 baud und alles ist fein.

EDIT
Vielen Dank für deine Hilfe Mehmet

: Bearbeitet durch User
von Simon H. (elefant)


Lesenswert?

Hi Michael
ich habe deinen Thread "STM32F0 Discovery und UART1"
gelesen da ich ein ähnliches Problem habe.
Ich arbeite mit dem STM32F4 Discoveryboard,
mein Programm arbeitet mit 25MHz Systemtakt, für die
USART-Übertragung habe ich eine Library gefunden welche aber
für einen Systemtakt mit 8MHz ausgelegt ist, leider funktioniert
diese Library nicht in meinem Programmm, da die Frequenzen für den
Systemtakt unterschiedlich sind. Kannst du mir vielleicht helfen ohne
das ich den Systemtakt ändern muss?

Vielen Dank für deine Hilfe!

von Michael N. (betonmicha)


Lesenswert?

Die Einstellung der Baudrate sollte unabhängig von der Frequenz 
funktionieren, besser gesagt, sie sollte automatisch an die Frequenz 
angepasst werden.

Welche Library benutzt du denn? Benutzt du die ST Libraries? Ein paar 
mehr Informationen wären nicht schlecht, sonst kann ich dir nicht 
helfen.

von Simon H. (elefant)


Angehängte Dateien:

Lesenswert?

ich lad dir mal meine Library hoch!!

von Michael N. (betonmicha)


Lesenswert?

Ich habs jetzt nur überflogen, aber soweit ich es sehe ist die Library 
unabhängig vom Systemtakt. Es muss also ein anderer Fehler sein (es sei 
denn es sind Fehler in der Library).

Was ist denn überhaupt dein Problem?

von Simon H. (elefant)


Lesenswert?

Also wenn ich die Library als Programm laufen lasse funktioniert diese 
einwandfrei, Systemtakt auf 8MHz eingestellt, binde ich diese Library in 
mein Projekt ein (Systemtakt 25MHz) läuft das Programm nicht mehr.
Soweit der Stand

von Michael N. (betonmicha)


Lesenswert?

Was bedeutet denn "Programm läuft nicht"? Kommen wirre Zeichen?
Das Problem muss dann in deinem Programm liegen, da die Baudrate anhand 
der Frequenz eingestellt wird.
Was für ein Quarz ist verbaut, 8MHz? Wie ist dein HSE Wert im Programm? 
Da sind irgendwelche Einstellungen falsch.

Wenn du mal deine Dateien mit den Einstellungen hochladen würdest, 
könnte ich vielleicht weiterhelfen. Ich vermute bei dir heißen die 
Dateien auch system_stm32f4.c/h

Den HSE Wert muss auf dein Quarz angepasst sein, das verbaut ist. Die 
steht in der stm32f4.h glaub ich. Oder sie ist beim Compiler als 
Präprozessor Direktive eingestellt.

von Simon H. (elefant)


Angehängte Dateien:

Lesenswert?

Ich hab einen 8MHz Quarz eingebaut, kurios ist HSE Frequenz ist auf 
25MHz eingestellt und PLL_M auch auf 25, mit diesen Einstellungen läuft 
das Programm. Änder ich nun diese Frequenzen auf 8MHz, startet das 
Programm nicht, ich kann nicht reseten, gar nichts.

von Michael N. (betonmicha)


Lesenswert?

Also die HSE muss auf 8 MHz gesetzt werden, ansonsten werden alle 
anderen Frequenzen falsch berechnet.

Wenn es dann nicht funktioniert, gibt es noch einen anderen Fehler. Was 
funktioniert denn nicht. Beschreib den Fehler doch bitte mal etwas 
genauer.

von Simon H. (elefant)


Lesenswert?

Ich steuer ein Display an, ich messe Frequenzen mit dem Input Capture 
Mode, wenn ich die HSE auf 8MHz stelle funktioniert noch alles, aber 
sobald ich die PLL_M auch auf 8 stelle geht nichts mehr, das Display 
zeigt nichts mehr an, das Programm wird aber fehlerfrei gebuildet!

von Michael N. (betonmicha)


Lesenswert?

Also beides muss auf 8 eingestellt sein.
dimmst du die Hintergrundbeleuchtung deines Displays über einen Timer? 
So mache ich das. Bei mir war nach der Änderung der Frequenz auch das 
Display "aus". Es war allerdings nicht wirklich aus, sonder der Timer 
lief viel langsamer und so war die Hintergrundbeleuchtung aus.
Nach anpassen des Timers ging alles normal bei mir.

von Simon H. (elefant)


Lesenswert?

sorry für die späte Rückmeldung!

also ich habs nun soweit hinbekommen, dass mein Hauptprogramm wieder 
läuft, aber die UART-Daten nicht eingelesen bzw verarbeitet werden.
Ich denke irgendwo sind dort unstimmigkeiten mit SPI und UART,
kann es sein, dass die Frequenzen ein Problem machen.
Das Display spreche ich hauptsächlich über SPI-Funktionen an!!

von Michael N. (betonmicha)


Lesenswert?

Funktioniert denn das Anzeigen auf dem Display generell? Probier beides 
mal getrennt. Wenn beides einzeln funktioniert, kannst du es in 
Kombination probieren.

von Simon H. (elefant)


Lesenswert?

jetzt klappt auch beides in Kombination, nur werden nicht alle Daten 
richtig empfangen bzw gesendet, da muss noch irgendwo ein kleiner 
Timing-Fehler sein.

von Michael N. (betonmicha)


Lesenswert?

Wie sieht denn dein Aufbau aus. Wer sendet die Daten und wer empfängt?

von Simon H. (elefant)


Lesenswert?

das GPS-Modul sendet GPS-Daten über UART an den STM32F4, dieser empfängt 
die Daten und sendet diese unverfälscht an ein MAX3232 und dann an die 
RS232 Schnittstelle wo ich mit einem Teminalprogramm die Daten auslese.

von Simon H. (elefant)


Angehängte Dateien:

Lesenswert?

Hab mal zwei .txt Dateien hochgeladen mit den Daten die ich empfange,
in der einen Datei sind die Daten die ich empfange wenn ich die Abfrage 
im laufenden Projekt mache, in der anderen Datei die Daten die ich 
empfange wenn ich die Bibliothek alleine laufen lasse.

von Michael N. (betonmicha)


Lesenswert?

Wenn die drei Baudraten (GPS, STM32F4, RS232) übereinstimmen, vemute ich 
weiterhin ein Problem beim STM32F4. Ich habe deinen Programmcode noch 
nicht durchgeschaut. Aber ich würde dort das Problem vermuten.

von Simon H. (elefant)


Lesenswert?

ja, alles bei 38400 Baud, ich denke es hat irgendwas mit Timings zu 
tun?!

von Michael N. (betonmicha)


Lesenswert?

Du benutzt zwei UARTs und beide ohne Interrupts, oder?
Es könnte sein, das sie sich gegenseitig stören, wenn sie warten.

von Simon H. (elefant)


Lesenswert?

Das Empfangen von UART läuft über einen Interrupt! Und ich benutze nur 
einen UART vom STM32

von Simon H. (elefant)


Lesenswert?

doch eigentlich wenn der Interrupt richtig läuft dürfte es doch keine 
Timing-Probleme geben?!

von Michael N. (betonmicha)


Lesenswert?

Ich hab deine UART Funktionen gerade mal überflogen. Was mir auffällt:
1
void P_UART_Receive(UART_NAME_t uart, uint16_t wert)
2
{
3
  if(UART_RX[uart].wr_ptr<RX_BUF_SIZE) {
4
    // wenn noch Platz im Puffer
5
    if(UART_RX[uart].status==RX_EMPTY) {
6
      // wenn noch keine Endekennung empfangen wurde
7
      if((wert>=RX_FIRST_CHR) && (wert<=RX_LAST_CHR)) {
8
        // Byte im Puffer speichern
9
        UART_RX[uart].rx_buffer[UART_RX[uart].wr_ptr]=wert;
10
        UART_RX[uart].wr_ptr++;
11
      }
12
      if(wert==RX_END_CHR) {
13
        // wenn Endekennung empfangen
14
        UART_RX[uart].rx_buffer[UART_RX[uart].wr_ptr]=wert;
15
        UART_RX[uart].status=RX_READY;
16
      }
17
    }
18
  }
19
  else {
20
    // wenn Puffer voll ist
21
    UART_RX[uart].status=RX_FULL;
22
  }
23
}

bei if(wert==RX_END_CHR) schreibst du einen Wert in den Puffer aber 
machst kein wr_ptr++ am Ende. Ist das so beabsichtigt?

Außerdem hast du ein Problem mit deinem Puffer, wenn der String länger 
als der Puffer ist. Zurückgesetzt wird der Puffer erst wenn du den 
String einliest. Ich denke da musst du deinen Fehler suchen.

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.