STM32 UART DMA example - STM32CubeIDE STM32CubeMX

In this tutorial I will show you how to use DMA mode with UART on STM32 Microcontroller. 

You will learn,

  • How to Create project using STM32CubeMX.
  • Import and Edit Project in STM32CubeIDE
  • Enable and use DMA with UART on STM32 Microcontroller. 
  • Build and Flash code on Nucleo-F334 board. 


STM32 UART Communication with DMA Mode



STM32F334 Features

  • Core: Arm® Cortex®-M4 32-bit CPU with FPU (Floating Point Unit) up to 72 MHz.
  • Memory: Up to 64 KB Flash, 12 KB SRAM.
  • Analog: Fast 12-bit ADCs (5 Msps), Comparators, Op-Amp, DACs.
  • Timers: High-resolution Timer (HRTIM), Motor Control Timer, General-purpose Timers.
  • Communication: I2C, SPI, up to 3 USARTs, CAN.
  • Power: Comprehensive power-saving modes. 



What is Direct Memory Access (DMA)?

DMA is a technology that allows hardware devices to transfer data between themselves and memory without involving CPU. It increases CPU performance by offloading data transfer tasks from CPU, Enabling it to focus it on other critical operations.

DMA can be considered as traffic controller for data transfers in and out of memory. It efficiently manages these transfers freeing CPU for more complex tasks.

Advantages of DMA,

  • Increases efficiency by reducing load on CPU,
  • Real-Time responsiveness,
  • Reduces power usages,
  • High throughput and Speed,
  • Non-Blocking operation,
  • Power saving


Prerequisite

Before proceeding further make sure you have installed STM32CubeIDE and STM32CubeMX. Links to download both are as below,

Hardware Used

In this tutorial we are using below hardware,

Project Creation and Settings

We are going to use 2 different software from STMicroelectronics,
  1. STM32CubeMX
  2. STM32CubeIDE

STM32CubeMX

STM32CubeMX is a graphical tool that allows a very easy configuration of STM32 microcontrollers and microprocessors, as well as the generation of the corresponding initialization C code for the Arm® Cortex®‑M core or a partial Linux® Device Tree for the Arm® Cortex®‑A core, through a step-by-step process.
 

STM32CubeIDE

STM32CubeIDE is eclipse based IDE with an advanced C/C++ development platform with peripheral configuration, code generation, code compilation, and debug features for STM32 microcontrollers and microprocessors.

STM32CubeMX Steps,

I will explain step by step process for project creation, peripheral settings.

  1. Open STM32CubeMX software and Click on File -> New Project or "CTRL + N" to create new project.

    How to create a new project using STM32CubeMX Software on Windows


  2. At New Project window, Search "stm32f334r" in Commercial part number tab, It will filter and show part numbers and board with STM32F334 microcontroller.

    Select STM32F334R8T6 which is microcontroller part used on NUCLEO-F334R8 board and click on start project button.


    Search STM32F334 in STM32CubeMX Software


  3. You will see screen options for configuring peripherals and clocks of microcontroller.

    STM32CubeMX new project configuration screen.

     
  4. First we will configure clocks, click on "Clock Configuration tab".

    STM32CubeMX Clock configuration window.

    STM32F334 supports maximum 64MHZ clock frequency. Enter 64 at "To AHB Bus core tab" and press "Enter" button. STM32CubeMX will automatically do required changes in clock settings.

  5. Now we will do settings for UART module,

    STM32CubeMX UART Settings.

    Select USART2 from Connectivity drop-down, which will options for settings UART.

    Select Asynchronous from Mode drop-down.

    Set below values from Basic Parameters options in "Parameters Settings" tab,
    Baud Rate        : 9600 Bits/s
    Word Length    : 8 Bits
    Parity                : None
    Stop Bits           : 1

  6. Next, We will initialize DMA for UART,

    Click on "DMA Settings" tab,


    STM32CubeMX UART DMA Settings Options.


    Lets enable DMA for UART TX and RX using "Add" button. Select settings as show in below image,

    STM32CubeMX UART Transmit and Receive DMA Settings Options.


  7. Before generating code, We will save project at a STM32CubeIDE workspace location and do other settings.

    Before saving project do following settings shown in below image.
    a. Project Name : Name of Project You want,
    b. Project Location : Location of STM32CubeIDE Workspace,
    c. Toolchain / IDE : Select STM32CubeIDE from Drop Down,

    STM32CubeMX Project Settings.

  8. To Generate code, Click on "GENERATE CODE" button.

    STM32CubeMX Generate Code.

    In few seconds it will generate code source code for STM32CubeIDE Project.

STM32CubeIDE Steps,

Lets import created project in STM32CubeIDE, Modify code, build and then flash on board.

  1. Open STM32CubeIDE and select workspace location which we used for STM32CubeMX project export and click on "Launch" button.

    STM32CubeIDE workspace location selection.

    Wait for STM32CubeIDE to open.

  2. After opening STM32CubeIDE, You will see screen as shown below,

    STM32CubeIDE window.

  3. To import STM32CubeMX exported project into STM32CubeIDE, Click on File tab and import option.

    STM32CubeIDE File Tab.


    It will open import window,

    STM32CubeIDE Import Window.

    Select "Generate -> Existing Projects into Workspace" and click on "Next" button.


    At Import Window, Click on Browse button and select path at which we have exported project.

    STM32CubeIDE Project location selection.


  4. Select Project and Click on Finish button.

    STM32CubeIDE Select and Import Project.

  5. After project gets imported, You will see screen as shown below.

    STM32CubeIDE Screen after Project Import.

  6. Modify main.c code file as per given source code in github link below and then right click on project and build project.

    STM32CubeIDE build project.

    Uploading: 116561 of 116561 bytes uploaded.
    After build completion connect hardware and flash on board.

Code

  uint8_t txbuf[] = "Hi from EmbeTronics!!";
  uint8_t rxbuf[256] = "";

  HAL_UART_Transmit_DMA(&huart1, txbuf,strlen((char *)txbuf));

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rxbuf, 256) == HAL_OK)
	  {
		  HAL_UART_Transmit_DMA(&huart1, rxbuf,strlen((char *)rxbuf));
		  while(HAL_DMA_GetState(&hdma_usart1_tx) == HAL_DMA_STATE_BUSY);
		  memset(rxbuf,0,256);
	  }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */


Explanation of Code

Let us understand blocks of code and see how it works.

First we have defined array variables for transmitting and receiving data from UART.
uint8_t txbuf[] = "Hi from EmbeTronics!!";
uint8_t rxbuf[256] = "";

HAL_UART_Transmitt_DMA function transmits data from txbuf on UART using DMA Mode.
HAL_UART_Transmit_DMA(&huart1, txbuf,strlen((char *)txbuf));

Below codes runs in infinite loop and waits for data to be received from UART in DMA mode and Transmits same data bak to host using DMA mode with UART.
if(HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rxbuf, 256) == HAL_OK)
{
    HAL_UART_Transmit_DMA(&huart1, rxbuf,strlen((char *)rxbuf));
    while(HAL_DMA_GetState(&hdma_usart1_tx) == HAL_DMA_STATE_BUSY);
    memset(rxbuf,0,256);
}


Full Project Code

You can directly download and use whole project from below GitHub link.

GitHub Repo Link



Working Of Code

Below video shows working of this project. Code at boot up will send "Hi from EmbeTronics!!", then it will wait for data to be received from UART and will send back received data.




Wrapping Up

In todays tutorial, You have learned how to use DMA with UART. Using DMA with UART reduces load on CPU and increases performance.

Please leave a comment if you have a question or you found this tutorial helpful.


Tags

STM32 UART DMA example,
stm32 uart dma,
STM32 UART DMA transmit,
STM32 UART DMA RX,
STM32 UART DMA receive to idle,
STM32 UART DMA receive unknown length,
STM32 UART interrupt example,
HAL_UART_Transmit_DMA example,

Post a Comment

0 Comments