总体说明一下:这个函数只是将采集的正弦序列的值逼近于标准的正弦序列,标准正弦序列随着你的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[]至少在数值上有个增大减小的趋势,如果采集的就不行,就不要怪我这函数写的不咋地,当然写的的确也不咋的,没啥技术含量哈哈,只是写来玩玩,或许对信号处理有点帮助吧。