STM32F4四路ADC采样问题探讨

来源:互联网 发布:excel单元格内换行 mac 编辑:程序博客网 时间:2024/06/06 04:14

1.ADC配置

**####1.1模式确定

1.1.1 主从模式,选择主ADC1模式带动从ADC2模式**

ADC模式
交替模式
1.1.2 对应代码段:

    /* Enable DMA request after last transfer (Multi-ADC mode)  */    ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

####1.2 时钟初始化ADC
ADC时钟挂在APB2上,这里程序配置为168MHz

    RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);    RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);    RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,ENABLE);    RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,DISABLE);

1.3 引脚选择和初始化

#####1.3.1引脚
这里的ADC是加DMA的,需要根据DMA和ADC相关默认引脚来选择
简化来说 PC0–ADC通道10,PC1–ADC通道11…
选定相应引脚

#####1.3.2 初始化配置

    ADC_Init(ADC2, &ADC_InitStructure);/* ADC2 regular channel5 configuration ****************/    ADC_RegularChannelConfig(ADC2,ADC_Channel_13,1,ADC_SampleTime_15Cycles);       //PC3/* ADC1 regular channel5 configuration ************/    ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 2, ADC_SampleTime_15Cycles);     //PA3    ADC_Init(ADC1, &ADC_InitStructure);     /* ADC1 regular channel5 configuration ****************/    ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_15Cycles);     //PC2    /* ADC1 regular channel5 configuration ******************/    ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_15Cycles);      //PA5...    ADC_Cmd(ADC1, ENABLE)    ADC_Cmd(ADC2, ENABLE);

2.DMA配置

####2.1初始化
2.1.1确定数据流,这里F4系列的开发板有3个ADC
DMA2
####2.2程序配置

/* DMA2 Stream0 channel2 configuration */DMA_InitStructure.DMA_Channel = DMA_Channel_0;  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_DR_ADDRESS;DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)aADCConvertedValue;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;DMA_InitStructure.DMA_BufferSize = ADC_BUF_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_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;DMA_Init(DMA2_Stream0, &DMA_InitStructure);DMA_Cmd(DMA2_Stream0, ENABLE);

3.滤波平均

####3.1一般滤波方法
这里尝试过其他一些滤波方法,加权滤波,中值滤波,滑动滤波方法,在大数据量下,排序消耗时间和占用资源都比较不好,经测试,一般滤波方法比较好。

u32 adc_filter(u32 cnt,u32 adc_num_value){    u8 i;    u32 adc_min=0,adc_max=0;    u32 adc_sum=0,adc_ave=0;    for(i=0;i<cnt;i++)    {            adc_sum += adc_num_value;            adc_min=adc_num_value;            adc_max=adc_num_value;        if(adc_num_value<=adc_min)            adc_min=adc_num_value;        if(adc_num_value>=adc_max)            adc_max=adc_num_value;    }    adc_sum -= (adc_max+adc_min);       adc_ave=adc_sum/(cnt-2);    adc_sum=0;    return adc_ave;}

####3.2 采样计算求值
根据之前规定的组合依次可计算出各采样值,这里优化了浮点计算方法

u8 j,k;u32 adc_getvalue[4];memset(&adc_getvalue,0,sizeof(adc_getvalue));for(j=0;j<40;j++){    for(k=0;k<4;k++)    adc_getvalue[k] += adc_filter(8,aADCConvertedValue[k]);}//PC3--[1] PC1--[3] PC2--[0] PA5--[2]voltage1_calculate= (float)adc_getvalue[0]*33/(400*4096);voltage2_calculate= (float)adc_getvalue[1]*33/(400*4096);current1_calculate= (float)adc_getvalue[2]*33/(400*4096);current2_calculate= (float)adc_getvalue[3]*33/(400*4096);memset(&adc_getvalue,0,sizeof(adc_getvalue));//减少线差adc_voltage1=voltage1_calculate;adc_voltage2=voltage2_calculate;adc_current1=current1_calculate;adc_current2=current2_calculate;            

这里相关配置就可以结束了,需注意的是,计算采样时需要定义数组,数组类型也有明确要求。这里附上程序配置相关文件。