STM32 Automatic Data Acquisition System: Detailed Explanation of ADC + DMA Process (Includes Complete Code)

This is a further supplement and expansion of the original content, aimed at providing a more comprehensive understanding of the ADC + DMA automatic acquisition system in STM32, including its working principles, configuration details, and application techniques.

1. Overview of System Principles

The ADC + DMA automatic acquisition system is an efficient data acquisition architecture suitable for applications that require high-frequency sampling with low CPU usage (such as sensor acquisition, audio processing, voltage monitoring, etc.).

The system consists of the following three core modules:

  • ADC (Analog-to-Digital Converter): Converts continuously varying analog voltage signals into digital signals;
  • DMA (Direct Memory Access): Automatically transfers the results converted by the ADC to memory;
  • CPU (Central Processing Unit): Responsible only for initialization configuration and data processing, not involved in the intermediate transfer process.

Analogy for Understanding:

  • ADC is like a “scanner”, responsible for acquiring external signals;
  • DMA is like a “conveyor belt”, responsible for delivering the sampling results to memory;
  • CPU is like a “conductor”, only checking results and processing when needed, not responsible for data transfer.

2. Workflow

The complete workflow of data acquisition is as follows:

  1. CPU initializes and configures ADC and DMA
  2. Start ADC sampling
  3. After ADC completes one sampling, it automatically triggers DMA transfer
  4. DMA transfers data to the preset memory array
  5. When the sampling reaches the set quantity, DMA triggers an interrupt to notify the CPU
  6. CPU responds to the interrupt and processes the collected data

This mechanism achieves a fully automated process of **”acquisition – transfer – storage – processing”**, greatly freeing up CPU resources.

3. Key Technical Points

Technical Point Description
ADC Trigger Mode Can use software trigger or timer trigger; it is recommended to use timer trigger for achieving evenly spaced sampling
DMA Transfer Mode Use Circular mode for continuous sampling and rewriting
Data Buffer Use an array (e.g., <span>uint16_t ADC_ConvertedValue[]</span>) to store sampling results
Channel Mapping For STM32F1, DMA1_Channel1 is used in conjunction with ADC1
Data Alignment and Size ADC output is 12-bit, it is recommended to use <span>uint16_t</span> type for reception
Interrupt Handling Optionally use DMA transfer complete interrupt to implement data processing trigger mechanism

4. System Initialization Steps

Step 1: Configure GPIO as Analog Input

void ADC_GPIO_Config(void){    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    GPIO_InitTypeDef GPIO_InitStructure;    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  // ADC Channel 0    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;    GPIO_Init(GPIOA, &GPIO_InitStructure);}

Step 2: ADC Configuration

void ADC_Config(void){    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);    ADC_InitTypeDef ADC_InitStructure;    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;    ADC_InitStructure.ADC_ScanConvMode = DISABLE;    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;    ADC_InitStructure.ADC_NbrOfChannel = 1;    ADC_Init(ADC1, &ADC_InitStructure);    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);    ADC_Cmd(ADC1, ENABLE);    // Calibration    ADC_ResetCalibration(ADC1);    while(ADC_GetResetCalibrationStatus(ADC1));    ADC_StartCalibration(ADC1);    while(ADC_GetCalibrationStatus(ADC1));}

Step 3: DMA Configuration

#define ADC_BUFFER_SIZE 1000uint16_t ADC_ConvertedValue[ADC_BUFFER_SIZE];void DMA_Config(void){    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);    DMA_InitTypeDef DMA_InitStructure;    DMA_DeInit(DMA1_Channel1);    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue;    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;    DMA_InitStructure.DMA_BufferSize = ADC_BUFFER_SIZE;    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;    DMA_InitStructure.DMA_Priority = DMA_Priority_High;    DMA_Init(DMA1_Channel1, &DMA_InitStructure);    DMA_Cmd(DMA1_Channel1, ENABLE);    ADC_DMACmd(ADC1, ENABLE);}

Step 4: Start ADC

void Start_ADC(void){    ADC_SoftwareStartConvCmd(ADC1, ENABLE);}

5. Example of Main Function

int main(void){    ADC_GPIO_Config();  // Configure GPIO as analog input    DMA_Config();       // Configure DMA    ADC_Config();       // Configure ADC    Start_ADC();        // Start ADC sampling    while (1)    {        // Process data in ADC_ConvertedValue[]        // Can add filtering algorithms, data upload, display, etc.    }}

6. Operational Effects

  • The system can continuously and automatically acquire analog voltage signals;
  • Sampling data is stored in the memory array in real-time without CPU intervention;
  • CPU can be used for other tasks (such as serial communication, data display, control logic, etc.);
  • On the STM32F103 platform, a sampling rate of 1Msps (million samples per second) can be achieved, demonstrating powerful performance.

7. Common Issues and Debugging Tips

Issue Possible Cause Solution
All data is 0 DMA not enabled, ADC not started Check the startup sequence of DMA and ADC
Data offset or misalignment Buffer size or data alignment error Ensure <span>uint16_t</span> type matches ADC output
Data discontinuity DMA not set to Circular mode Set <span>DMA_Mode</span> to <span>DMA_Mode_Circular</span>
Interrupt not triggered DMA interrupt not configured or interrupt flag not cleared Configure the interrupt and clear the flag in the interrupt service function
Data lost too quickly Buffer too small, processing not timely Increase array size or improve processing speed

8. Knowledge Summary

Module Function Description
ADC Analog signal sampling Converts voltage analog signals into digital values
DMA Automatic data transfer Automatically transfers ADC conversion results to memory
CPU Control and data processing Initialization configuration, processing final results

9. Extension Suggestions

  • Use timer to trigger ADC sampling for precise periodic sampling;
  • Add DMA interrupt handling function to automatically process data upon completion of sampling;
  • Support multi-channel sampling: Enable <span>ScanConvMode</span> in conjunction with DMA for multi-channel buffering;
  • Filtering and averaging algorithms: Apply software filtering to sampled values to enhance stability;
  • Combine with RTOS or timed tasks: Implement a more complex multi-task processing structure.

Leave a Comment