Getting Started with STM32G0 and STM32CubeIDE: ADC Polling Mode

In this guide, we shall learn how to use the ADC of the STM32 for single channel Single Conversion mode using HAL API with STM32CubeMX.

In this guide, we shall cover the following:

  • What is the ADC.
  • Driver development.
  • Results.

1.1 What is the ADC

In electronics, an analog-to-digital converter (ADCA/D, or A-to-D) is a system that converts an analog signal, such as a sound picked up by a microphone or light entering a digital camera, into a digital signal that can be read by STM32. 

ADCs can vary greatly between microcontroller. The ADC on the STM32F103 is a 12-bit ADC meaning it has the ability to detect 4096(2^12) discrete analog levels (which is also called Resolution). Some microcontrollers have 8-bit ADCs (2^8 = 256 discrete levels) and some have 16-bit ADCs (2^16 = 65,536 discrete levels).

The way an ADC works is fairly complex. There are a few different ways to achieve this feat (see Wikipedia for a list), but one of the most common technique uses the analog voltage to charge up an internal capacitor and then measure the time it takes to discharge across an internal resistor. The microcontroller monitors the number of clock cycles that pass before the capacitor is discharged. This number of cycles is the number that is returned once the ADC is complete. Other methods used called Successive-approximation ADC which you can read about it in details from this wikipedia page (Link).

1.2 Relating ADC Value to Voltage

The ADC reports a ratio metric value. This means that the ADC assumes 3.3V is 4095 and anything less than 3.3V will be a ratio between 3.3V and 4095.

For example if the sensor has output voltage of 1.66V hence the ADC output will be (4095/3.3)*1.66=2059.

2. Driver Development:

We start off by creating new STM32 project and name it ADC_Polling. For more details how to create new project, please refer to this guide.

In Pinout and configuration, Open Analog and select IN0 as following:

As you can see, CubeMX automatically enabled PA0 as analog pin.

Leave the ADC settings to default.

Also, we need to print the ADC values using serial communications, for how to enable the serial, please refer to this guide here.

Save the project and it will generate the code required.

In main.c:

In User code begin includes, include stdio.h as following:

/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

In USER CODE BEGIN PV, we shall declare the following variables:

/*ADC values*/
uint16_t adc_value;

/*Length of the string*/
uint32_t len;

/*Array for UART transmit*/
uint8_t uart_data[40];

Since the ADC of STM32G0 is 12-bit, we shall use uint16_t to hold the ADC value.

In user code begin 3:

Start the ADC as following:

HAL_ADC_Start(&hadc1);

This function shall start the ADC according to our configuration.

Wait until the ADC finish conversion by polling for conversion as following:

if(HAL_ADC_PollForConversion(&hadc1, 100)==HAL_OK)

This function shall wait until the ADC finishes the conversion and wait according to the timeout, if timed out, it will return error. If there is no error, we shall get the ADC value as following:

adc_value=HAL_ADC_GetValue(&hadc1);

Send the ADC value to serial:

len=sprintf((char*)uart_data,"ADC Value =%d\r\n",adc_value);
HAL_UART_Transmit(&huart2, uart_data, len, 100);

Outside the if, delay by a half second as following:

 HAL_Delay(500);

Hence, the while 1 code as following:

    /* USER CODE BEGIN 3 */



	  HAL_ADC_Start(&hadc1);

	  if(HAL_ADC_PollForConversion(&hadc1, 100)==HAL_OK)
	  {
		  adc_value=HAL_ADC_GetValue(&hadc1);
		  len=sprintf((char*)uart_data,"ADC Value =%d\r\n",adc_value);
		  HAL_UART_Transmit(&huart2, uart_data, len, 100);
	  }
	  HAL_Delay(500);
  }
  /* USER CODE END 3 */

3. Results:

Upload the code to your board, select your TTL-USB converter and set the baud rate to 115200 and you should get the following.

It will print the ADC value each half second.

Happy coding 🙂

Add Comment

Your email address will not be published. Required fields are marked *