Bird
Raised Fist0
Embedded Cprogramming~20 mins

DMA with ADC for continuous sampling in Embedded C - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
DMA ADC Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this DMA ADC buffer processing code?

Consider the following embedded C code snippet that uses DMA to continuously sample ADC values into a buffer. What will be the printed output after the DMA transfer completes once?

Embedded C
#include <stdio.h>
#include <stdint.h>

#define BUFFER_SIZE 4

uint16_t adc_buffer[BUFFER_SIZE] = {0};

void DMA_TransferComplete_Callback() {
    for (int i = 0; i < BUFFER_SIZE; i++) {
        printf("%d ", adc_buffer[i]);
    }
    printf("\n");
}

int main() {
    // Simulate ADC values filled by DMA
    adc_buffer[0] = 100;
    adc_buffer[1] = 200;
    adc_buffer[2] = 300;
    adc_buffer[3] = 400;

    DMA_TransferComplete_Callback();
    return 0;
}
A100 200 300 0
B0 0 0 0
C100 200 300 400
D200 300 400 500
Attempts:
2 left
💡 Hint

Look at how the adc_buffer array is filled before the callback prints it.

🧠 Conceptual
intermediate
1:30remaining
Which statement best describes DMA's role in continuous ADC sampling?

In embedded systems, what is the main advantage of using DMA with ADC for continuous sampling?

ADMA allows ADC to sample data without CPU intervention, reducing CPU load.
BDMA increases the ADC sampling rate beyond hardware limits.
CDMA converts analog signals to digital automatically.
DDMA disables ADC interrupts to save power.
Attempts:
2 left
💡 Hint

Think about how DMA helps with data transfer in the background.

🔧 Debug
advanced
2:30remaining
Identify the error causing incorrect ADC data in DMA buffer

Given the code below, the DMA buffer does not contain the expected ADC values after sampling. What is the most likely cause?

Embedded C
volatile uint16_t adc_buffer[4];

void ADC_DMA_Init() {
    // DMA configuration omitted for brevity
    // Start ADC with DMA
    HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, 4);
}

int main() {
    ADC_DMA_Init();
    // Wait for DMA transfer complete
    while(!dma_transfer_complete_flag) {}
    // Process adc_buffer here
    return 0;
}
AThe DMA transfer size is set incorrectly to 4 instead of 8.
BThe dma_transfer_complete_flag is never set to true.
CThe ADC is not started before DMA initialization.
DThe adc_buffer is not declared as volatile, so compiler optimizations may cause stale data.
Attempts:
2 left
💡 Hint

Consider how the compiler treats variables modified outside the main flow.

📝 Syntax
advanced
1:30remaining
Which option correctly configures DMA for circular ADC sampling?

Which of the following DMA initialization snippets correctly sets up circular mode for continuous ADC sampling?

Ahdma_adc.Init.Mode = DMA_SINGLE;
Bhdma_adc.Init.Mode = DMA_CIRCULAR;
Chdma_adc.Init.Mode = DMA_PINGPONG;
Dhdma_adc.Init.Mode = DMA_NORMAL;
Attempts:
2 left
💡 Hint

Continuous sampling requires the DMA to restart automatically after finishing.

🚀 Application
expert
3:00remaining
How many ADC samples are stored after 3 full DMA buffer cycles?

An ADC is configured with DMA in circular mode with a buffer size of 8 samples. The DMA continuously fills the buffer. After 3 full cycles of the DMA buffer, how many unique ADC samples have been stored in total?

A24
B8
C3
D16
Attempts:
2 left
💡 Hint

Think about how many samples fit in one buffer and multiply by the number of cycles.

Practice

(1/5)
1. What is the main advantage of using DMA with ADC in continuous sampling mode?
easy
A. It disables ADC interrupts to save power.
B. It transfers ADC data to memory automatically without CPU intervention.
C. It allows manual control of each ADC conversion.
D. It increases the ADC resolution beyond hardware limits.

Solution

  1. Step 1: Understand DMA role with ADC

    DMA (Direct Memory Access) moves data from ADC to memory automatically, reducing CPU load.
  2. Step 2: Identify continuous sampling benefit

    Continuous mode means ADC keeps sampling without CPU restarting it each time.
  3. Final Answer:

    It transfers ADC data to memory automatically without CPU intervention. -> Option B
  4. Quick Check:

    DMA automates data transfer = It transfers ADC data to memory automatically without CPU intervention. [OK]
Hint: DMA automates ADC data transfer, no CPU needed [OK]
Common Mistakes:
  • Thinking DMA increases ADC resolution
  • Confusing manual and automatic data transfer
  • Assuming DMA disables ADC interrupts
2. Which of the following is the correct way to configure DMA for circular mode with ADC in embedded C?
easy
A. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
B. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
C. DMA_InitStructure.DMA_Mode = DMA_Mode_Manual;
D. DMA_InitStructure.DMA_Mode = DMA_Mode_Interrupt;

Solution

  1. Step 1: Recall DMA modes for continuous ADC sampling

    DMA_Mode_Circular allows buffer to be reused endlessly for continuous data.
  2. Step 2: Match correct DMA mode setting

    DMA_Mode_Normal stops after one transfer; DMA_Mode_Circular repeats automatically.
  3. Final Answer:

    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; -> Option A
  4. Quick Check:

    Circular mode enables continuous buffer reuse = DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; [OK]
Hint: Use DMA_Mode_Circular for endless ADC data buffering [OK]
Common Mistakes:
  • Using DMA_Mode_Normal for continuous sampling
  • Confusing DMA_Mode_Manual which doesn't exist
  • Selecting interrupt mode instead of circular
3. Given the following code snippet, what will be the content of the buffer after 3 ADC conversions with DMA in circular mode?
uint16_t adc_buffer[4] = {0};
// DMA and ADC configured in circular mode
// ADC conversions produce values: 100, 200, 300
// DMA transfers these values into adc_buffer sequentially
// After 3 conversions, what is adc_buffer content?
medium
A. [300, 200, 100, 0]
B. [0, 100, 200, 300]
C. [100, 200, 300, 0]
D. [100, 200, 0, 300]

Solution

  1. Step 1: Understand DMA circular buffer filling

    DMA fills buffer sequentially from index 0 upwards with ADC values.
  2. Step 2: Map ADC values to buffer after 3 transfers

    First 3 elements get 100, 200, 300; last element remains 0 as no 4th conversion yet.
  3. Final Answer:

    [100, 200, 300, 0] -> Option C
  4. Quick Check:

    Buffer fills sequentially = [100, 200, 300, 0] [OK]
Hint: DMA fills buffer from start sequentially [OK]
Common Mistakes:
  • Assuming buffer shifts values on each new sample
  • Thinking DMA fills buffer backwards
  • Confusing buffer initialization with data content
4. Identify the error in this DMA + ADC continuous sampling setup code snippet:
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;

// ADC and DMA configuration omitted for brevity
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
ADC_Cmd(ADC1, ENABLE);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
medium
A. DMA_Mode_Normal should be DMA_Mode_Circular for continuous sampling.
B. ADC_SoftwareStartConvCmd should be called before DMA_Init.
C. DMA1_Channel1 is not valid for ADC1 DMA transfers.
D. ADC_Cmd should be called after starting conversion.

Solution

  1. Step 1: Check DMA mode for continuous ADC sampling

    DMA_Mode_Normal stops after one transfer; continuous sampling needs DMA_Mode_Circular.
  2. Step 2: Verify other calls order and parameters

    Calling ADC_SoftwareStartConvCmd after DMA_Init is correct; DMA1_Channel1 is valid for many MCUs; ADC_Cmd before conversion start is correct.
  3. Final Answer:

    DMA_Mode_Normal should be DMA_Mode_Circular for continuous sampling. -> Option A
  4. Quick Check:

    Continuous DMA needs circular mode = DMA_Mode_Normal should be DMA_Mode_Circular for continuous sampling. [OK]
Hint: Use circular mode for continuous DMA transfers [OK]
Common Mistakes:
  • Using normal mode for continuous DMA
  • Misordering ADC and DMA initialization calls
  • Assuming DMA channel is invalid without checking MCU
5. You want to continuously sample 8 ADC channels using DMA in circular mode into a buffer of size 16 (uint16_t). Which approach correctly handles the buffer to process the latest samples without data loss?
hard
A. Disable circular mode and manually restart DMA after each 8 samples.
B. Process the entire buffer only after DMA transfer completes once, then restart DMA.
C. Use polling to check ADC conversion complete flag before reading buffer.
D. Use half-transfer and transfer-complete DMA interrupts to process buffer halves alternately.

Solution

  1. Step 1: Understand circular DMA buffer usage

    Circular DMA fills buffer continuously; half-transfer and transfer-complete interrupts signal when half/full buffer is ready.
  2. Step 2: Choose method to avoid data loss

    Processing halves alternately on interrupts prevents overwriting unprocessed data and ensures continuous handling.
  3. Final Answer:

    Use half-transfer and transfer-complete DMA interrupts to process buffer halves alternately. -> Option D
  4. Quick Check:

    Half/full DMA interrupts enable safe continuous processing = Use half-transfer and transfer-complete DMA interrupts to process buffer halves alternately. [OK]
Hint: Use DMA half/full interrupts to process buffer safely [OK]
Common Mistakes:
  • Waiting for full buffer before processing causes data loss
  • Disabling circular mode loses continuous sampling benefit
  • Polling ADC flags wastes CPU and misses DMA data
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard