green circuit boardPhoto by Miguel Á. Padriñán on <a href="https://www.pexels.com/photo/green-circuit-board-343457/" rel="nofollow">Pexels.com</a>

Today we are going to read the ADC with the help of DMA module in STM32F4 discovery board. If you had seen our previous STM32 post series, you may had remember that in one of our previous post we shows how to read the adc in timer trigger mode. In today’s tutorial our main focus is STM32 DMA module.

The DMA is for Direct Memory Access, and we are going to use the ADC with DMA. For this we are using the HAL library and STM32CUBEIDE unlike the previous tutorial where we demonstrated the timer trigger mode of ADC reading with bare metal programming of the ADC. Today we are going to use STM32 CUBE IDE for developing our project and STM32 HAL library for accessing the ADC and DMA peripherals.

Create a New Project in STM32 CUBE IDE

First of all, let’s create a new project and setup .ioc file for our STM32F4 Discovery board. For this, all you have to do is to follow the following steps.

  • Open STM32CubeIDE.
  • Go to “File” > “New” > “STM32 Project”.
  • Select the target microcontroller (e.g., STM32F407) and click “Next”.
  • Name your project (e.g., “ADC_DMA_Example”) and click “Finish”.

Configure the project with STM32CubeMX

Next we need to configure our project in STM32CubeMX setup which is visual setting for the required peripheral in microcontroller. Here is how you need to setup the ADC module

  • Open the .ioc file in the “Core” folder of your project.
  • In the “Pinout & Configuration” tab, configure the following peripherals:
    • ADC: Enable the ADC channel you want to use (e.g., IN1) and set the Conversion Mode to “Continuous Conversion.”
    • DMA: Enable DMA for the ADC, set the Direction to “Peripheral to Memory”, the Mode to “Circular”, and the Memory Data Width to “Half Word.”
    • GPIO: Set the appropriate GPIO pin as “Analog” for the ADC channel (e.g., PA1 for ADC_IN1).
    • Enable the necessary clock sources if required.
  • Save your configuration and generate the code.

Here you need to remember few things, because we want to read the adc and we have to include the adc pin setup as and ADC input mode. DMA direction is from Peripheral to Memory because we need to read data from ADC into our memory address. The mode is Circular, this is due to the nature of the ADC, which reading could be stored into a circular buffer. If you are not aware of Circular Buffer Data Structure, you might want to read the circular buffer data structure article on Wikipedia for more details.

Edit the Main.c File

Now we are done with the visual setup and ready to jump into the coding part. For that, you need to switch to the main.c file which will automatically switch your perspective of the IDE and auto generate code for you. In the main.c file you first of all have to declare a circular buffer for holding the adc readings. This is how you could do this

#define ADC_BUFFER_SIZE 10
volatile uint16_t adc_buffer[ADC_BUFFER_SIZE];
Code language: CSS (css)

Next In the main() function, before the while (1) loop, start the ADC with DMA:

HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_BUFFER_SIZE);

If you want to process the adc data, you can create a custom function to process the all readings of the ADC. You may need to do this due to the reason, maybe, you need to take the average of the samples. So here is how you can achieve this

void process_adc_data(void) {
  // Process the ADC data, for example, calculate the average value:
  uint32_t sum = 0;
  for (size_t i = 0; i < ADC_BUFFER_SIZE; i++) {
    sum += adc_buffer[i];
  }
  uint16_t average = sum / ADC_BUFFER_SIZE;

//yu may want to transfer the reading to the serial port 
}
Code language: JavaScript (javascript)

You can call this function inside the while(1) loop like following

while (1) {
  process_adc_data();
  HAL_Delay(1000); // Delay to avoid excessive processing
}
Code language: JavaScript (javascript)

Compile and flash the STM32 Project

Now that you had written the logic, it’s time to check the project by compiling and running to the target device, which in our case is STM32F4 Discovery board. These are the steps you need to follow to compile and write the code on to your STM32F4 Discovery board.

  • Build the project by pressing “Ctrl+B” or by clicking the “Build” icon.
  • Connect your STM32 board to your computer.
  • Flash the compiled binary onto your board by pressing “Ctrl+F” or by clicking the “Run” icon.

By Abdul Rehman

My name is Abdul Rehman and I love to do Reasearch in Embedded Systems, Artificial Intelligence, Computer Vision and Engineering related fields. With 10+ years of experience in Research and Development field in Embedded systems I touched lot of technologies including Web development, and Mobile Application development. Now with the help of Social Presence, I like to share my knowledge and to document everything I learned and still learning.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.