1 //1.限幅濾波法(又稱程序判斷濾波法) 2 /* 3 * description: 根據經驗判斷,確定兩次采樣允許的最大偏差值(設為A), 4 * 每次檢測到新值時判斷:新值和舊值差值如果超過A, 5 * 則用舊值,否則用新值 6 * advantage: 能夠克服因偶然因素引起的脈沖干擾 7 * disadvantage: 無法抑制那種周期性的干擾,平滑度差 8 */ 9 /* A值可根據實際情況調整 10 value為有效值,new_value為當前采樣值 11 濾波程序返回有效的實際值 */ 12 #define A 10 13 14 char value; 15 16 char filter() 17 { 18 char new_value; 19 new_value = get_ad(); 20 if ( ( new_value - value > A ) || ( value - new_value > A ) 21 return value; 22 return new_value; 23 24 } 25 26 27 //2.中位值濾波法 28 /* 29 * description: 連續采樣N次(N取奇數),把N次采樣值按大小排列, 30 * 取中間值為本次有效值 31 * advantage: 能夠有效克服偶然因素引起的波動干擾, 32 * 對溫度、液位等變化緩慢的被測參數有良好的濾波效果 33 * disadvantage: 對流量、速度等快速變化的參數不宜 34 */ 35 /* N值可根據實際情況調整 36 排序采用冒泡法*/ 37 #define N 11 38 39 char filter() 40 { 41 char value_buf[N]; 42 char count,i,j,temp; 43 for ( count=0;count<N;count++) 44 { 45 value_buf[count] = get_ad(); 46 delay(); 47 } 48 for (j=0;j<N-1;j++) 49 { 50 for (i=0;i<N-j;i++) 51 { 52 if ( value_buf[i]>value_buf[i+1] ) 53 { 54 temp = value_buf[i]; 55 value_buf[i] = value_buf[i+1]; 56 value_buf[i+1] = temp; 57 } 58 } 59 } 60 return value_buf[(N-1)/2]; 61 } 62 63 64 //3.算數平均濾波法 65 /* 66 * description: 連續取N個采樣值進行算數平均運算, 67 * N值較大時:信號平滑度較高,但靈敏度較低; 68 * N值較小時:信號平滑度較低,但靈敏度較高; 69 * N值的選取:一般流量,N=12,壓力:N=4 70 * advantage: 適用於對一般具有隨機干擾的信號進行濾波, 71 * 這樣的信號的特點是有一個平均值,信號在某一個數值范圍附近上下波動 72 * disadvantage: 對於測量速度較慢或要求數據計算速度較快的實時控制不適用,比較浪費ram 73 */ 74 #define N 12 75 76 char filter() 77 { 78 int sum = 0; 79 for ( count=0;count<N;count++) 80 { 81 sum + = get_ad(); 82 delay(); 83 } 84 return (char)(sum/N); 85 } 86 87 88 //4.遞推平均濾波法(滑動平均濾波法) 89 /* 90 * description: 把連續取N個采樣值看成一個隊列,隊列的長度固定為N, 91 * 每次采樣到一個新數據放入隊尾,並扔掉原來隊首的一次數據(先入先出原則), 92 * 把隊列中的N個數據進行算術平均運算,就可獲得新的濾波結果 93 * N值的選取:流量,N=12;壓力:N=4;液面,N=4~12;溫度:N=1~4 94 * advantage: 對周期性干擾有良好的抑制作用,平滑度高,適用於高頻震盪的系統 95 * disadvantage: 靈敏度低,對偶然出現的脈沖性干擾的抑制作用較差, 96 * 不易消除由於脈沖干擾所引起的采樣值偏差, 97 * 不適用於脈沖干擾比較嚴重的場合,比較浪費ram 98 */ 99 #define N 12 100 101 char value_buf[N]; 102 char i=0; 103 104 char filter() 105 { 106 char count; 107 int sum=0; 108 value_buf[i++] = get_ad(); 109 if ( i == N ) 110 111 { 112 113 i = 0; 114 115 } 116 for ( count=0;count<N,count++) 117 118 { 119 120 sum = value_buf[count]; 121 122 } 123 return (char)(sum/N); 124 } 125 126 127 //5.中位值平均濾波法(又稱防脈沖干擾平均濾波法) 128 /* 129 * description: 相當於“中位值濾波法”+“算數平均濾波法” 130 * 連續采樣N個數據,去掉一個最大值和一個最小值, 131 * 然后計算N-2個數據的算數平均值,N值的選取:3~14 132 * advantage: 融合了兩種濾波法的優點,對於偶然出現的脈沖性干擾, 133 * 可消除由於脈沖干擾所引起的采樣值偏差 134 * disadvantage: 測量速度較慢,和算數平均濾波法一樣,比較浪費ram 135 */ 136 #define N 12 137 138 char filter() 139 { 140 char count,i,j; 141 char value_buf[N]; 142 int sum=0; 143 for (count=0;count<N;count++) 144 { 145 value_buf[count] = get_ad(); 146 delay(); 147 } 148 for (j=0;j<N-1;j++) 149 { 150 for (i=0;i<N-j;i++) 151 { 152 if ( value_buf[i]>value_buf[i+1] ) 153 { 154 temp = value_buf[i]; 155 value_buf[i] = value_buf[i+1]; 156 value_buf[i+1] = temp; 157 } 158 } 159 } 160 for(count=1;count<N-1;count++) 161 sum += value[count]; 162 return (char)(sum/(N-2)); 163 164 } 165 166 167 //6.限幅平均濾波法 168 /* 169 * description: 相當於“限幅濾波法”+“遞推平均濾波法” 170 * 每次采樣到的新數據先進行限幅處理, 171 * 再送入隊列進行遞推平均濾波處理 172 * advantage: 融合了兩種濾波法的優點,對於偶然出現的脈沖干擾, 173 * 可消除由於脈沖干擾所引起的采樣值偏差 174 * disadvantage: 比較浪費ram 175 */ 176 177 178 179 //7.一階滯后濾波法 180 /* 181 * description: 取a=0~1,本次濾波結果=(1-a)*本次采樣值+a*上次濾波結果 182 * advantage: 對周期性干擾具有良好的抑制作用,適用於波動頻率較高的場合 183 * disadvantage: 相位之后,靈敏度低,滯后程度取決於a值大小, 184 * 不能消除濾波頻率高於采樣頻率的1/2的干擾信號 185 */ 186 /* 為加快程序處理速度假定基數為100,a=0~100 */ 187 188 #define a 50 189 190 char value; 191 192 char filter() 193 { 194 char new_value; 195 new_value = get_ad(); 196 return (100-a)*value + a*new_value; 197 } 198 199 200 //8.加權遞推平均濾波法 201 /* 202 * description: 是對遞推平均濾波法的改進,即不同時刻的數據加以不同的權重,通常是, 203 * 越接近現在時刻的數據,權重越大。給予新采樣值的權系數越大,則靈敏度越高, 204 * 但信號平滑度越低 205 * advantage: 適用於有較大純滯后時間常數的對象,和采樣周期較短的系統 206 * disadvantage: 對於純滯后時間常數較小,采樣周期較長,變化緩慢的信號不能迅速反應系統當前所受干擾的 207 * 嚴重程度,濾波效果差 208 */ 209 /* coe數組為加權系數表,存在程序存儲區。*/ 210 211 #define N 12 212 213 char code coe[N] = {1,2,3,4,5,6,7,8,9,10,11,12}; 214 char code sum_coe = 1+2+3+4+5+6+7+8+9+10+11+12; 215 216 char filter() 217 { 218 char count; 219 char value_buf[N]; 220 int sum=0; 221 for (count=0,count<N;count++) 222 { 223 value_buf[count] = get_ad(); 224 delay(); 225 } 226 for (count=0,count<N;count++) 227 sum += value_buf[count]*coe[count]; 228 return (char)(sum/sum_coe); 229 } 230 231 232 //9.消抖濾波法 233 /* 234 * description: 設置一個濾波計數器,將每次采樣值與當前有效值比較: 235 * 如果采樣值=當前有效值,則計數器清零,如果采樣值<>當前有效值, 236 * 則計數器+1,並判斷計數器是否>=上限N(溢出),如果計數器溢出, 237 * 則將本次值替換當前有效值,並清計數器 238 * advantage: 對於變化緩慢的被測參數有較好的濾波效果,可避免在臨界值附近控制器的反復開/關跳動或 239 * 顯示器上數值抖動 240 * disadvantage: 對於快速比那花的參數不宜,如果在計數器溢出的那一次采樣到的值恰好是干擾值, 241 * 則會將干擾值當作有效值導入系統 242 */ 243 #define N 12 244 245 char filter() 246 { 247 char count=0; 248 char new_value; 249 new_value = get_ad(); 250 while (value !=new_value); 251 { 252 count++; 253 if (count>=N) return new_value; 254 delay(); 255 new_value = get_ad(); 256 } 257 return value; 258 } 259 260 261 //10.限幅消抖濾波法 262 /* 263 * description: 相當於“限幅濾波法”+“消抖濾波法”先限幅,后消抖 264 * advantage: 繼承了“限幅”和“消抖”的優點,改進了“消抖濾波法”中的某些缺陷,避免將干擾值導入系統 265 * disadvantage: 對於快速變化的參數不宜 266 */