What is DMA
DMA, or direct memory access, is a feature in some microcontrollers that lets data move independently of the CPU. This frees the CPU to perform other tasks and increases the total amount of concurrent work the system can handle.
Basic DMA data flows
DMA can move data between memory regions, from memory to a peripheral, or from a peripheral to memory.
Memory-to-peripheral example
An example of memory-to-peripheral transfer is sending a large block of data through a communication peripheral such as a UART. Without DMA, the CPU would either block during the transfer (typically slow, limited by the communication protocol speed) or use interrupts to manage the transfer, which adds context-switching overhead.
This example assumes a single simultaneous transfer; many DMA implementations support multiple concurrent streams, depending on the specific microcontroller.
Peripheral-to-memory example
Peripheral-to-memory DMA works similarly. While the CPU is busy with other tasks, data can be read from a communication peripheral (for example, a UART) and copied into a memory buffer. Besides freeing the CPU, this ensures received data is not lost if the CPU is not currently running the code to handle incoming data.
When multiple devices may communicate concurrently, DMA can buffer each communication stream without data loss until the CPU is ready to process the received data. Although some microcontrollers include a small receive buffer in the peripheral, using DMA allows the receive buffer to be as large as available RAM.
ADC/DAC and DSP pipeline
Another common use case is ADC sampling of analog signals. A timer can trigger ADC conversions at set intervals across one or more channels, and the readings are automatically transferred to a memory buffer via DMA. A separate DMA stream can then copy these buffers to another memory area for the CPU to run DSP algorithms. Finally, another DMA stream can transfer the processed samples to a DAC for output (memory-to-peripheral).
Buffering strategies
For receiving data, microcontrollers may support circular DMA buffers or ping-pong (double) buffers, where data reception alternates between two memory regions. Circular buffers are often preferred for their efficiency and simpler code.
Practical note for developers
DMA can be intimidating at first, but implementing it provides reusable code patterns that can be applied to other projects and significantly increase a project’s capability and the complexity the microcontroller can handle.