对AD采样信号的简单滤波处理

总体说明一下:这个函数只是将采集的正弦序列的值逼近于标准的正弦序列,标准正弦序列随着你的AD转换器的位数而改变,不同的波形也会使标准序列发生改变,这里只是论述一下方法而已。

/**
  * @brief  This function makes the sample value of AD closer to the normal sine wave.By defining a predetermined sine array, the AD sample value approximates to the sine array.
  * @param  xn: The AD samples values

        param  num: The number of elements in the sampled value array

        param  yn: Output sequence after processing

        param  num_of_return: Number of output sequences

  * @retval None
  */

//标准正弦序列,由正弦函数产生,当然也可以弄成标准的三角波序列。我这里用的是12位的AD,所以从序列值域0---4095

 

int sin_data[501]={4095,4095,4095,4095,4094,4094,4094,4093,4092,4092,4091,4090,4089,4088,4087,4086,4085,4083,4082,4080,4079,4077,4076,4074,4072,4070,4068,4066,4064,4061,4059,4056,4054,4051,4049,4046,4043,4040,4037,4034,4031,4028,4024,4021,4018,4014,4010,4007,4003,3999,3995,3991,3987,3983,3979,3974,3970,3966,3961,3956,3952,3947,3942,3937,3932,3927,3922,3917,3912,3906,3901,3895,3890,3884,3878,3873,3867,3861,3855,3849,3843,3837,3830,3824,3817,3811,3804,3798,3791,3784,3777,3771,3764,3757,3749,3742,3735,3728,3720,3713,3705,3698,3690,3683,3675,3667,3659,3651,3643,3635,3627,3619,3610,3602,3594,3585,3577,3568,3560,3551,3542,3533,3525,3516,3507,3498,3488,3479,3470,3461,3452,3442,3433,3423,3414,3404,3394,3385,3375,3365,3355,3345,3336,3326,3315,3305,3295,3285,3275,3264,3254,3244,3233,3223,3212,3202,3191,3180,3170,3159,3148,3137,3126,3115,3104,3093,3082,3071,3060,3049,3038,3026,3015,3004,2992,2981,2970,2958,2947,2935,2923,2912,2900,2888,2877,2865,2853,2841,2830,2818,2806,2794,2782,2770,2758,2746,2734,2722,2709,2697,2685,2673,2661,2648,2636,2624,2611,2599,2587,2574,2562,2549,2537,2525,2512,2500,2487,2474,2462,2449,2437,2424,2411,2399,2386,2374,2361,2348,2335,2323,2310,2297,2284,2272,2259,2246,2233,2221,2208,2195,2182,2169,2157,2144,2131,2118,2105,2092,2080,2067,2054,2041,2028,2015,2003,1990,1977,1964,1951,1938,1926,1913,1900,1887,1874,1862,1849,1836,1823,1811,1798,1785,1772,1760,1747,1734,1721,1709,1696,1684,1671,1658,1646,1633,1621,1608,1595,1583,1570,1558,1546,1533,1521,1508,1496,1484,1471,1459,1447,1434,1422,1410,1398,1386,1373,1361,1349,1337,1325,1313,1301,1289,1277,1265,1254,1242,1230,1218,1207,1195,1183,1172,1160,1148,1137,1125,1114,1103,1091,1080,1069,1057,1046,1035,1024,1013,1002,991,980,969,958,947,936,925,915,904,893,883,872,862,851,841,831,820,810,800,790,780,769,759,750,740,730,720,710,701,691,681,672,662,653,643,634,625,616,607,597,588,579,570,562,553,544,535,527,518,510,501,493,485,476,468,460,452,444,436,428,420,412,405,397,390,382,375,367,360,353,346,338,331,324,318,311,304,297,291,284,278,271,265,258,252,246,240,234,228,222,217,211,205,200,194,189,183,178,173,168,163,158,153,148,143,139,134,129,125,121,116,112,108,104,100,96,92,88,85,81,77,74,71,67,64,61,58,55,52,49,46,44,41,39,36,34,31,29,27,25,23,21,19,18,16,15,13,12,10,9,8,7,6,5,4,3,3,2,1,1,1,0,0,0};


//yn肯定不能在主函数中声明其大小

void Filter_Me(int *xn,int num,int* yn,int*num_of_return)
{
  int i,start,end,length,j,flag;
  for(i=1;i<num;i++)
  {
    if(xn[i]>xn[i-1] && xn[i]>xn[i+1])
    {
      xn[i]=4095;
    }
    else if(xn[i]<xn[i-1] && xn[i]<xn[i+1])
    {
      xn[i]=0;
    }
    else
    {

    }
  }
  //求起始点
  for(i=0;i<num;i++)
  {
    if(xn[i]==4095 || xn[i]==0)
    {
      start=i;
      flag=start;
      break;
    }
  }
  //处理
  while(i<num)
  {
    if(xn[i]==0)
    {
      start=i;
      if(start>num)break;
      while(xn[i]!=4095)
      {
        i++;
        if(i>num)
        {
          break;
        }
      }
      end=i;
      if(end>num)break;
      length=end-start;
      length=500/length;
      for(j=start+1;j<end;j++)
      {
        xn[j]=sin_data[500-length*(j-start)];
      }
      i=j;
    }
    else
    {
      start=i;
      if(start>num)break;
      while(xn[i]!=0)
      {
        i++;
        if(i>num)
        {
          break;
        }
      }
      end=i;if(end>num)break;
      length=end-start;
      length=500/length;
      for(j=start+1;j<end;j++)
      {
        xn[j]=sin_data[length*(j-start)];
      }
      i=j;
    }

  }
  *num_of_return=start-flag;
  for(i=0;i<start-flag;i++)
  {
    yn[i]=xn[i+flag];
  }

}

 

主函数检测:

int main(void)
{
  int i,num;
  int xn[64]={2448,2600,3300,3496,3751,3800,4057,4095,4057,3940,
    3751,3496,3186,2832,2448,2048,1648,1264,910,600,345,
    156,39,0,39,156,345,600,800,1264,1648,2048,
    2448,2832,3186,3496,3751,3940,4057,4095,4057,3940,
    3751,3496,2900,2832,2448,2200,1648,1264,910,600,345,
    156,39,0,39,156,345,600,910,1000,1648,2048};
  int yn[]={0};
  Filter_Me(xn,64,yn,&num);
  for(i=0;i<num;i++)
  printf("%d\r\n",yn[i]);
}

这是未处理的xn:

 

输出yn:

 

由于excel会自动拟合曲线,所以当打在示波器上时会发生失真,应该加平滑滤波器使信号拟合一下,另外提一下,采集的数据xn[]至少在数值上有个增大减小的趋势,如果采集的就不行,就不要怪我这函数写的不咋地,当然写的的确也不咋的,没啥技术含量哈哈,只是写来玩玩,或许对信号处理有点帮助吧。


 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
STM8S 是一种微控制器系列,它具有模拟到数字转换器(ADC)功能,用于对模拟信号进行采样和转换为数字信号。在STM8S上实现AD采样滤波算法有很多种方法,下面我将介绍一种常见的算法。 第一步是设置ADC的参数。我们可以选择采样速率、参考电压和采样分辨率等参数,以适应应用的需求。 第二步是初始化ADC。这包括设置引脚和模式,并启用ADC模块。 第三步是开始AD转换。通过启动ADC转换,并等待转换完成的标志位。 第四步是获取转换结果。读取ADC的数据寄存器,获取转换后的数字值。 第五步是进行滤波。我们可以使用不同的滤波算法来处理采样数据,如移动平均滤波、中值滤波或卡尔曼滤波等。这些算法可以根据应用的需求选择适当的方法。 最后一步是根据需要重复以上步骤。我们可以设置一个循环来连续进行AD采样滤波,以获取连续的数据流。 需要注意的是,选择适当的采样速率和滤波算法非常重要。过高的采样速率可能会浪费系统资源,而过低的采样速率可能会导致数据丢失或失真。滤波算法的选择应根据应用的实际需求和性能要求进行权衡。 总结起来,STM8S上的AD采样滤波算法需要经过设置参数、初始化ADC、开始转换、获取结果和滤波处理等步骤,以获取满足应用需求的高质量数字信号。这是一种常见的实现方法,具体的细节会根据具体的应用和系统要求进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GallagherZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值