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 */