top of page

12-STM32 ADC DMA Method



Previous Tutorial

Example 12

Next Tutorial



This project showcases the utilization of ADC DMA (Direct Memory Access) method on the STM32L476 microcontroller to read analog voltages from a potentiometer.

  • The analog voltage from the potentiometer is converted into a digital value using the ADC.

  • The DMA controller is employed to transfer the converted ADC values directly to memory without CPU intervention.

  • The digital values are then transmitted via UART to a PC, enabling real-time monitoring of the ADC values.


ADC DMA with HAL functions:

  • ADC DMA method employs DMA (Direct Memory Access) controller to automatically transfer ADC conversion results to memory without CPU intervention.

  • Here's a breakdown of the steps involved in implementing ADC DMA with HAL functions:

  • ADC Initialization: Initialize the ADC peripheral using HAL_ADC_Init().

  • ADC Channel Configuration: Configure the ADC channel and associated GPIO pin.

  • DMA Configuration: Initialize and configure the DMA controller to handle ADC data transfer.

  • Interrupt Configuration: Enable ADC DMA interrupt using HAL_ADC_Start_DMA().

HAL_ADC_Start_DMA(&hadc1, &adc_value, 1);
  • Data Transmission: Transmit the converted ADC values stored in memory via UART to a PC.

  • Error Handling: Handle any errors that may occur during ADC conversion or DMA transfer.

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
	{
		if(hadc->Instance == ADC1)
		{
			ADC_Value=HAL_ADC_GetValue(&hadc1);
			adc_valid=1;
		}
	}

Required Parts For Example:

  1. STM32L476 development board.

  2. Potentiometer.

  3. USB-to-Serial converter (if connecting to a PC).

  4. PC with UART terminal software (e.g., PuTTY, RealTerm, Tera Term).


CUBEIDE Configuration Steps:

  1. Create a new project in CUBEIDE.

  2. Select the STM32L476 microcontroller variant.

  3. Configure ADC peripheral settings, including resolution, sampling frequency, and channel selection, using the CubeMX configuration tool.

  4. Configure UART peripheral settings for serial communication with the PC.

  5. Configure DMA controller settings for ADC data transfer.

  6. Generate initialization code and project configuration.


Set ADC:


SET UART:

"Sometimes you can't see yourself clearly until you see yourself through the eyes of others." -- Ellen DeGeneres

CODE:

#include<string.h>

ADC_HandleTypeDef hadc1;
TIM_HandleTypeDef htim2;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM2_Init(void);

uint16_t adc_value=0;
uint8_t adc_valid=0;
uint16_t my_adc_value=0;
char msg[50]={'\0'};

#define SYSTICK_LOAD (SystemCoreClock/1000000U)
#define SYSTICK_DELAY_CALIB (SYSTICK_LOAD >> 1)

#define DELAY_US(us) \
	do { \
	      uint32_t start = SysTick->VAL; \
	      uint32_t ticks = (us * SYSTICK_LOAD)-SYSTICK_DELAY_CALIB;  \
	      while((start - SysTick->VAL) < ticks); \
	   } while (0)

#define DELAY_MS(ms) \
	  do { \
	      for (uint32_t i = 0; i < ms; ++i) { \
	         DELAY_US(1000); \
	        } \
	     } while (0)

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
	if(hadc->Instance == ADC1)
	{
		adc_valid=1;
		adc_value=HAL_ADC_GetValue(&hadc1);
	}
}

int main(void) {

    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();
    MX_TIM2_Init();

  HAL_ADC_Start_DMA(&hadc1, &adc_value, 1);

  while (1)
  {
	if(adc_value)
	  {
		  adc_value=0;
		  HAL_ADC_Start_DMA(&hadc1, &adc_value, 1);
	  }

      my_adc_value= adc_value*100/4096; // adc_value between 0-100 		     
	  sprintf(msg, "My_ADC_Value=%d \r\n", my_adc_value);
	  HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 100);
	  DELAY_MS(30);
  }

void SystemClock_Config(void) {
    // System Clock Configuration
    // Add code to configure system clock if needed
}

static void MX_GPIO_Init(void) {
    // GPIO Initialization
    // Add code to initialize GPIO pins if needed
}

static void MX_ADC1_Init(void) {
    // ADC Initialization
    // Add code to initialize ADC if needed
}

static void MX_TIM2_Init(void) {
    // TIM2 PWM Initialization
    // Add code to initialize TIM2 for PWM if needed
}

Result


  • The STM32L476 ADC DMA project enables real-time monitoring of the ADC values from a potentiometer on a PC via UART communication.

  • As the potentiometer is adjusted, the ADC values are continuously converted and transferred to memory via DMA.

  • The DMA controller automatically transfers the ADC values from memory to UART for transmission to the PC.

  • This example demonstrates the efficient utilization of DMA for ADC data transfer, reducing CPU overhead and enabling real-time data transmission in embedded systems.









Now it's your turn.
What I'm asking from you this time is to create an example using not just one ADC channel, but three ADC channels with DMA METHOD. In other words, there will be three potentiometers and three LEDs. Each potentiometer will control the brightness of one LED. Let's see if you can do it! Those who can accomplish this, share your methods in the comments. Those who can't, feel free to ask questions in the comments.



Previous Tutorial

Tutorial 12

Next Tutorial





 
 
 

Recent Posts

See All

Comentarios


bottom of page