Peripheral-to-memory transfer moves data from a device like a sensor or communication port directly into memory. This helps programs get data without waiting or using extra steps.
0
0
Peripheral-to-memory transfer in Embedded C
Introduction
Reading sensor data continuously into memory for processing.
Receiving data from a communication port like UART or SPI.
Storing audio or video data from a camera or microphone.
Logging data from a peripheral device without CPU delay.
Syntax
Embedded C
DMA_Channel->CCR = DMA_CCR_MINC | DMA_CCR_TCIE | DMA_CCR_EN; DMA_Channel->CPAR = (uint32_t)&PERIPHERAL_DATA_REGISTER; DMA_Channel->CMAR = (uint32_t)memory_buffer; DMA_Channel->CNDTR = data_length;
This example shows setting up a DMA channel for peripheral-to-memory transfer.
DMA_CCR_MINC enables memory address increment, so data fills the buffer.
Examples
Setup DMA channel 1 to transfer 100 ADC readings from ADC data register to adc_buffer in memory.
Embedded C
DMA1_Channel1->CCR = DMA_CCR_MINC | DMA_CCR_EN;
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;
DMA1_Channel1->CMAR = (uint32_t)adc_buffer;
DMA1_Channel1->CNDTR = 100;Configure DMA channel 3 to receive 50 bytes from SPI1 data register into spi_rx_buffer with transfer complete interrupt enabled.
Embedded C
DMA2_Channel3->CCR = DMA_CCR_MINC | DMA_CCR_TCIE | DMA_CCR_EN;
DMA2_Channel3->CPAR = (uint32_t)&SPI1->DR;
DMA2_Channel3->CMAR = (uint32_t)spi_rx_buffer;
DMA2_Channel3->CNDTR = 50;Sample Program
This program simulates a peripheral-to-memory transfer using a DMA channel. It copies 10 bytes from a simulated peripheral data array into a memory buffer and prints the result.
Embedded C
#include <stdint.h> #include <stdio.h> // Simulated peripheral data register volatile uint8_t PERIPHERAL_DATA_REGISTER = 0; // Buffer in memory to store data uint8_t memory_buffer[10]; // Simulated DMA channel structure typedef struct { uint32_t CCR; uint32_t CPAR; uint32_t CMAR; uint32_t CNDTR; } DMA_Channel_TypeDef; DMA_Channel_TypeDef DMA_Channel1; // Constants for DMA control register bits #define DMA_CCR_MINC (1 << 7) // Memory increment mode #define DMA_CCR_EN (1 << 0) // Channel enable // Function to simulate peripheral-to-memory transfer void start_dma_transfer(DMA_Channel_TypeDef *dma, volatile uint8_t *peripheral, uint8_t *memory, uint32_t length) { dma->CPAR = (uint32_t)peripheral; dma->CMAR = (uint32_t)memory; dma->CNDTR = length; dma->CCR = DMA_CCR_MINC | DMA_CCR_EN; // Simulate transfer: copy data from peripheral to memory for (uint32_t i = 0; i < length; i++) { memory[i] = peripheral[i]; } // Disable DMA after transfer dma->CCR &= ~DMA_CCR_EN; } int main() { // Simulate peripheral data as an array volatile uint8_t peripheral_data[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; // Start DMA transfer from peripheral_data to memory_buffer start_dma_transfer(&DMA_Channel1, peripheral_data, memory_buffer, 10); // Print memory buffer contents for (int i = 0; i < 10; i++) { printf("%d ", memory_buffer[i]); } printf("\n"); return 0; }
OutputSuccess
Important Notes
Peripheral-to-memory transfer often uses DMA to avoid CPU load.
Memory increment mode (MINC) is important to fill buffers correctly.
Always disable DMA channel after transfer to avoid unintended behavior.
Summary
Peripheral-to-memory transfer moves data directly from device to memory.
DMA hardware helps do this efficiently without CPU waiting.
Setup involves configuring source, destination, length, and enabling DMA.