Getting started with ADC

This article explains what is ADC and how to use it through an example.

1. What is an analog to digital converter (ADC)?

The analog-to-digital converters allows the microcontroller to accept an analog value like a sensor output and convert the signal into the digital domain. In this article, we focus on the STM32L4 ADC.

1.1. Simplified block diagram

The figure below shows the general block diagram for each analog-to-digital converter embedded in the STM32L4. ADC block diagram .png

1.2. ADC features in STM32L4x6 products

ADC units Up to 3 modules
Input channel Up to 24 external channels (GPIOs), single/differential
Technology 12-bit successive approximation
Conversion time 188 nS, 5.33 Msamples/s (when fADC_CLK = 80 MHz)
Functional mode Single, Continuous, Scan, Discontinuous, or Injected
Triggers Software or external trigger (for Timers & IOs)
Special functions Hardware oversampling, analog watchdogs
Data processing Interrupt generation, DMA requests
Low-power modes Deep power-down, auto delay, power consumption dependent on speed
  • High performance features
    • Supports up to 5.33 mega samples per second of conversion which could be extended to 10Msamples/s (devices with dual ADC).
    • Includes the oversampling hardware which accumulates data and then divides it without CPU.
    • Flexible sequencer
    • Auto-calibration to reduce offset
  • Low Power features
    • Deep power-down mode
    • Auto-delayed conversion
    • Power consumption depends on sampling time
  • Conversion Speeds
    • ADC needs minimum 2.5ADC_CLKs for sample period and 12.5ADC_CLKs for conversion (12-bit).
    • 80 MHz maximum clock with a 15 cycle results in 5.33 Msamples/s
    • Speed up by low resolution
  • Programmable sampling time
  • Flexible clock selection

1.3. ADC Conversion Modes

AD converter supports several conversion modes:

  • Single mode, which converts only one channel, in single-shot or continuous mode.
  • Scan mode, which converts a complete set of pre-defined programmed input channels, in single-shot or continuous mode.
  • Discontinuous mode, converts only a single channel at each trigger signal from the list of pre-defined programmed input channels.

ADC conversion modes.png
There are several functional modes which are explained in details in the product Reference Manual.

2. Configure ADC to measure the DAC output

2.1. Objectives

  • Learn how to set up the ADC with DMA in STM32CubeMX.
  • Generate code in STM32CubeMX and using HAL functions.
  • Create a simple application to start the ADC and measure the DAC output.

2.2. Create the project in STM32CubeIDE

  • File > New > STM32 Project in main panel.

create STM32CubeIDE project.png.

This example uses the NUCLEO-L476RG board.

  • Select NUCLEO-L476RG board using Board selector as shown in the figure below:

Select NUCLEO-L476RG board.png

If you did not download the STM32L476 Cube library, it will automatically be downloaded. This can take some time.

  • Save the project:

Save Project ADC.png

2.1. Configure peripherals

2.1.1. Configure DAC

We will use PA5 as the DAC's output. As it is configured as GPIO Output by default, we need to reset it first.

  • Search for PA5 in the bottom right search field, then click Reset_State.


  • Search for DAC1 in the left search field.
  • OUT2 connected to only to external pin. Notice how PA5 is automatically set to DAC1_OUT2 on the pinout view.
  • Parameter Settings should be set up as in the below example: normal mode, buffer enabled and no trigger.

DAC Output Config.PNG

2.1.2. Configure ADC

Configure ADC with the following settings:

  • Asynchronous clock mode div by 256
  • Resolution 12bits
  • Right alignment
  • Continuous conversion mode Enabled
  • Software trigger
  • sampling time for CH6 (92.5cycles)
  • DMA Continuous requests Enabled

ADC mode1.png ADC mode2.png

Info white.png Information
Make sure to tonnect PA1 with PA5. You can use a jumper for that.

2.1.3. Configure DMA

The ADC conversion values will be transferred into memory by DMA controller. DMA config.png

2.2. Generate the project and edit main.c

  • Click Ctrl+S to generate the project:

Generate project.png

  • Edit main.c:
Info white.png Information
Insert your code between /* USER CODE BEGIN PV */ and /* USER CODE END PV */ tags
uint32_t value_adc;
uint32_t value_dac=0;
Info white.png Information
Start the DAC, the ADC calibration and the ADC conversion by inserting the required code between /* USER CODE BEGIN 2*/ and /* USER CODE END 2 */ tags
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
Info white.png Information
Set the DAC output value by inserting the required code between /* USER CODE BEGIN 3 */ and /* USER CODE END 3 */ tags
while (1)
  HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_2, DAC_ALIGN_12B_R, value_dac);
  if(value_dac>4095) {
  • Explanation

First, DAC is configured as input voltage source for ADC. It uses output channel 2 (OUT2) and is connected to an external pin (PA5).
The ADC is configured to use asynchronous clock mode with a clock prescaler of 256 ensuring that ADC is not running too fast.
ADC is configured to have a resolution of 12 bits, right alignment, continuous conversion mode enabled (in order to convert data continuously), and software trigger with a sampling time of 92.5 cycles for channel 6 (PA1).
The ADC values are transferred to memory using DMA controller, which is configured as follows :

  • Circular mode, allowing an updated indefinitely transfer.
  • Continuous DMA request enabled allowing an uninterrupted transfer of data to the memory.

ADC and DAC should have similar values, while using PA1 – PA5 jumper.
Therefore, the code will sweep through all the possible ADC output values, and then reset it to zero restarting the process all over again.

2.3. Compile and flash

  • Click the Build button Built.png
  • Click the Debug button to run it step by step Debug.png

3. Build and measure a simple signal generator

  • Put jumper on PA1 - PA5 pins to connect DAC output to ADC input. The result is as follows

ADC value.png

  • Explore further application notes such as:
  • How to get the best ADC accuracy in STM32 microcontrollers [1]

4. References