STM32F0 Discovery und UART1

#3403713
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.
#3403895
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.
#3405247
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!
Angehängte Dateien:
#3405579
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.
#3405815
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?
#3406101
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
Angehängte Dateien:
#3419487
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
#3421113
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!
#3421164
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.
#3421384
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.
#3421431
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!
#3421696
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.
#3428067
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!!
#3431818
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren