之前做一个东西显示电量的时候用过这种方式,终于知道这种滤波的名字了 真是好资料,学习到了很多,顶 很实用,学习了, 说的挺好的。。 要是有fir 这么简单的教程就好了 收藏,学习了 非常感谢!!! 记号 备用 我之前用的是平均值滤波,但是效果不是很好 受教了!!! 我需要学习卡尔曼滤波{:lol:} 学习了, 谢谢楼主. 本帖最后由 Kwangsi 于 2015-7-27 09:30 编辑
go2deathward 发表于 2014-4-8 14:01
呵呵,中位值滤波,为什么要排序?简单的东西,复杂化了。中位值无非就是去掉最大最小值而已,排序太麻烦了 ...
事实上 就算是你这个做法还有 很大的提升空间,
单片机本身资源就有限,而且很多情况下要求实时
如果按教科书的算法去做 那就该吃药了 贴一个我的代码给大家
电路有市电 过零点检测
每次过零 启动150us的 TIMER1_ISR 中断 在3750 us开始,每隔150us采集一次市电的 ADC 以检测用的市电是110v还是220V 同时检测一个0.1R的ADC ,市电的 ADC *16 /0.R的ADC 连续采样10次 去掉最大值和最小值。
void TIMER1_ISR (void) interrupt 3 //using 1
{
//150us
//GPIO2 ^= BIT3;//GPIO19
//GPIO0 ^= BIT2;
//++electrical_level_timer;//t2_count2
switch(++electrical_level_timer)
{
case 1:
TRIAC_OFF;//bidirectional triode thyristor
break;
case 24:
electric_supply_0p1R_adc_max = 0x0000;
electric_supply_0p1R_adc_min = 0xFFFF;
electric_supply_0p1R_adc_sum = 0x0000;
break;
case 25://150*25=3750
case 26://150*26=3900
case 27://150*27=4050
case 28://150*28=4200
case 29://150*29=4350
case 30://150*30=4500
case 31://150*31=4650
case 32://150*32=4800
case 33://150*33=4950
electric_supply_voltage_adc = ADC1_GetConversionValue(2);//adc 220v or 110v
electric_supply_voltage_adc = (electric_supply_voltage_adc << 4);
electric_0p1R_adc = ADC1_GetConversionValue(0);//0.1R
electric_supply_0p1R_adc = (electric_supply_voltage_adc) / electric_0p1R_adc;
if(electric_supply_0p1R_adc_max < electric_supply_0p1R_adc)
{
electric_supply_0p1R_adc_max = electric_supply_0p1R_adc;
}
else if(electric_supply_0p1R_adc_min > electric_supply_0p1R_adc)
{
electric_supply_0p1R_adc_min = electric_supply_0p1R_adc;
}
electric_supply_0p1R_adc_sum += electric_supply_0p1R_adc;
#if 0
Debug_UartSendByte(0x55);
Debug_UartSendByte(electric_supply_voltage_adc >> 8);
Debug_UartSendByte((u8_t)electric_supply_voltage_adc);
Debug_UartSendByte(0x56);
Debug_UartSendByte(electric_0p1R_adc >> 8);
Debug_UartSendByte((u8_t)electric_0p1R_adc);
#endif
Debug_UartSendByte(0x5A);
Debug_UartSendByte(electric_supply_0p1R_adc >> 8);
Debug_UartSendByte((u8_t)electric_supply_0p1R_adc);
Debug_UartSendByte(0xA5);
Debug_UartSendByte(electric_supply_0p1R_adc_sum >> 8);
Debug_UartSendByte((u8_t)electric_supply_0p1R_adc_sum);
break;
case 34://150*34=5100us
electric_supply_voltage_adc = ADC1_GetConversionValue(2);//adc 220v or 110v
electric_supply_voltage_adc = (electric_supply_voltage_adc << 4);
electric_0p1R_adc = ADC1_GetConversionValue(0);//0.1R
electric_supply_0p1R_adc = (electric_supply_voltage_adc) / electric_0p1R_adc;
if(electric_supply_0p1R_adc_max < electric_supply_0p1R_adc)
{
electric_supply_0p1R_adc_sum -= electric_supply_0p1R_adc_min;
electric_supply_0p1R_adc_max = electric_supply_0p1R_adc;
}
else if(electric_supply_0p1R_adc_min > electric_supply_0p1R_adc)
{
electric_supply_0p1R_adc_sum -= electric_supply_0p1R_adc_max;
electric_supply_0p1R_adc_min = electric_supply_0p1R_adc;
}
else
{
electric_supply_0p1R_adc_sum -= electric_supply_0p1R_adc_min;
electric_supply_0p1R_adc_sum -= electric_supply_0p1R_adc_max;
electric_supply_0p1R_adc_sum += electric_supply_0p1R_adc;
}
//3.3ms
TF1 = 0;
TR1 = 0; //disable T1
ET1 = 0;
Debug_UartSendByte(0x5A);
Debug_UartSendByte(electric_supply_0p1R_adc >> 8);
Debug_UartSendByte((u8_t)electric_supply_0p1R_adc);
Debug_UartSendByte(0xA5);
Debug_UartSendByte(electric_supply_0p1R_adc_sum >> 8);
Debug_UartSendByte((u8_t)electric_supply_0p1R_adc_sum);
Debug_UartSendByte(0x8A);
Debug_UartSendByte(electric_supply_0p1R_adc_min >> 8);
Debug_UartSendByte((u8_t)electric_supply_0p1R_adc_min);
Debug_UartSendByte(0x9A);
Debug_UartSendByte(electric_supply_0p1R_adc_max >> 8);
Debug_UartSendByte((u8_t)electric_supply_0p1R_adc_max);
Debug_UartSendByte(0xAA);
Debug_UartSendByte(electric_supply_0p1R_adc_sum >> 8);
Debug_UartSendByte((u8_t)electric_supply_0p1R_adc_sum);
electrical_level_timer = 0;
break;
default:
break;
}
} 收藏了,慢慢消化 好东西 常用 总结的好好 好东西,学些一下。
收藏,谢谢分享 数字滤波很有用的,马克一下,谢谢 MARKC语言滤波 这个确实经典 mark,多谢 mark, 记下来 mark一下以后说不定有用 mark 谢谢楼主了
不错,收藏了1 做个记号,明天电脑上再仔细看 这个是在‘程序匠人"写的一本书里看到多,网上也到处都是。 不错的资料,多谢分享 中位值平均滤波法运算中有一处问题:
/********************************************
说明:采一组队列去掉最大值和最小值
优点:融合了两种滤波的优点。对于偶然出现的脉冲性干扰,可消
除有其引起的采样值偏差。对周期干扰有良好的抑制作用,
平滑度高,适于高频振荡的系统。
缺点:测量速度慢
*********************************************/
#define N 12
uchar filter()
{
unsigned char i,j,k,l;
unsigned char temp,sum=0,value;
unsigned char value_buf,;
for(i=0;i<N;i++)
{
value_buf = get_ad();
delay();
}
//采样值从小到大排列(冒泡法)
for(j=0;j<N-1;j++)
{
for(i=0;i<N-j;i++)
应该改成for(i=0;i<(N-1-j);i++)
{
if(value_buf>value_buf)
{
temp = value_buf;
value_buf = value_buf;
value_buf = temp;
}
}
}
for(i=1;i<N-1;i++)
sum += value_buf;
value = sum/(N-2);
return(value);
} 收藏备用,数字滤波 如此强大,可惜我看不懂@ 有2种方法用过了 mark下,需要实践测试验证下 122楼的代码写的真好.顶! 谢了,学习 实用,作个记号 收藏了,谢谢分享 学习收藏,谢谢 谢谢各位分享,正需要。现在学习51ADC
页:
1
[2]