STM32 ADC Continuous Conv Mode does not automatically start conversion

11,075

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.

Share:
11,075
Nixmd
Author by

Nixmd

Updated on June 04, 2022

Comments

  • Nixmd
    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?