guenthernagel
guenthernagel

Reputation: 93

Voltage Measurement on STM32

Im new in ANSI C @STM32 but I tried to measure a Voltage (~12V) with a voltage divider and a Analog GPIO.

I tried:

value = HAL_GPIO_ReadPin(VOLTAGE_GPIO_Port, VOLTAGE_Pin);

But it always return 0

Then I tried to use the ADC (I dont know that thats required)

value = HAL_ADC_GetValue(&hadc1);

But still 0.

On Arduino you can simple use:

value = analogRead(1);

And it work.

Here is the Init of the ADC Channel:

    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.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_15;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

Do I really need a ADC Channel, is there no "simple" Analog Input like Arduino?

I know that I need to div the incoming value to get the right voltage but at the moment I do not get any data back.

MCU is STM32F107VCT7

EDIT:

Tried the following now:

HAL_ADC_Start(&hadc1);
  if (HAL_ADC_PollForConversion(&hadc1, 1000000) == HAL_OK)
          {
  g_ADCValue = HAL_ADC_GetValue(&hadc1);

          }
  HAL_Delay(500);

Now g_ADCValue return values but seems like random numbers... The Input voltage is not changed and get various data back.

Found that Code: https://hackaday.io/project/4277-stm32f030f4p6-breakout-board/log/13897-printing-adc-values-over-uart

Tried 1:1, but it allways pint 0x3E, changing Voltage to not make any effect

Upvotes: 1

Views: 6929

Answers (2)

peets
peets

Reputation: 441

brhans is right, but the instructions are a bit confusing for someone coming e.g. from Arduino or other libraries or simpler microcontrollers.

Because there are so many, even complex possibilities, more functions are needed for a simple conversion.

For example you could periodically scan 10 analog inputs, store the results to a memory array and generate an interrupt when the whole scan is ready to wake up your evaluation routines - only from a few settings without lots of code.

On an STM32L476 I successfully used the following sequence (should work on most other STM32s):

int voltsRaw;   // raw value as measured by ADC
...
HAL_ADC_Start(&hadc1);
while(HAL_ADC_GetState(&hadc1) & HAL_ADC_STATE_BUSY);
voltsRaw = HAL_ADC_GetValue(&hadc2);

If you don't need more complex operations, simply write your own 'analogRead()' function containing the commands above. I also used arrays and an index to get rid of the nasty (Port/Bit) pair for Pin-Reference in the function call.

Upvotes: 2

brhans
brhans

Reputation: 402

You need to read the documentation for the STM32 HAL functions if you're going to try to use them.
You're missing some function calls like HAL_ADC_Start.
HAL_ADC_GetValuewill only return a new ADC reading after you've told the ADC module to start a conversion and then waited for it to complete.

All of these kinds of operations also happen in an Arduino environment - they're just hidden from you to make things simple.

Upvotes: 4

Related Questions