滤波处理,首先提几个问题:为什么要滤波?滤波的方式有那么多有什么作用?分别的应用场合是什么?
下面就开始滤波的说明和代码了!
一:移动平滑滤波:
该滤波方法为:采用最新的N个数据的平均值。N为恒定值。
那么问题来了:
在初始采样平均值该如何处理?X1/N?还是第一次采样将N个数据全填充为X1?然后开始计算?还是在第一遍采样中,X1/1,(X1+X2)/2,(X1+...+X(n-1))/(N-1)的方式?直到最少获取了N个采样结果以后,在利用(Xn+...X(2n-1))/N的方式进行滤波?
下面就对两种进行简单的分析,当然,有几种不同的处理方式。
第一种处理,使用了如下的全局变量;
1.N个元素数组的全局变量;
2.循环位标记符;
3.初次采样未满足采样数据标记值;
采用的为:
X1/1,(X1+X2)/2,(X1+...+X(n-1))/(N-1)的方式;
代码可以直接测试。
1 #include <stdio.h> 2 3 /* DEFINE */ 4 #define N (6) 5 /* Gs */ 6 /* Value */ 7 static int a[N] = {0}; 8 /* Pointer */ 9 static int i = 0; 10 /* Flag for First Cycle */ 11 static int flag = 0; 12 13 int main(void) 14 { 15 int sum = 0; /* Init Sum Value */ 16 int avg = 0; /* Init Avg Value */ 17 int Index = 0; /* Init Index for Loop */ 18 printf("在输入的数字后面紧跟';'号,表示输入结束\n"); 19 do{ 20 if(0 == flag) 21 { 22 printf("输入%d个数据:",i+1); 23 scanf("%d",&a[i++]); 24 if(N == i) 25 { 26 flag = 1; 27 } 28 } 29 else 30 { 31 if(N == i) 32 { 33 i = 0; 34 } 35 printf("输入%d个数据:",i+1); 36 scanf("%d",&a[i++]); 37 } 38 39 }while(getchar()!=';'); /* Get ";" break */ 40 41 if(0 == flag) 42 { 43 for(Index=0; Index<i; Index++) 44 { 45 sum += a[Index]; 46 } 47 avg = sum/i; 48 } 49 else 50 { 51 for(Index=0; Index<N; Index++) 52 { 53 sum += a[Index]; 54 } 55 avg = sum / N; 56 } 57 printf("平均值为%d\n",avg); 58 }
第二种方式:
采用获取到的第一次的值,将数据获取Buffer全填充。故不用以上这么复杂。
全局变量:
1.Buffer
2.first Vale Flag
以下为代码:
1 #include <stdio.h> 2 3 /* DEFINE */ 4 #define N (6) 5 /* Gs */ 6 /* Value */ 7 static int a[N] = {0}; 8 /* Flag for First Value */ 9 static int flag = 0; 10 11 int main(void) 12 { 13 int sum = 0; /* Init Sum Value */ 14 int avg = 0; /* Init Avg Value */ 15 int Index = 0; /* Init Index for Loop */ 16 int Temp_First = 0; 17 printf("在输入的数字后面紧跟';'号,表示输入结束\n"); 18 do{ 19 if(0 == flag) 20 { 21 printf("输入数据:"); 22 scanf("%d",&a); 23 for(Index = 1; Index < N; Index++) 24 { 25 a[Index] = a[0]; 26 } 27 flag = 1; 28 } 29 else 30 { 31 for(Index = 0; Index < N - 1; Index++) 32 { 33 a[Index] = a[Index + 1]; 34 } 35 printf("输入数据:"); 36 scanf("%d",&a[N-1]); 37 } 38 39 }while(getchar()!=';'); /* Get ";" break */ 40 41 for(Index=0; Index<N; Index++) 42 { 43 sum += a[Index]; 44 } 45 avg = sum / N; 46 printf("平均值为%d\n",avg); 47 }
方法二也可以借用一中的循环标记位“i”,那样的话,就省去了代码31L中的for循环,但会增加一个全局变量来表示当前“挤掉”的值,依个人喜好吧!
二:判断值是否稳定:
经常会遇到判断二值是否稳定的情况,这里可以有如下的方法:
1.实时获取当前值;
2.保存上一次获取的值;
3.判断稳定了多少个数据点;
4.稳定标准。
以下为代码,main函数部分没有编写,具体的可以参照上面的方式进行扩充。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 5 /* define Filter Time Count - 1 */ 6 #define FILTER_COUNT (9) 7 8 /* 定义结构 */ 9 typedef struct{ 10 int Value_Last; /* 实时保存当前值 */ 11 int Value_Out; /* 存储滤波以后的值 */ 12 int TimeCnt; /* 记录当前所处滤波次数,为0表示稳定 */ 13 int TimeCntMax; /* 设定需要滤波次数 */ 14 }DATA_t; 15 16 static DATA_t gs_testValue; /* 设定全局变量 */ 17 18 void Filter_Buf(void); /* 函数定义 */ 19 20 /* main */ 21 int main(void) 22 { 23 printf("有兴趣可以测试一下:\n"); 24 /* 类似于上面几个例子的循环输入和退出 */ 25 /* 26 * 若需要获取稳定后的值,只需要 gs_testValue.Value_Out 就可以了. 27 * 若想知道当前是否稳定,判断 gs_testValue.TimeCnt 就可以了. 28 */ 29 } 30 31 void Filter_Fun(void) 32 { 33 int Temp = 0; 34 /* Get Value */ 35 Temp = Read_Value(); 36 if(gs_testValue.Value_Last != Temp) /* Last is not Equ Now */ 37 { 38 gs_testValue.Value_Last = Temp; /* New Value */ 39 gs_testValue.TimeCnt = gs_testValue.TimeCntMax; /* Re Start */ 40 } 41 else 42 { 43 if(0 == gs_testValue.TimeCnt) /* stable */ 44 { 45 gs_testValue.Value_Out = gs_testValue.Value_Last; /* Change Stable Value */ 46 } 47 else 48 { 49 if(gs_testValue.TimeCntMax < gs_testValue.TimeCnt) /* if Filter Time Change */ 50 { 51 gs_testValue.TimeCnt = gs_testValue.TimeCntMax; 52 } 53 else 54 { 55 gs_testValue.TimeCnt--; 56 } 57 } 58 } 59 } 60 61 int Read_Value(void) 62 { 63 srand((int)time(0)); /* Time for srand */ 64 srand(rand()%100); /* 0-100 for srand */ 65 return (rand()%2); /* 0/1 */ 66 }