STM32 HAL_ADC_Start() endet mit HAL_ERROR

Ich bin neu in der Mikrocontroller-Programmierung und habe ein Problem, das ich nicht lösen kann.

Ich verwende das STM32 Nucleo-Board L4R5ZI und versuche, den Analogwert an einem der Pins zu lesen, und verwende dann den ADC, um ihn umzuwandeln und ihn mit dem UART an den PC zu senden.

Aber wenn ich diesen Code verwende, bekomme ich in meinem PC nur eine "0". Es sieht so aus, als ob die HAL_ADC_start()Funktion zurückgibt HAL_ERROR. Weißt du, was es sein könnte?

Ich hoffe du verstehst, Englisch ist nicht meine Muttersprache :)

ADC_HandleTypeDef hadc1;
UART_HandleTypeDef hlpuart1;

...

uint16_t raw;
char msg[10];

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();
MX_LPUART1_UART_Init();
MX_USART3_UART_Init();
MX_USB_OTG_FS_PCD_Init();
MX_ADC1_Init();


    while (1){
    
      HAL_ADC_Start(&hadc1);
      HAL_ADC_PollForConversion(&hadc1, 100);
      raw = HAL_ADC_GetValue(&hadc1);
      sprintf(msg, "%hu\r\n", raw);

      HAL_UART_Transmit(&hlpuart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
      HAL_Delay(5);
    }

...

  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.NbrOfDiscConversion = 1;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.OversamplingMode = DISABLE;

BEARBEITEN 1
Ich finde heraus, dass die HAL_ADC_startFunktion HAL_ERRORin diesem Codeabschnitt zurückkehrt:

while (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)
    {
      /*  If ADEN bit is set less than 4 ADC clock cycles after the ADCAL bit
          has been cleared (after a calibration), ADEN bit is reset by the
          calibration logic.
          The workaround is to continue setting ADEN until ADRDY is becomes 1.
          Additionally, ADC_ENABLE_TIMEOUT is defined to encompass this
          4 ADC clock cycle duration */
      /* Note: Test of ADC enabled required due to hardware constraint to     */
      /*       not enable ADC if already enabled.                             */
      if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
      {
        LL_ADC_Enable(hadc->Instance);
      }

      if ((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT)
      {
        /* Update ADC state machine to error */
        SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);

        /* Set ADC error code to ADC peripheral internal error */
        SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);

        return HAL_ERROR;
      }
    }
return HAL_OK;

Es ist Teil der Funktion ADC_Enable(), die in verwendet wird HAL_ADC_start(). Zustand in while()ist immer noch TRUE, dh es kommt später zu einem Timeout.

Weiß immer noch nicht, wie ich es lösen soll.

Sie können die Funktion debuggen HAL_ADC_Start, um die Bedingung zu überprüfen, die sie zur Rückgabe veranlasst HAL_ERROR.
Dies ist normalerweise das Ergebnis einer fehlenden Initialisierung oder eines ungültigen Optionsauswahlversuchs. Sehen Sie, ob es ein Herstellerbeispiel gibt, das Sie zuerst absolut unverändert ausführen können.
Haben wir am Ende eine Lösung? Ich habe ein ähnliches Problem an meinem Ende mit STM32U5.

Antworten (1)

Einige Dinge, die Sie versuchen könnten:

  1. Überprüfen Sie, ob die Uhr für den ADC aktiviert ist – suchen Sie also in der SystemClock_Config()Funktion nach der Zeile, die einstellt, PeriphClkInit.PeriphClockSelectionund vergewissern Sie sich, dass sie enthält RCC_PERIPHCLK_ADC.

  2. Überprüfen Sie, ob die Taktfrequenz für den ADC akzeptabel ist – verwenden Sie STM32CubeMX und sehen Sie sich die Registerkarte „Clock Configuration“ an und stellen Sie sicher, dass keine Fehler ausgegeben werden.

  3. Ihr Code führt den ADC als One-Shot aus, konfiguriert ihn jedoch für kontinuierliches Sampling -- hadc1.Init.ContinuousConvMode = ENABLE;. Es kann sich lohnen, dies stattdessen einzustellen DISABLE.


Alte Antwort hier für die Nachwelt hinterlassen:

Ich sehe das gleiche Problem (HAL_ADC_Start() gibt HAL_ERROR zurück), allerdings mit einem PlaformIO + STM32CubeMX-Build. In diesem Fall baut PlatformIO den CMSIS-Code und den CubeMX-HAL-Treibercode separat in zwei Bibliotheken auf: libFrameworkCMSISDevice.a und libFrameworkHALDriver.a.

In der libFrameworkHALDriver-Bibliothek gibt es eine Reihe von Funktionen, die zweimal definiert sind, einmal mit schwacher Verknüpfung und ein zweites Mal mit starker Verknüpfung.

Für mich erzeugt der letzte Link eine Ausgabe, die nur die schwache Version vieler dieser Funktionen enthält. Für die fragliche Funktion HAL_ADC_Start() gibt es nur die schwache Version, die nichts tut und HAL_ERROR zurückgibt, was das in der Frage gemeldete Symptom ist.

Wenn Sie sich dies genauer ansehen, scheint es, dass der Linker beim Verknüpfen statischer Bibliotheken schwache Symbole, die zu Beginn des Links angezeigt werden, nicht mit starken Symbolen überschreibt, die später angezeigt werden. Siehe zB diese Diskussion: https://stackoverflow.com/a/37191811/1770902 .

Wenn dies die Ursache Ihres Problems ist, scheint die Lösung darin zu bestehen, die Dateien mit den starken Symbolen früher in den Link einzufügen als die schwachen Symbole, die sie überschreiben sollten.

In meinem Fall habe ich noch nicht herausgefunden, wie dieses Problem behoben werden kann, da es anscheinend keine Möglichkeit gibt, die Reihenfolge zu beeinflussen, in der die Builds der PlatformIO-Bibliothek die Objektdateien enthalten haben.

Die hal "Bibliothek" wird typischerweise als Teil eines Projekts kompiliert, nicht in eine statische Bibliothek vorkompiliert und gelinkt, daher wird der Bibliotheksmechanismus dafür normalerweise überhaupt nicht verwendet. Die hier gezeigten .o-Dateien sind keine "Bibliotheken"
Vielleicht gibt meine Antwort gemischte Nachrichten, aber in meinem Fall der Verwendung von PlatformIO mit STM32CubeMX zum Erstellen für das STM32F323C-EVAL-Board werden zwei statische Bibliotheken erstellt, mit denen es automatisch verknüpft wird. Dies sind libFrameworkCMSISDevice.a und libFrameworkHALDriver.a. In der libFrameworkHALDriver.a taucht die Funktion HAL_ADC_Start() zweimal auf, die erste ist eine schwache Version, die zweite eine starke. In der final verlinkten Ausgabe gibt es nur die schwache Version.
Ich habe meine Antwort aktualisiert, um weitere Informationen über die Situation zu geben, in der ich ein Problem mit denselben Symptomen habe.
Das scheint sich von dieser Frage zu unterscheiden
Ja, ich akzeptiere, dass es sein kann. Aber es kann auch nicht sein, da das OP nicht angibt, wie sein Setup ist. Wenn er PlatformIO mit STM32CubeMX verwendet, um sein HAL-Setup zu erhalten, wäre meine Antwort für seinen Fall relevant. Andernfalls kann dies jemand anderem helfen, der PlatformIO mit STM32CubeMX verwendet, der wie ich zu dieser Frage kommt, indem er nach dem Grund sucht, warum HAL_ADC_Start() mit HAL_ERROR fehlschlägt.
"Antworten" müssen hier speziell auf die tatsächlich gestellte Frage eingehen, weit hergeholte Vermutungen, die Fehler in ihrer eigenen Erklärung enthalten und keine unterstützenden Beweise in der Frage selbst haben, sind wirklich nicht von Vorteil für die Website und führen tendenziell nur zu uninformiertem "Probieren Sie es aus". ismus. Das, worüber Sie sprechen, hat hier bereits eine eigene Frage.
OK, würden Sie also sagen, dass die tatsächlich gestellte Frage lautet: "Warum gibt HAL_ADC_Start() HAL_ERROR zurück"?