Soy nuevo en la programación de microcontroladores y tengo un problema que no puedo resolver.
Estoy usando la placa STM32 Nucleo L4R5ZI y trato de leer el valor analógico en uno de los pines, y luego uso el ADC para convertirlo y enviarlo a la PC usando el UART.
Pero cuando uso este código, solo obtengo un "0" en mi PC. Parece que la HAL_ADC_start()
función regresa HAL_ERROR
. ¿Sabes lo que podría ser?
Espero que lo entiendas, el inglés no es mi idioma nativo :)
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;
EDITAR 1
Descubro que HAL_ADC_start
la función regresa HAL_ERROR
en esta sección del código:
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 parte de la función ADC_Enable()
que se usa en HAL_ADC_start()
. La condición en while()
todavía TRUE
significa que se produce un tiempo de espera más tarde.
Aun no se como solucionarlo.
Algunas cosas que podrías probar:
Verifique que el reloj para el ADC esté habilitado; por lo tanto, en la SystemClock_Config()
función busque la línea que establece PeriphClkInit.PeriphClockSelection
y asegúrese de que contenga RCC_PERIPHCLK_ADC
.
Verifique que la frecuencia del reloj para el ADC sea aceptable: use STM32CubeMX y mire la pestaña "Configuración del reloj" y asegúrese de que no arroje ningún error.
Su código está ejecutando el ADC como un solo uso, pero lo está configurando para un muestreo continuo hadc1.Init.ContinuousConvMode = ENABLE;
. Puede valer la pena configurar esto DISABLE
en su lugar.
Respuesta anterior dejada aquí para la posteridad:
Estoy viendo el mismo problema (HAL_ADC_Start() devolviendo HAL_ERROR), aunque con una compilación PlaformIO + STM32CubeMX. En este caso, PlatformIO compila el código CMSIS y el código del controlador CubeMX HAL por separado en dos bibliotecas: libFrameworkCMSISDevice.a y libFrameworkHALDriver.a.
En la biblioteca libFrameworkHALDriver existe una serie de funciones que se definen dos veces, una con enlace débil y la segunda con enlace fuerte.
Para mí, el enlace final produce una salida que solo tiene la versión débil de muchas de estas funciones. Para la función HAL_ADC_Start() en cuestión, solo tiene la versión débil, que no hace nada y devuelve HAL_ERROR, que es el síntoma informado en la pregunta.
Mirando esto un poco más, parece que al vincular bibliotecas estáticas, el vinculador no anula los símbolos débiles que se ven al principio del enlace con los fuertes que se ven más tarde. Por ejemplo, vea esta discusión: https://stackoverflow.com/a/37191811/1770902 .
Por lo tanto, si esto es lo que está causando su problema, la solución parecería ser colocar los archivos con los símbolos fuertes antes en el enlace que los símbolos débiles que deberían anular.
En mi caso, aún no he descubierto cómo solucionar este problema, ya que no parece haber ninguna forma de influir en el orden en que las compilaciones de la biblioteca PlatformIO han incluido los archivos de objetos.
michel keijzers
HAL_ADC_Start
función para verificar la condición que hace que regreseHAL_ERROR
.chris stratton
Dhafer LAKDHAR