STM32 ADC Continuous Conv Mode does not automatically start conversion
I am sure that the EOC flag setting is the problem. hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
should be changed to hadc1.Init.EOCSelection = EOC_SEQ_CONV;
.
Your current option ADC_EOC_SINGLE_CONV
acts like an enable of single conversion, but you need EOC_SEQ_CONV
aka sequential conversions.
It is pretty much the same problem that has been discussed here.
Nixmd
Updated on June 04, 2022Comments
-
Nixmd almost 2 years
I am trying to configure ADC over a STM32F411RE in simple Continuous Conv Mode. I used CubeMX to generate the code based on HAL drivers and this is some parts of the generated code which intialize ADC:
/* ADC1 init function */ void MX_ADC1_Init(void) { /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */ hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8; hadc1.Init.Resolution = ADC_RESOLUTION_8B; hadc1.Init.ScanConvMode = DISABLE; hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } }
and here is the main function:
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_ADC1_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ uint8_t analogVal; uint8_t string[] = "Poll failed\n"; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ HAL_Delay(1000); if( HAL_ADC_Start(&hadc1) == HAL_OK) HAL_UART_Transmit(&huart2,(uint8_t*)"STRT OK\n",8,100); else HAL_UART_Transmit(&huart2,(uint8_t *)HAL_ADC_Start(&hadc1),1,100); while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(HAL_ADC_PollForConversion(&hadc1,1) == HAL_OK){ analogVal = HAL_ADC_GetValue(&hadc1); HAL_UART_Transmit(&huart2,&analogVal,sizeof(analogVal),100); } else{ HAL_UART_Transmit(&huart2,string,sizeof(string)-1,100); } HAL_Delay(100); } /* USER CODE END 3 */ }
If I compile and upload this code into the microcontroller, no more than once analogVal would be transmitted over UART. But if I place HAL_ADC_Start function inside the while loop, HAL_ADC_PollForConversion returned value will be HAL_OK in every cycle of while and there will be a analogVal to report.
My question is, why should I everytime ask the ADC to start if I have enabled ContinuousConvMode?