cancel
Showing results for 
Search instead for 
Did you mean: 

ADC: Cannot change channel.

TomC
Senior

Board: STM32WB55-NUCLEO Pack

I am unable to change the channel being read by the ADC using the included code.

I have set the number of conversion to 3 in the ADC configurations. I am not using the DMA but am polling.

uint32_t get_battery_voltage(){
 
	sConfig.Channel = ADC_CHANNEL_3 ;
	sConfig.Rank = 1;
	if (HAL_ADC_ConfigChannel(&hadc1,&sConfig) != HAL_OK)
	  {
	    Error_Handler();
	  }
 
	HAL_ADC_Start(&hadc1);
 
	if(HAL_ADC_PollForConversion(&hadc1,5)==HAL_OK){
	 state.battery_voltage = (double)(HAL_ADC_GetValue(&hadc1));	
	 state.battery_voltage = (state.battery_voltage/4095)*3.3;
	}
	HAL_Delay(50);
 
	HAL_ADC_Stop(&hadc1);
 
	return state.battery_voltage;
}

1 ACCEPTED SOLUTION

Accepted Solutions
TomC
Senior

The reason I was unable to change channel correctly and thus read another ADC pin was because I did not specify the "Number of Conversions" as the number of channels I wished to use in the ADC's configuration.

View solution in original post

6 REPLIES 6
TDK
Guru

If you're converting multiple channels, they're probably overwriting each other and you're only reading the last one (i.e. rank 3) which is converted.

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

>unable to change the channel being read by the ADC

What do you mean?

To read another channel, you have to set​ sConfig.Channel to another channel.

>I have set the number of conversion to 3 in the ADC configurations

Do you mean you want to perform 3 sucessive conversions?

Could you also show that configuration (hadc structure) in MX_ADC_Init function?

Hi Remi,

I mean that despite changing sConfig's channel, the data being generated by HAL_ADC_GetValue(&hadc1) is consistent with initial configuration set by MX_ADC1_Init(void). That is to say, I believe the channel specified by the sConfig object is not changing correctly. Please see the ADC initialization code:

/**
  * @brief ADC1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_ADC1_Init(void)
{
 
  /* USER CODE BEGIN ADC1_Init 0 */
 
  /* USER CODE END ADC1_Init 0 */
 
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /* USER CODE BEGIN ADC1_Init 1 */
 
  /* USER CODE END ADC1_Init 1 */
  /** Common config
  */
  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_ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 3;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  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;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_14;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_2;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_3;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
 
  /* USER CODE END ADC1_Init 2 */
 
}

Hi TDK.

Are you saying that I'm not specifying which channel to read correctly so the program is only reading whatever's in rank 3? Why do you think that the program would only read rank 3 as opposed to 1 or 2?

I believe I've followed the polling method described in this document (pg 74) correctly.

I have made ADC_ChannelConfTypeDef sConfig (line 13) global so that it can be modified outside of the MX_ADC1_Init(void) and in different implementation files. My concern is that it is not being referred to correctly outside of the init function and hence not being modified, however when observing its values using the debugger the channel does appear to be changing when modified external to the init function.

TomC
Senior

The reason I was unable to change channel correctly and thus read another ADC pin was because I did not specify the "Number of Conversions" as the number of channels I wished to use in the ADC's configuration.