UART ISR Problem STM32F1

Gast #6142719
Lesenswert?

Hi,

ich habe scheinbar ein Problem mit meinem UART ISR oder der 
Initialisierung.

Folgendes Problem:

Ich empfange Daten via UART per Interrupt. Nun ist das Problem das mein 
ISR zwar ausgelöst wird aber die ankommenden Daten sind Müll. 
Interessanter Weise sind die Daten immer gleich. Also sieht nicht so aus 
als würde die Variable von "außen" zerschossen werden.

Hab ich nen SWD Debugger dran passiert dieses Problem nicht. Liegt für 
mich also nah das es ein Timing Problem beim Initalisieren ist, aber ich 
habe mit verschiedenen Pausen gespielt ohne Änderung.

Code läuft mit Debugger immer, ohne Debugger gar nicht oder nur sehr 
selten. Das konnte ich bisher nicht zuverlässig diagnostizieren.

Hier mein Code für den Init:
1
if (HAL_UART_Receive_IT(&huart5, display_Rx, 15) == HAL_OK) { // enabling uart interrupt
2
      __HAL_UART_ENABLE_IT(&huart5, UART_IT_IDLE); // enabling idle interrupt
3
    }

Wie gesagt der Interrupt wird zuverlässig aufgerufen, nur eben die daten 
in display_Rx sind mist.

Habe es mit Pausen davor und danach versucht aber ohne Erfolg.
Gast #6142753
Lesenswert?

peterpan schrieb:
> Liegt für
> mich also nah das es ein Timing Problem beim Initalisieren ist, aber ich
> habe mit verschiedenen Pausen gespielt ohne Änderung.

Wenn du schon den Fehler an der Stelle vermutest, solltest du auch den 
Code der Clock-Initialisierung posten. Vermutlich fehlt an der Stelle 
ein:
1
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)!= SET);
Gast #6143365
Lesenswert?

D. W. schrieb:
> peterpan schrieb:
>> Liegt für
>> mich also nah das es ein Timing Problem beim Initalisieren ist, aber ich
>> habe mit verschiedenen Pausen gespielt ohne Änderung.
>
> Wenn du schon den Fehler an der Stelle vermutest, solltest du auch den
> Code der Clock-Initialisierung posten. Vermutlich fehlt an der Stelle
> ein:while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)!= SET);
1
void SystemClock_Config(void)
2
{
3
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
4
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
5

6
  /** Initializes the CPU, AHB and APB busses clocks 
7
  */
8
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
9
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
10
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
11
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
12
  RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_HSE;
13
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
14
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
15
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
16
  RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL_NONE;
17
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
18
  {
19
    Error_Handler();
20
  }
21
  /** Initializes the CPU, AHB and APB busses clocks 
22
  */
23
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
24
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
25
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
26
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
27
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
28
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
29

30
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
31
  {
32
    Error_Handler();
33
  }
34
  /** Configure the Systick interrupt time 
35
  */
36
  __HAL_RCC_PLLI2S_ENABLE();
37
}

Die Sachen sind ja HAL / CubeMX generiert....



Stefan ⛄ F. schrieb:
> peterpan schrieb:
>> Hab ich nen SWD Debugger dran passiert dieses Problem nicht.
>
> Hast du GND Leitungen von der Gegenstelle mit dem STM32 verbunden? Oder
> etwa nur RxD und TxD?

Selbstverständlich auch GND.
Gast #6143393
Lesenswert?

peterpan schrieb:
> UART ISR Problem STM32F1

Welcher F1 denn? Gibt es nur einen? Ist es ein selbstgebautes
Board oder ein fertiges? Wenn alles schon fertig, welches?

Solche Fragen kommen auf wenn die notwendigen Informationen
nicht oder nur in Salamitaktik geliefert werden.

Könnte es nicht sein dass an deinem UART5 Anschluss etwas
dranhängt was dort nicht hingehört?
Gast #6143410
Lesenswert?

Beo Bachta schrieb:
> Welcher F1 denn? Gibt es nur einen? Ist es ein selbstgebautes
> Board oder ein fertiges? Wenn alles schon fertig, welches?

F107, der hat 5.

Board ist ein eigenes. Die Clock Config funktioniert schon ewig. Der 
UART lief auch lange Zeit sauber, aber mit einmal brachte es dann 
Fehler. Das Problem ist ja vorwiegend das es sich nicht debuggen lässt.

Habe auch ein gleiches, andereres Board probiert um die HW 
auszuschließen. Gleiches Problem.
Gast #6143445
Lesenswert?

Nachdem du
1. nur häppchenweise den halben Code rausrückst und
2. sich in Folge dessen keiner durch die undurchschaubaren 
Funktionsaufrufe des HAL ein Bild von der Anwendung machen kann..hier 
mal ein hint der dir vielleicht weiter hilft:

https://www.st.com/resource/en/datasheet/stm32f105r8.pdf Seite 19/20
1
The STM32F105xx and STM32F107xx connectivity line embeds three universal
2
synchronous/asynchronous receiver transmitters (USART1, USART2 and USART3) and
3
two universal asynchronous receiver transmitters (UART4 and UART5).
1
USART1, USART2 and USART3 also provide hardware management of the CTS and RTS
2
signals, Smart Card mode (ISO 7816 compliant) and SPI-like communication capability. All
3
interfaces can be served by the DMA controller except for UART5.
Gast #6143461
Lesenswert?

D. W. schrieb:
> Nachdem du
> 1. nur häppchenweise den halben Code rausrückst und
> 2. sich in Folge dessen keiner durch die undurchschaubaren
> Funktionsaufrufe des HAL ein Bild von der Anwendung machen kann..hier
> mal ein hint der dir vielleicht weiter hilft:
>
> https://www.st.com/resource/en/datasheet/stm32f105r8.pdf Seite 19/20
> The STM32F105xx and STM32F107xx connectivity line embeds three universal
> synchronous/asynchronous receiver transmitters (USART1, USART2 and
> USART3) and
> two universal asynchronous receiver transmitters (UART4 and
> UART5).USART1, USART2 and USART3 also provide hardware management of the
> CTS and RTS
> signals, Smart Card mode (ISO 7816 compliant) and SPI-like communication
> capability. All
> interfaces can be served by the DMA controller except for UART5.

Danke. Welchen weiteren Code brauchst Du denn?

DMA ist ja nicht notwenig an dieser Stelle. Daher sollte das auch kein 
Problem sein. Zumal ja nach wie vor der Debugger den Code funktionieren 
lässt und Standalone nicht - was ich als Haupt "Problem" sehe.
Gast #6143509
Lesenswert?

pegel schrieb:
> Hast Du die aktuelle CubeMX Version?

Hi, ja habe ich. Ich nutze CubeIDE, in der neusten Version. Das Projekt 
ist allerdings schon älter, hat also schon mehrere Versionen gesehen. 
Der Fehler trat aber nicht nach oder vor einen Update auf.

UART5 läuft auf 115200. Im Anhang mal ein Bild der Clock Config.

Am OSC_IN / OUT hängt ein ECS-080-18-23G-JGN-TR.
Am OSC32_IN / OUT ein MC-306 32.7680K-A0:ROHS
Gast #6149926
Lesenswert?

Ich würde das gern noch mal hochholen. Leider habe ich nach mehreren 
Tagen immer noch nicht den Fehler gefunden. Nach wie vor funktioniert 
der Code via Debugger und ohne nicht / selten.

Hat noch jemand Ideen oder brauch weitere Infos / Code?
Gast #6149934
Lesenswert?

Es geht aber ganz Sicher um den STM32F1?

Ich frage, weil mir bezüglich der Taktkonfiguration von OpenOCD etwas 
seltsamen aufgefallen ist: 
http://stefanfrings.de/stm32/system_workbench.html#clock_bug

Aber das betraf nur die anderen Modelle.

Falls du auch OpenOCD verwendest, könnte es dennoch einen Versuch Wert 
sein, mal deine Konfigurationsdatei zu überprüfen, so wie ich das damals 
gemacht habe.
Gast #6149944
Lesenswert?

Stefan ⛄ F. schrieb:
> Es geht aber ganz Sicher um den STM32F1?

Hi, ja ganz sicher. STM32F107VCT7

Matthias S. schrieb:
> Ich traue HAL soweit, wie ich Manhattan werfen kann - sprich, bist du
> sicher, das HAL sich auch wirklich daran HÄLt, DMA für USART5 nicht zu
> aktivieren?

Nun was mich verwundert ist halt das es mit Debugger geht und der 
Ursprungscode (leider ist sehr viel die letzten Monate hinzugekommen 
ohne richtige Voll-Funktionstests) über ein halbes Jahr jeden Tag 
genutzt und perfekt funktioniert hat.
Gast #6149958
Lesenswert?

Matthias S. schrieb:
> das HAL sich auch wirklich daran HÄLt, DMA für USART5 nicht zu
> aktivieren?

Da es in CubeIDE (in der Config Einstellung im IOC file) DMA nicht 
aktivierbar ist glaube ich scheint das zu passen. Hier noch etwas Code:
1
static void MX_UART5_Init(void)
2
{
3

4
  /* USER CODE BEGIN UART5_Init 0 */
5

6
  /* USER CODE END UART5_Init 0 */
7

8
  /* USER CODE BEGIN UART5_Init 1 */
9

10
  /* USER CODE END UART5_Init 1 */
11
  huart5.Instance = UART5;
12
  huart5.Init.BaudRate = 115200;
13
  huart5.Init.WordLength = UART_WORDLENGTH_8B;
14
  huart5.Init.StopBits = UART_STOPBITS_1;
15
  huart5.Init.Parity = UART_PARITY_NONE;
16
  huart5.Init.Mode = UART_MODE_TX_RX;
17
  huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
18
  huart5.Init.OverSampling = UART_OVERSAMPLING_16;
19
  if (HAL_UART_Init(&huart5) != HAL_OK)
20
  {
21
    Error_Handler();
22
  }
23
  /* USER CODE BEGIN UART5_Init 2 */
24

25
  /* USER CODE END UART5_Init 2 */
26

27
}
Gast #6149988
Lesenswert?

Stefan ⛄ F. schrieb:
> Kannst den Inhalt der relevanten Register (vom UART und RCC) mit printf
> (oder so ähnlich) auf einem seriellen Port ausgeben oder auf einem
> Display anzeigen?

Ich befüchte da müsste ich nochmal den Mikrocontroller-C Kurs 
wiederholen. Durch HAL & Co. braucht man das i.d.R. ja nicht mehr.
Gast #6150007
Lesenswert?

peterpan schrieb:
> Leider habe ich nach mehreren
> Tagen immer noch nicht den Fehler gefunden. Nach wie vor funktioniert
> der Code via Debugger und ohne nicht / selten.
>
> Hat noch jemand Ideen oder brauch weitere Infos / Code?

Ähemm...

Also ich brauche hier nichts. Aber du brauchst vielleicht ein 
funktionierendes Konzept, wie man einen Low-Level-Treiber für die 
U(S)ART's der STM32F10x schreibt.

Wenn du wirre Zeichen siehst, dann fange erstmal mit einer gemütlichen 
Baudrate an. So mit 9600 zum Beispiel. Wenn damit dein Treiber sauber 
funktioniert, dann wage dich an höhere Baudraten heran.

Ich hatte hier vor lange Zeit schon mal eine komplette Mini-Firmware für 
den STM32F103C8T6 gepostet. Da ist natürlich auch der UART-Treiber mit 
dabei. Und der funktioniert. Such einfach mal.

Ansonsten solltest du bedenken, daß die UART-Interrupts bei den 
STM32F10x statisch sind. Also wenn dein Senderegister leer oder das 
Empfangsregister voll ist, dann ist der Interrupt aktiv. Empfangsdaten 
muß man eben lesen (egal ob man die nun anschließend verwirft oder 
nicht) und wenn du nix zu senden hast, mußt du bis zum nächsten Mal den 
Tx-Interrupt eben abschalten.

Ach, guck hier im Forum mal selber nach. UART-Betrieb ist ja nun keine 
besondere Herausforderung.

W.S.
Gast #6150013
Lesenswert?

W.S. schrieb:
> Ich hatte hier vor lange Zeit schon mal eine komplette Mini-Firmware für
> den STM32F103C8T6 gepostet.

Ich habe auf meiner Homepage (die inzwischen wohl kaum noch zu übersehen 
sein dürfte) auch gut kommentierte Beispiele sowohl für die 
Taktkonfiguration als auch für die UART Schnittstellen veröffentlicht.

Aber wer sogar an der HAL Festhält, während sie nicht funktioniert, 
der steht wohl auf Schmerzen.
Gast #6150028
Lesenswert?

Stefan ⛄ F. schrieb:
> Aber wer sogar an der HAL Festhält, während sie nicht funktioniert,
> der steht wohl auf Schmerzen.

Würde ich jetzt auch zustimmen, insbesondere weil eine UART-
Implementierung auf einem F1xx nun sicher keinen Aufwand
bedeuted und man alles durch "Selbstprogrammierung" in der
Hand hat.
Gast #6150031
Lesenswert?

Hier noch mein Custom Interrupt Code falls es hilft.
1
void HAL_UART_customIRQHandler(UART_HandleTypeDef *huart) {
2
  uint32_t isrflags = READ_REG(huart->Instance->SR);
3
  uint32_t cr1its = READ_REG(huart->Instance->CR1);
4

5
  if (((isrflags & USART_SR_IDLE) != RESET)
6
      && ((cr1its & USART_CR1_IDLEIE) != RESET)) {
7

8
    UART_IDLE_IT(huart);
9
    return;
10
  }
11

12
}
13

14
static HAL_StatusTypeDef UART_IDLE_IT(UART_HandleTypeDef *huart) {
15
  __HAL_UART_CLEAR_IDLEFLAG(huart);
16
  HAL_UART_IDLECallback(huart);
17
  return HAL_OK;
18
}
(Firma: matzetronics) #6150803
Lesenswert?

peterpan schrieb:
> Durch HAL & Co. braucht man das i.d.R. ja nicht mehr.

Schön wärs - bzw. ich weiss gar nicht ob das so schön wäre...
Mir kommts mittlerweile so vor, als bräuchte man mehr Erfahrung in C für 
den HAL als für die SPL. Da klappt sowas in Nullkommanix, sobald man ein 
paar Erfahrungen und Code hat.
Bin jedenfalls froh, das Atollic 9.3 immer noch prima mit SPL 
zurechtkommt.
(Firma: matzetronics) #6150827
Lesenswert?

Beo Bachta schrieb:
> Und es gibt ja noch Hoffnung dass Embitz nochmal auflebt,
> auch wenn es auch im jetzigen Status ja wunderbar nutzbar ist.

Ja, Atollic ist nun praktisch auf die STM32 Familie festgelegt, aber im 
Moment habe ich auch keine anderen Targets mit ARM, die ich 
programmieren möchte, seit ich es aufgegeben habe, an der Betty 
rumzumurksen.
Gast #6150853
Lesenswert?

Matthias S. schrieb:
> Mir kommts mittlerweile so vor, als bräuchte man mehr Erfahrung in C für
> den HAL als für die SPL. Da klappt sowas in Nullkommanix, sobald man ein
> paar Erfahrungen und Code hat.

Deswegen empfehle ich jedem, die ersten Schritte Anhand vom 
Referenzhandbuch und Application Notes auf Register-Ebene zu machen. 
Wenn man damit soweit vertraut ist, hat man das nötige 
Hintergrundwissen, die HAL richtig zu benutzen.
Gast #6150880
Lesenswert?

peterpan schrieb:
> Hier noch mein Custom Interrupt Code falls es hilft.

Nein, es hilft nicht.

Es haben jetzt einige Leute versucht, dir zu helfen - und keiner benutzt 
die/den/das HAL. (des HALes wahres Geschlecht ist mir schnurz)

Folglich ist das Posten von irgend einer Callback-Funktion aus diesen 
Gefilden nicht hilfreich.

Nun ist es an dir, dich zu entscheiden, was du tun willst:

Entweder:..
.. du hältst fest an deinem bisherigen Zeugs und beißt dich selbständig 
durch dein(e) HAL, bis du endlich weißt, wie das ganze Zeugs 
funktionieren soll und wie man es einzusetzen hat, oder..

.. oder: du räumst mit HAL auf und lernst anhand der hier ja schon lange 
existierenden Beispiele, wie man so einen seriellen Port selber benutzt, 
oder..

.. oder: du kommst mit deinem Zeugs eben nicht klar. Dann kann dir auch 
bloß keiner helfen.

W.S.
Gast #6150895
Lesenswert?

Letztendlich muss man sich ja nicht ganz von der HAL trennen. Wenn man 
sie z.B. zur Konfiguration der Taktversorgung oder vielleicht für USB 
nutzen will, kann man das ja auch mit handgeklöppelten Registerzugriffen 
kombinieren.

Ich würde nur darauf achten, das nicht pro Peripherieeinheit zu 
vermissen. Wenn UART ohne HAL, dann auch selber initialisieren.

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