ADC采集完数据后,如何写程序滤除50hz工频干扰啊

2019-07-20 08:22发布

#include "stm32f4xx.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "oled.h"
#include "adc2.h"
#include "dma.h"
#include "math.h"
//本例程的OLED中的CE(部分厂家引脚标注为CS)引脚已接地,如果是7线引脚,将CE引脚直接接GND即可使用

int main(void)
{        
   __IO uint16_t uhADCxConvertedValue = 0;
   __IO uint32_t uwADCxConvertedVoltage = 0;

        u16 temp;
        u16 adxe;
  u16 i;
         u16 count;
        u16 charge;
        //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        delay_init(168);                     //延时函数初始化
        uart_init(115200);

        OLED_Init();
        OLED_Clear();
         
         

        ADC2_Init();
        DMA4_Init(DMA2_Stream0,DMA_Channel_0,(u32)&ADC1->DR,(u32)&uhADCxConvertedValue,1);
        DMA4_Enable(DMA2_Stream0,1);
         

         OLED_ShowString(0,0,"CH0VAL:");
        OLED_ShowString(0,2,"VOL:        V");

        while(1)
        {               
                //使用ADC 直接在OLED上显示
                temp=GET_ADC_Average(ADC_Channel_5,20);
          OLED_ShowNum(60,0,temp,4);
                adxe=(float)temp*(3.3/4096);          //获取计算后的带小数的实际电压值,比如3.1111

                OLED_ShowNum(30,2,adxe,1);
                OLED_ShowChar(38,2,'.');
                temp-=adxe;
                temp*=1000;
                OLED_ShowNum(42,2,temp,5);
                delay_ms(250);
}               

#include "stm32f4xx.h"
#include "adc2.h"
#include "dma.h"
#include  "delay.h"


void ADC2_Init(void)
{
        GPIO_InitTypeDef  GPIO_InitStruct;
        ADC_CommonInitTypeDef  ADC_CommonInitStruct;
        ADC_InitTypeDef  ADC_InitStruct;
       
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
       
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AN;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
        GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;//配置为不带上下拉
        GPIO_Init(GPIOA,&GPIO_InitStruct);

        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);//ADC1复位
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);//复位结束
       
        ADC_CommonInitStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_1;//开启ADC_DMA传输模式
        ADC_CommonInitStruct.ADC_Mode=ADC_Mode_Independent;//设置ADC为独立模式,即一个ADC单独工作
        ADC_CommonInitStruct.ADC_Prescaler=ADC_Prescaler_Div4;
        ADC_CommonInitStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;//设置ADC的延时周期数
        ADC_CommonStructInit(&ADC_CommonInitStruct);
       
       
        ADC_InitStruct.ADC_ContinuousConvMode=ENABLE;//设置连续转化模式
        ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//设置对其方式为右对齐
        ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;
        ADC_InitStruct.ADC_NbrOfConversion=1;
        ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;//设置ADC转换分辨率为12位
        ADC_InitStruct.ADC_ScanConvMode=DISABLE;//不开启扫描模式
        ADC_Init(ADC1,&ADC_InitStruct);
       
       
        //ADC_RegularChannelConfig(ADC1,ADC_Channel_5,1,ADC_SampleTime_480Cycles); //相当于控制多路DMA通道的顺序
        //ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE);//发送一组DMA数据后立即申请DMA请求
        ADC_Cmd(ADC1,ENABLE);//开启A/D转换器
// ADC_DMACmd(ADC1,ENABLE);//开启ADC_DMA传输
        //ADC_SoftwareStartConv(ADC1);//启动ADC1的软件转换功能
       
}

/*获取ADC通道
  ch 为通道值
  返回值:转换结果
*/
u16  GET_ADC(u8 ch)
{
                ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_480Cycles);//使能规则转换
          ADC_SoftwareStartConv(ADC1);//使能指定的ADC1的软件转换启动功能
    while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==0);//等待转换完成
         return ADC_GetConversionValue(ADC1);

}

u16 GET_ADC_Average(u8 ch,u8 times)
{
                        u32 temp=0;
                        u8 t=0;
                        for(t=0;t<times;t++)
                        {
                                 temp+=GET_ADC(ch);
                                 delay_ms(5);
                        }
                        return temp/times;
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。