I'm new to microcontroller programming and I have a problem I can't solve.
I am using STM32 Nucleo board L4R5ZI and I try to read the analog value on one of the pins, and then use the ADC to convert it and send it to the PC using the UART.
But when using this code, I only get a "0" in my PC. It looks like the HAL_ADC_start()
function returns HAL_ERROR
. Do you know what it could be?
I hope that you understand, English is not my native language :)
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;
EDIT 1
I find out that HAL_ADC_start
function return HAL_ERROR
in this section of code:
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;
It is part of function ADC_Enable()
which is used in HAL_ADC_start()
. Condition in while()
is still TRUE
that means, a timeout occurs later.
Still don't know how to solve it.
HAL_ADC_Start
function to check the condition that causes it to returnHAL_ERROR
. \$\endgroup\$