STM32-Peripheral’s-ADC: Scan Mode

STM32-Peripheral’s-ADC: Scan Mode

An analog to digital converter is a circuit that converts a continuous voltage value (analog) to a binary value (digital) that can be understood by a digital device which could then be used for digital computation. These ADC circuits can be found as an individual ADC ICs by themselves or embedded into a microcontroller. They’re called ADCs for short.

ADC Peripheral features: (STM32F429XX)


1. 12-bit, 10-bit, 8-bit or 6-bit configurable resolution.
2. Interrupt generation at the end of conversion, end of injected conversion, and in case of analog watchdog or
overrun events
3. Single and continuous conversion modes.
4. Scan mode for automatic conversion of channel 0 to channel x.
5. Data alignment with in-built data coherency.
6. Channel-wise programmable sampling time.
7. External trigger option with configurable polarity for both regular and injected conversion.
8. Dual/Triple mode (on devices with 2 ADCs or more).
9. Configurable DMA data storage in Dual/Triple ADC mode.
10. Configurable delay between conversions in Dual/Triple interleaved mode.
11. ADC conversion type (refer to the datasheets).
12. ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at slower speed.
13. ADC input range: VREF(minus) = VIN = VREF(plus).
14. DMA request generation during regular channel conversion.

How to use this driver

Initialize the ADC low level resources by implementing the HAL_ADC_MspInit():
a. Enable the ADC interface clock using __HAL_RCC_ADC_CLK_ENABLE()
b. ADC pins configuration
◦ Enable the clock for the ADC GPIOs using the following function:
__HAL_RCC_GPIOx_CLK_ENABLE()
◦ Configure these ADC pins in analog mode using HAL_GPIO_Init()
c. In case of using interrupts (e.g. HAL_ADC_Start_IT())
◦ Configure the ADC interrupt priority using HAL_NVIC_SetPriority()
◦ Enable the ADC IRQ handler using HAL_NVIC_EnableIRQ()
◦ In ADC IRQ handler, call HAL_ADC_IRQHandler()
d. In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA())
◦ Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE()
◦ Configure and enable two DMA streams stream for managing data transfer from peripheral to
memory (output stream)
◦ Associate the initialized DMA handle to the CRYP DMA handle using __HAL_LINKDMA()
◦ Configure the priority and enable the NVIC for the transfer complete interrupt on the two DMA
Streams. The output stream should have higher priority than the input stream.

Execution of ADC conversions


1. ADC driver can be used among three modes: polling, interruption, transfer by DMA.
Polling mode IO operation
• Start the ADC peripheral using HAL_ADC_Start()
• To read the ADC converted values, use the HAL_ADC_GetValue() function.

For this blog we are going to use ADC in scan mode (Dual Channel) , for demonstration purpose we will configure two DAC’s (for more details click here) , output of DAC’s will be Input of two ADC channels.

PA9 & PA10 Pin used for debugging purpose as UART Tx & UART Rx respectively.

Creating a new STM32 executable project

  1. The easiest way to create a new STM32 C/C++ project is to use the STM32 project wizard. It is selected through the menu [File]>[New STM32 Project].
  2. The MCU/MPU selector and Board Selector tabs can be selected at the top of the window. Use the first tab to create project for a specific device and the second if a project for a specific board is needed. today we will select specific device.
Figure 1

3. Select SMT32F429ZI in MCU Selector tab

4. According to the settings in Figure 3, the project is meant to be stored in the default location with the following

options set:

• C project

• Executable binary type

STM32CubeIDE targeted project type

Press [Next] to open the Firmware Library Package Setup page.

Figure 3 Project Name

5. In this page, it is possible to select the STM32Cube firmware package to use when creating the project. In this case, the default settings are used. Press [Finish] to create the project. (Fig 4)

Figure 4 Select Firmware Package

6. wait for project creation process

Figure 5 Project Creation process

7. Initial view of STM32CUBE ide after project generation

Figure 6

8. Go to System core > SYS > Enable Serial wire debug

Figure 8 Enable Serial Wire Debug

9. If require enable external clock

Figure 9 Enable external clock

10. System clock setting at 180MHz

Figure 10 clock settings

11. Enable DAC Functionality

Go to System mode > Analog > DAC > Enable Out1 & Out2 Configuration > keep all other settings as its

Figure 11 Enable DAC 1 & 2
Figure 12 Keep other DAC settings as its

12. Enable ADC Functionality

Go to System mode > Analog > ADC > In1 & In2 Configuration > Enable

Figure 13 Enable ADC1 & 2

13. Go to System mode > Analog > Parameter Settings

Scan Conversion Mode: Enable

Rank 1: In1

Rank 2: In2

Figure 14 ADC Parameter Settings

14. Go to System mode > Analog > DMA Settings

Mode: Circular

Data Width: Word

Priority: Low

Figure 15 DMA Parameter Settings

15. Press below icon for code generation

Figure 16: Cube IDE Code Generation

16. Sample Code

#define MAX_ADC_CHANNEL 2U
#define DAC_JUMP_COUNT	100U
#define DAC_LOWER_THRESHOLD 200U
#define DAC_UPPER_THRESHOLD 2100U

/* USER CODE BEGIN PV */
uint32_t dac_data = DAC_LOWER_THRESHOLD;
uint32_t adcValue;
uint32_t alocalbuff[MAX_ADC_CHANNEL];

int main (void)
{
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_DAC_Init();
  HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
  HAL_DAC_Start(&hdac, DAC_CHANNEL_2);
  
  while (1)
  {
    
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    HAL_Delay(1000);	//1000 ms delay

    HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, dac_data);
    HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, dac_data);

    uart1_printf_debug(YEL"DAC Value = %d  === ",dac_data);
    HAL_ADC_Start_DMA(&hadc1,(uint32_t *)alocalbuff,MAX_ADC_CHANNEL);

    uart1_printf_debug(GRN"ADC Value 0 = %d , ",alocalbuff[0]);
    uart1_printf_debug(GRN"ADC Value 1 = %d\n", alocalbuff[1]);

    dac_data += DAC_JUMP_COUNT;
    if (dac_data > DAC_UPPER_THRESHOLD)
      dac_data = DAC_LOWER_THRESHOLD;
  }
}

16. Debug Output

Software Tools:
  1. STM32CubeIDE
  2. STM32CubeMx
  3. Teraterm
Hardware Setup:
  1. STM32F429IDISCOVERY board
  2. Mini USB Cable
  3. Jumper wire
Conclusion:

Successfully demonstrated ADC functionality in scan mode (Dual Channel), for testing purpose we have used Two DAC’s & UART for debug.

If you enjoyed this article, share your feedback.

References:
  1. STM32 HAL Library
  2. STM32 UM1718 document
Similar topics:
  1. STM32 Peripherals: ADC using Polling Mode
  2. STM32 Peripherals: UART Interrupt Mode
  3. STM32-Peripheral’s-SPI: Polling Mode
  4. STM32 Peripherals : Base timer in interrupt mode
  5. STM32 Peripherals: DAC

Leave a Reply

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

%d bloggers like this: