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:
- CPU initializes and configures ADC and DMA
- Start ADC sampling
- After ADC completes one sampling, it automatically triggers DMA transfer
- DMA transfers data to the preset memory array
- When the sampling reaches the set quantity, DMA triggers an interrupt to notify the CPU
- 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.