stm32F407多通道ADC DMA采集代码hal库
时间: 2025-05-24 10:52:52 浏览: 28
### 使用HAL库实现STM32F407多通道ADC DMA采集
以下是基于HAL库实现STM32F407多通道ADC DMA采集的完整代码示例。此代码涵盖了ADC初始化、DMA传输以及数据处理的部分。
#### 初始化部分
在`main.c`中完成ADC和DMA的相关配置:
```c
#include "stm32f4xx_hal.h"
#define FILTER_WIDTH 16 // 滤波窗口大小
#define NUM_CHANNELS 4 // ADC通道数量
// 定义存储ADC采样的数组
uint16_t AdcValues[NUM_CHANNELS * FILTER_WIDTH];
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC3_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC3_Init();
// 启动DMA模式下的ADC转换
HAL_ADC_Start_DMA(&hadc3, (uint32_t*)AdcValues, NUM_CHANNELS * FILTER_WIDTH);
while (1)
{
// 主循环可以用于其他任务
}
}
/**
* @brief ADC3 Initialization Function
*/
static void MX_ADC3_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc3.Instance = ADC3;
hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; // 设置时钟分频
hadc3.Init.Resolution = ADC_RESOLUTION_12B; // 设置分辨率为12位
hadc3.Init.ScanConvMode = ENABLE; // 开启扫描模式
hadc3.Init.ContinuousConvMode = ENABLE; // 连续转换模式
hadc3.Init.DMAContinuousRequests = ENABLE; // 启用连续DMA请求
hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV; // 结束标志选择序列结束
if (HAL_ADC_Init(&hadc3) != HAL_OK)
{
Error_Handler(); // 错误处理函数
}
// 配置具体使用的ADC通道
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; // 温度传感器通道
sConfig.Rank = 1; // 排序优先级
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; // 转换时间设置为3周期
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_1; // 额外的模拟输入通道
sConfig.Rank = 2;
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
Error_Handler();
}
// 可以继续添加更多通道...
}
```
以上代码完成了以下功能:
- **ADC初始化**:设置了分辨率、时钟分频器、扫描模式等参数[^2]。
- **DMA启用**:通过`HAL_ADC_Start_DMA()`启动了DMA传输,将采集到的数据存入指定缓冲区 `AdcValues` 中[^3]。
- **多通道支持**:通过调用多次`HAL_ADC_ConfigChannel()`方法来定义多个ADC通道并分配其顺序[^4]。
#### 数据处理部分
为了进一步利用这些数据,在程序运行期间可以通过中断或其他方式读取已保存至内存中的样本值,并对其进行必要的计算或过滤操作。例如简单的平均滤波算法如下所示:
```c
float CalculateAverage(uint16_t* data, uint8_t num_samples_per_channel)
{
float sum = 0;
for (int i = 0; i < num_samples_per_channel; ++i)
{
sum += *(data + i);
}
return sum / num_samples_per_channel;
}
// 在适当位置调用该函数
for (size_t channel_index = 0; channel_index < NUM_CHANNELS; ++channel_index)
{
printf("Channel %d Average Value: %.2f\n",
channel_index,
CalculateAverage(AdcValues + channel_index * FILTER_WIDTH, FILTER_WIDTH));
}
```
上述代码实现了每条通道上的简单算术平均运算[^1]。
---
###
阅读全文
相关推荐


















