1

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

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
guenthernagel
  • 73
  • 1
  • 3
  • 14

2 Answers2

4

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.

brhans
  • 402
  • 3
  • 10
  • Do i get right, that i need the ADC for measure analog values? there is no way without ADC? – guenthernagel Jun 20 '19 at 20:15
  • EDIT: Seen the Analog Documentation for Arduino: "The ATmega controllers used for the Arduino contain an onboard 6 channel (8 channels on the Mini and Nano, 16 on the Mega) analog-to-digital (A/D) converter. " Got my answer. Now I will try with ADC on STM :-) – guenthernagel Jun 20 '19 at 20:20
  • Please check my Edit into the question. Started the ADC now, but still return 0. The function HAL_ADC_ConfigChannel is used in MX_ADC1_Init() which is all generated by Cube IDE – guenthernagel Jun 20 '19 at 20:31
  • Do you also have the CubeMX-generated initialization for the GPIO ports and RCC clock module in your code? Are you certain that you're doing the conversion on the correct channel? Which pin is your voltage-divider connected to? – brhans Jun 20 '19 at 20:44
  • The Pin is now configured as "ADC1_IN14", connected is the divender on Pin PC4. RCC is configured too. I get values back but seems more like random numbers. – guenthernagel Jun 20 '19 at 20:47
  • Did you change your `sConfig.Channel = ADC_CHANNEL_15;` line to `ADC_CHANNEL_14`? – brhans Jun 20 '19 at 21:18
  • Yes I did (Cube Made IT) – guenthernagel Jun 20 '19 at 21:45
  • 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 – guenthernagel Jun 21 '19 at 14:29
1

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.

peets
  • 393
  • 1
  • 4
  • 13