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_start
Funktion HAL_ERROR
in 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.
Einige Dinge, die Sie versuchen könnten:
Ü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.PeriphClockSelection
und vergewissern Sie sich, dass sie enthält RCC_PERIPHCLK_ADC
.
Ü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.
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.
Michel Keijzers
HAL_ADC_Start
, um die Bedingung zu überprüfen, die sie zur Rückgabe veranlasstHAL_ERROR
.Chris Stratton
Dhafer LAKDHAR