Direct Memory Access in Microcontroller: LPC1768 DMA Tutorial with Examples

Direct Memory Access in Microcontroller LPC1768 DMA Tutorial

Unlock High-Speed Data Transfers Without CPU Overhead

Direct Memory Access (DMA) is one of the most powerful performance features available in modern microcontrollers. In ARM Cortex-M3 based devices like the NXP LPC1768, DMA allows peripherals such as ADC, UART, SPI, and memory blocks to transfer data directly to RAM without continuous CPU intervention.

In real-time embedded systems, this means:

  • Faster data acquisition
  • Deterministic timing
  • Lower CPU utilization
  • Improved power efficiency

In this practical LPC1768 DMA guide, you will learn:

  • How DMA works in microcontroller systems
  • LPC1768 GPDMA architecture explained simply
  • LPC1768 ADC DMA example code
  • LPC1768 UART DMA example
  • Memory-to-memory DMA usage
  • Advanced DMA linked-list (scatter-gather) transfers

This guide is written for embedded engineers and firmware developers who want real, register-level DMA implementation, not theory alone.

Direct Memory Access in microcontroller systems enables high-speed data transfers between peripherals and memory without CPU intervention. This LPC1768 DMA tutorial explains how DMA works, with practical ADC DMA and UART DMA example code for ARM Cortex-M3. Learn to configure GPDMA, improve real-time performance, and reduce CPU load in embedded applications.

What Is DMA and How DMA Works in Microcontroller Systems

Direct Memory Access (DMA) is a hardware mechanism that allows peripherals to move data directly between memory and registers without CPU involvement during the transfer.

How DMA Works in a Microcontroller

The CPU configures the DMA controller with:

  • Source address
  • Destination address
  • Transfer size
  • Transfer type (M2M, P2M, M2P)

A peripheral (ADC, UART, SPI, etc.) generates a DMA request.
The DMA controller autonomously performs the transfer.
An interrupt notifies the CPU after completion or error.

This approach is widely used in ARM Cortex-M3 DMA applications to achieve high throughput and predictable timing.

Start Your Training Journey Today

Why DMA Matters in LPC1768 (ARM Cortex-M3)

The LPC1768 microcontroller includes a powerful General-Purpose DMA (GPDMA) controller designed for high-speed embedded systems.

Key Benefits of Using DMA in LPC1768

  • Reduced CPU load – CPU remains free for control logic
  • Higher throughput – Ideal for ADC sampling and UART streaming
  • Power efficiency – CPU can sleep while DMA runs
  • Real-time performance – Deterministic data movement

LPC1768 DMA Architecture Overview

  • 8 independent DMA channels
  • Memory-to-memory transfers
  • Peripheral-to-memory transfers
  • Memory-to-peripheral transfers
  • Hardware DMA request lines from ADC, UART, SPI, I2S
  • Linked-list (scatter-gather) DMA

This flexibility makes LPC1768 DMA suitable for both simple and advanced embedded applications.

Setting Up LPC1768 DMA – Step by Step

1. Enable DMA Clock and Power


// Power up GPDMA
LPC_SC->PCONP |= (1 << 29); // Enable DMA request select (if required) LPC_SC->DMAREQSEL |= 1;

2. Configure DMA Channel for ADC (LPC1768 ADC DMA)


void configure_dma_adc(void) {

    LPC_GPDMA->CH[0].CSRCADDR  = (uint32_t)&LPC_ADC->ADDR0;
    LPC_GPDMA->CH[0].CDESTADDR = (uint32_t)adc_buffer;

    LPC_GPDMA->CH[0].CCONTROL =
        (1000 << 0) |     // Transfer size
        (2 << 18)  |     // Source width: 16-bit
        (2 << 21)  |     // Destination width: 16-bit
        (1 << 27)  |     // Destination increment
        (1 << 31);       // Terminal count interrupt
}

3. Link DMA to ADC Peripheral


void link_dma_to_adc(void) {

    LPC_ADC->ADCR |= (1 << 21); // Enable ADC DMA LPC_GPDMA->DMACSync |= (1 << 0); LPC_GPDMA->CH[0].CCONFIG =
        (1 << 0)  |   // Enable channel
        (1 << 1)  |   // Source peripheral: ADC
        (1 << 11);    // Peripheral-to-memory
}

This completes a working LPC1768 ADC DMA example.

 

Explore Courses - Learn More

 

Practical Applications of DMA in LPC1768

A. LPC1768 UART DMA Example (High-Speed Serial Communication)


void uart_dma_send(const uint8_t *data, uint32_t length) {

    LPC_GPDMA->CH[1].CCONFIG &= ~(1 << 0); LPC_GPDMA->CH[1].CSRCADDR  = (uint32_t)data;
    LPC_GPDMA->CH[1].CDESTADDR = (uint32_t)&LPC_UART1->THR;

    LPC_GPDMA->CH[1].CCONTROL = length | (1 << 31); LPC_UART1->DMACR = 0x2;

    LPC_GPDMA->CH[1].CCONFIG =
        (1 << 0) | (6 << 6);
}

This LPC1768 UART DMA example enables continuous, non-blocking UART transmission.

B. Memory-to-Memory DMA Transfer


void dma_memcpy(void *dest, void *src, uint32_t size) {

    LPC_GPDMA->CH[2].CSRCADDR  = (uint32_t)src;
    LPC_GPDMA->CH[2].CDESTADDR = (uint32_t)dest;

    LPC_GPDMA->CH[2].CCONTROL = size | (1 << 31); LPC_GPDMA->CH[2].CCONFIG = (1 << 0);
}

Advanced Feature: DMA Linked Lists (Scatter-Gather)


typedef struct {
    uint32_t src;
    uint32_t dest;
    uint32_t control;
    uint32_t next;
} DMA_LLI;

Linked lists allow chained DMA transfers without CPU intervention.

Common Pitfalls and Debugging Tips

  • Ensure data width alignment
  • Use DMA-accessible SRAM
  • Enable peripheral clocks first
  • Do not reconfigure active DMA channels

DMA Status Debug Code


void check_dma_status(uint8_t channel) {

    if (LPC_GPDMA->INTSTAT & (1 << channel)) { if (LPC_GPDMA->INTTCSTAT & (1 << channel)) { // Transfer complete } if (LPC_GPDMA->INTERRSTAT & (1 << channel)) { uint8_t error = (LPC_GPDMA->CH[channel].CSTAT >> 1) & 0x3;
        }

        LPC_GPDMA->INTTCCLEAR  = (1 << channel); LPC_GPDMA->INTERRCLEAR = (1 << channel);
    }
}

Performance Comparison: CPU vs DMA

Transfer MethodCPU UsageTime (1 KB)
CPU Copy100%42 µs
DMA Transfer0–5%8 µs
Improvement20× less CPU5× faster

 

Talk to Academic Advisor

Conclusion

Direct Memory Access in microcontroller platforms like the LPC1768 is a game-changer for embedded systems requiring high-speed data movement with minimal CPU overhead. By implementing LPC1768 DMA, ADC DMA, and UART DMA, you can build efficient, real-time, and power-optimized applications.

Start with simple DMA transfers, then explore linked-list DMA to unlock the full potential of ARM Cortex-M3 GPDMA.

Frequently Asked Questions

Yes. The LPC1768 ADC supports DMA via the GPDMA controller, enabling peripheral-to-memory transfers without CPU involvement.

For large or continuous data transfers, DMA is significantly faster and more efficient than interrupt-based handling.

Yes. DMA operates independently, allowing the CPU to enter low-power modes until a DMA interrupt occurs.

The LPC1768 GPDMA controller provides 8 independent DMA channels.

DMA is not ideal for very small transfers, tightly synchronized control loops, or when RAM resources are extremely limited.

Author

Embedded Systems Trainer – IIES

Updated On: 19-01-26


10+ years of hands-on experience delivering practical training in Embedded Systems and it's design