STM32 DMA模式 ADC采集多通道数据 DMA使用二维数组 HAL库程序
时间: 2025-06-05 11:27:08 浏览: 11
### STM32 HAL库实现ADC多通道数据采集并存储到二维数组的示例代码
以下是一个完整的STM32 HAL库实现多通道ADC数据采集,并将数据存储到二维数组中的示例代码。该代码展示了如何通过DMA传输从多个ADC通道采集数据,并将结果存储到二维数组中。
#### 示例代码
```c
#include "stm32f4xx_hal.h"
// 定义全局变量
#define ADC_CHANNEL_COUNT 4 // 定义ADC通道数量
#define BUFFER_SIZE 10 // 每个通道的数据缓冲区大小
uint16_t ADValue[BUFFER_SIZE][ADC_CHANNEL_COUNT]; // 存储ADC采集值的二维数组
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_DMA_Init(void);
int main(void)
{
HAL_Init(); // 初始化HAL库
SystemClock_Config(); // 配置系统时钟
MX_GPIO_Init(); // 初始化GPIO
MX_ADC1_Init(); // 初始化ADC1
MX_DMA_Init(); // 初始化DMA
// 启动ADC DMA采集,将数据存储到二维数组中
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&ADValue[0][0], BUFFER_SIZE * ADC_CHANNEL_COUNT);
while (1)
{
for (int i = 0; i < BUFFER_SIZE; i++)
{
for (int j = 0; j < ADC_CHANNEL_COUNT; j++)
{
printf("Buffer[%d][Channel%d]: %d\r\n", i, j, ADValue[i][j]); // 输出每个缓冲区和通道的采集值
}
}
HAL_Delay(500); // 延时500ms
}
}
// ADC初始化函数(由CubeMX生成)
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PREScaler_2;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE; // 启用扫描模式
hadc1.Init.ContinuousConvMode = ENABLE; // 启用连续转换模式
hadc1.Init.DMAContinuousRequests = ENABLE; // 启用DMA连续请求
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
HAL_ADC_Init(&hadc1);
// 配置ADC通道
sConfig.Channel = ADC_CHANNEL_0; // 通道0
sConfig.Rank = 1; // 排序1
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_1; // 通道1
sConfig.Rank = 2; // 排序2
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_2; // 通道2
sConfig.Rank = 3; // 排序3
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_3; // 通道3
sConfig.Rank = 4; // 排序4
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
// DMA初始化函数(由CubeMX生成)
void MX_DMA_Init(void)
{
__HAL_RCC_DMA2_CLK_ENABLE();
hdma_adc1.Instance = DMA2_Stream0;
hdma_adc1.Init.Channel = DMA_CHANNEL_0;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR; // 循环模式
hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&hdma_adc1);
__HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);
}
```
#### 配置细节
- 在`MX_ADC1_Init`函数中,启用了扫描模式和连续转换模式,确保可以同时采集多个通道的数据[^1]。
- 在`MX_DMA_Init`函数中,DMA模式设置为循环模式(`DMA_CIRCULAR`),以便持续采集数据并将其存储到指定的缓冲区中[^1]。
- `HAL_ADC_Start_DMA`函数用于启动DMA传输,参数包括ADC句柄、目标缓冲区地址以及要采集的样本总数(缓冲区大小乘以通道数)[^1]。
- 使用二维数组`ADValue`来存储每个通道的采集数据,其中第一维表示缓冲区索引,第二维表示通道索引[^2]。
#### 注意事项
- 确保采样时间足够长以满足ADC转换需求[^1]。
- 如果需要对采集到的数据进行进一步处理,可以在`while (1)`循环中实现相关逻辑。
- 使用循环模式(`Circular Mode`)时,确保缓冲区大小与ADC通道数量匹配,避免数据覆盖或丢失。
阅读全文
相关推荐
















