DMA + 多路ADC + 定时器 + 均值滤波实现

DMA + 多路ADC + 定时器 + 均值滤波实现

基于STM32微控制器的DMA、多路ADC、定时器和均值滤波的实现,适用于高效数据采集和处理。

1. 硬件连接

将待采集的模拟信号连接到STM32的ADC通道引脚,确保电源和地连接正常。

2. 软件配置

2.1 时钟配置

使能ADC、DMA和GPIO的时钟。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
2.2 GPIO配置

将ADC通道对应的引脚设置为模拟输入模式。

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
2.3 ADC配置

配置ADC为多通道扫描模式,设置分辨率和采样时间。

ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_NbrOfChannel = 4;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_Init(ADC1, &ADC_InitStructure);

ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);
2.4 DMA配置

配置DMA传输源地址(ADC数据寄存器)、目标地址(内存缓冲区)、传输数据量和传输方向。

DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(ADC1->DR));
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 4;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
2.5 定时器配置

配置定时器以周期性触发ADC转换。

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 9999;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
2.6 均值滤波算法

对采集到的数据进行均值滤波处理,以减少噪声。

#define FILTER_SIZE 10
uint16_t filterBuffer[FILTER_SIZE] = {0};
uint16_t filterIndex = 0;

uint16_t applyMeanFilter(uint16_t newValue) {
    filterBuffer[filterIndex] = newValue;
    filterIndex = (filterIndex + 1) % FILTER_SIZE;

    uint32_t sum = 0;
    for (int i = 0; i < FILTER_SIZE; i++) {
        sum += filterBuffer[i];
    }
    return sum / FILTER_SIZE;
}

3. 数据采集与处理

在主循环中启动ADC采集,并通过DMA传输数据。使用定时器触发ADC转换,并在DMA传输完成后处理数据。

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_ADC1_Init();
    MX_TIM2_Init();

    uint16_t adcValues[4];

    while (1) {
        HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adcValues, 4);
        HAL_Delay(1000);

        // 处理采集到的数据
        for (int i = 0; i < 4; i++) {
            uint16_t filteredValue = applyMeanFilter(adcValues[i]);
            // 使用filteredValue进行进一步处理
        }
    }
}

参考代码 DMA+多路ADC+定时器+均值滤波 www.youwenfan.com/contentcse/102475.html

4. 项目特点

基于STM32的DMA、多路ADC、定时器和均值滤波的数据采集系统,适用于多种应用场景,如环境监测、工业控制和嵌入式数据采集。

专注于matlab/simulink,电子电路,编程