当前位置:   article > 正文

stm32进行ADC采集时有关于滤波的技巧_stm32 adc 滤波

stm32 adc 滤波

        当我们利用stm32制作电压表时,需要利用stm32单片机内置12位的ADC进行AD采集然后转换成电压值来显示,但是此时我们遇到了一个问题——stm32单片机进行AD采集到的数据总是在个位十位数跳变,转换成电压值时也会显示一直变化,那我们该如何解决这个问题呢?

        首先来看我对ADC进行的配置。

  1. void ADC1_Init(void)
  2. {
  3. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
  4. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  5. RCC_ADCCLKConfig(RCC_PCLK2_Div6);//六分频
  6. GPIO_InitTypeDef GPIO_InitStruct;
  7. GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
  8. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_6;
  9. GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
  10. GPIO_Init(GPIOA,&GPIO_InitStruct);
  11. ADC_InitTypeDef ADC_InitStructure;
  12. ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//单次转换
  13. ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
  14. ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
  15. ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;
  16. ADC_InitStructure.ADC_NbrOfChannel=1;
  17. ADC_InitStructure.ADC_ScanConvMode=DISABLE;//非扫描模式
  18. ADC_Init(ADC1,&ADC_InitStructure);
  19. ADC_Cmd(ADC1,ENABLE);
  20. ADC_ResetCalibration(ADC1);
  21. while(ADC_GetResetCalibrationStatus(ADC1)==SET);
  22. ADC_StartCalibration(ADC1);
  23. while(ADC_GetCalibrationStatus(ADC1)==SET);
  24. }
  25. u16 Get_ADValue(u8 ADC_Channel)//用哪个通道采集就填哪个ADC通道
  26. {
  27. ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_239Cycles5);//规则组通道配置
  28. ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件转换
  29. while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);//等待AD转换
  30. return ADC_GetConversionValue(ADC1);
  31. }

        这里我们想到的是利用取平均值消出AD采集值的抖动,每采集一百次时用一百次采集到的AD值的总和减去100次采集中的最大值和最小值再除以98来实现,代码如下。

  1. u32 AD_Counter=0;
  2. u16 AD_MAX=0;
  3. u16 AD_MIN=4095;//为什么AD_MIN最大,AD_MAX最小呢?后文会为你解释明白
  4. u32 AD_SUM=0;
  5. u8 AD_Value;
  6. float Voltage;
  7. char ADC_Strings[];
  8. void Get_Voltage(u8 ADC_Channel)
  9. {
  10. AD_Value=Get_ADValue(ADC_Channel);
  11. if(AD_Value>AD_MAX) AD_MAX=AD_Value;
  12. if(AD_Value<AD_MIN) AD_MIN=AD_Value;
  13. AD_Counter++;
  14. AD_SUM=AD_SUM+AD_Value;//储存AD采集的数值
  15. if(AD_Counter==100) //AD采集次数=100时
  16. {
  17. AD_Value=(AD_SUM-AD_MAX-AD_MIN)/(AD_Counter-2);//求平均值
  18. AD_Counter=0;
  19. AD_MAX=0;
  20. AD_MIN=4095;
  21. AD_SUM=0;
  22. Voltage=(float)AD_Value/4096*3.3;//将采集到的AD转换成电压
  23. sprintf(ADC_Strings,"%1.2f",Voltage);
  24. lcd_w_const_str(1,5,ADC_Strings);
  25. }
  26. }

        我们将此函数放到主函数的循环中,在对应开通的ADC通道的引脚接入外部电路测量即可(记得要共地)。

电压测量

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/236656
推荐阅读
相关标签
  

闽ICP备14008679号