cancel
Showing results for 
Search instead for 
Did you mean: 

How To read Multi Channel ADC on Blue Pill with continuous mode & Polling

njtucza2
Associate

I am using the STM32F103C8 (blue Pill) and have been having lots of troubles with reading multiple channels on ADC1. Here is my init code using firmware 1.7:

  ADC_ChannelConfTypeDef sConfig = {0};
 
  /* USER CODE BEGIN ADC1_Init 1 */
 
  /* USER CODE END ADC1_Init 1 */
  /**Common config 
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 4;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /**Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /**Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /**Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_2;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /**Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_3;
  sConfig.Rank = ADC_REGULAR_RANK_4;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

I am trying to read from analog pins PA0-3, and I am getting very odd results. Whenever I try change the value of just one ADC Pin, all of the values seem to change, and then on some pins when I change the value I see no response from the STM at all. Anyone have similar problems or see something up with my init? Here is how i call for values:

    HAL_ADC_Start(&hadc1);
 
    if(HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK);
    adc0 = HAL_ADC_GetValue(&hadc1);
 
 
    if(HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK)
      adc1 = HAL_ADC_GetValue(&hadc1);
 
    if(HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK);
   adc2 = HAL_ADC_GetValue(&hadc1);
 
    if(HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK);
    adc3 = HAL_ADC_GetValue(&hadc1);
 
 
    HAL_ADC_Stop(&hadc1);

5 REPLIES 5
Rogers.Gary
Senior II

I know it will be little consolation, I tried multi-channel polling and gave up. I switched to DMA and getting pretty consistent results.

MikeDB
Lead

Well I program at a lower level but simply trigger the ADC on each channel in turn in my code and it works fine with little crosstalk

void start_ADC(uint8_t ADC_type)                        // start A-D convertors

   {

      ADC0_MUXPOS = ADC_type;

      ADC0_COMMAND = 0b00000001;                        

   }

         if (ADC0_INTFLAGS & 1)                        // should be ready - conversion takes 8.7uS

            Vadc1 = ADC0_RES;

Rogers.Gary
Senior II

Soon as my two projects are done, going to get learning LL and register on the STM32L4 processors. Horrible HAL is too goofy :dizzy_face:

I tried it when it first came out and had to stop as too many problems. I keep telling myself I'll give it another try sometime but still haven't umpteen years later 🙂

TDK
Guru

You need to use DMA to read from multiple channels. Otherwise the ADC will only read from the channel on rank 1.

If you feel a post has answered your question, please click "Accept as Solution".