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.
Peripheral-to-memory transfer in 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.
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;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;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.
#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; }
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.
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.
Practice
Solution
Step 1: Understand peripheral-to-memory transfer
This transfer moves data directly from a peripheral device to memory, bypassing the CPU to improve efficiency.Step 2: Identify the main purpose
The main goal is to reduce CPU load by letting hardware handle data movement.Final Answer:
To move data directly from a peripheral device to memory without CPU intervention -> Option CQuick Check:
Peripheral-to-memory transfer = direct data move without CPU [OK]
- Confusing peripheral-to-memory with memory-to-peripheral transfer
- Thinking CPU processes data during transfer
- Assuming transfer resets the device
Solution
Step 1: Understand DMA enable bit setting
To enable DMA channel, the enable bit (DMA_CCR_EN) must be set using bitwise OR to preserve other bits.Step 2: Analyze options
DMA_Channel->CCR |= DMA_CCR_EN; sets the enable bit correctly with |=. DMA_Channel->CCR = 0; clears all bits, disabling DMA. DMA_Channel->CCR &= ~DMA_CCR_EN; clears the enable bit. DMA_Channel->CCR = DMA_CCR_EN << 1; shifts enable bit incorrectly.Final Answer:
DMA_Channel->CCR |= DMA_CCR_EN; -> Option BQuick Check:
Enable DMA by setting bit with |= [OK]
- Using = instead of |= clears other bits
- Clearing enable bit instead of setting it
- Shifting bits incorrectly
uint8_t peripheral_data = 0x55;
uint8_t memory_buffer[1] = {0x00};
// DMA configured to transfer 1 byte from &peripheral_data to memory_buffer
// DMA transfer completes here
Solution
Step 1: Understand DMA transfer setup
DMA is set to transfer 1 byte from peripheral_data (0x55) to memory_buffer.Step 2: Determine memory_buffer[0] after transfer
After transfer, memory_buffer[0] will hold the value 0x55 copied from peripheral_data.Final Answer:
0x55 -> Option AQuick Check:
DMA copies 0x55 to memory_buffer[0] [OK]
- Assuming memory_buffer stays unchanged
- Confusing peripheral_data value
- Thinking DMA sets memory to 0xFF
DMA_Channel->CPAR = (uint32_t)&memory_buffer; DMA_Channel->CMAR = (uint32_t)&peripheral_data; DMA_Channel->CNDTR = 4; DMA_Channel->CCR &= ~DMA_CCR_EN; DMA_Channel->CCR |= DMA_CCR_EN;
Solution
Step 1: Recall DMA register roles
CPAR holds peripheral (source) address, CMAR holds memory (destination) address for peripheral-to-memory transfer.Step 2: Check the code assignments
The code sets CPAR = &memory_buffer (should be peripheral), CMAR = &peripheral_data (should be memory). Addresses are swapped.Final Answer:
The peripheral address and memory address are swapped -> Option DQuick Check:
CPAR=peripheral, CMAR=memory [OK]
- Swapping peripheral and memory addresses
- Enabling DMA before setting parameters
- Not disabling DMA before re-enabling
Solution
Step 1: Identify source and destination
Source is UART data register (peripheral), destination is memory buffer.Step 2: Set DMA registers correctly
Peripheral address register (CPAR) must point to UART data register, memory address register (CMAR) to buffer, transfer length to 8 bytes, then enable DMA channel.Final Answer:
Set DMA peripheral address to UART data register; set memory address to buffer; set transfer length to 8; enable DMA channel -> Option AQuick Check:
Peripheral = source, Memory = destination, length set before enable [OK]
- Swapping peripheral and memory addresses
- Enabling DMA before setting addresses and length
- Setting transfer length after enabling DMA
Ready to prove it?
Pass the test and this pattern moves unknown
