濾波處理,首先提幾個問題:為什么要濾波?濾波的方式有那么多有什么作用?分別的應用場合是什么?
下面就開始濾波的說明和代碼了!
一:移動平滑濾波:
該濾波方法為:采用最新的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 }
