专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
我用ADC+DMA进行正弦波采集,如果是单通道输入的话,有什么软件滤波的方法吗?我看到之前的帖子用均值滤波应该要多通道输入吧。
2019-08-18 20:20
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
4180
5
1508
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
5条回答
木木之
2019-08-18 20:42
《匠人手记》里的10种软件滤波,感觉不错,跟大家分享。感谢“程序匠人”的奉献。
一、限幅滤波法
1、
先根据经验判断,确定两次采样允许的最大偏差值,设为A。
每次检测到新采样值时进行判断:
(1)如果本次新采样值与上一次滤波效果之差<=A,则本次采样值有效,令本次滤波结果=新采样值;
(2)如果本次采样值与上次滤波结果之差>A,则本次采样值无效,放弃本次采样值,本次滤波结果=上次滤波结果。
2、例程
#define A 10
uchar Value; //上次采样有效值
uchar AmplitudeLimiterFilter()
{
uchar NewValue,ReturnValue;
NewValue=GetAD(); //本次采样值
if(((NewValue-Value)>A)||((Value-NewValue)>A))
{
ReturnValue=Value;
}
else
{
ReturnValue=NewValue;
}
return(ReturnValue);
}
二、中位值滤波法
1、连续采样N次值,把采样值按大小排列,取中间值为本次有效值。
2、例程
#define N 9
unchar MiddleValueFilter()
{
unchar i,j,k;
uchar temp;
uchar ArrDataBuffer[N];
for(i=0; i<N; i++) //一次采集N个数据放入数组中
{
ArrDataBuffer=GetAD();
Delay();
}
for(j=0; j><N-1; j++) //采样值由小到大排列
{
for(k=0; k><N-j-1; k++)
{
if(ArrDataBuffer[k]>ArrDataBuffer[k+1])
{
temp=ArrDataBuffer[k];
ArrDataBuffer[k]=ArrDataBuffer[k+1];
ArrDataBuffer[k+1]=temp;
}
}
}
return(ArrDataBuffer[(N-1)/2]);//取中间值
}
三、算术平均滤波法
1、连续取N个值进行算术平均运算。
N较大时,信号平滑度较高,但灵敏度较低;N较小,信号平滑度低,但灵敏度较高。
2、例程
#define N 12
uchar ArithmeticalAverageValueFilter()
{
uchar i;
uchar Value;
uchar sum;
sum=0;
for(i=0; i<N; i++)
{
sum+=GetAD();
Delay();
}
Value=sum/N;
return(Value);
}
四、递推平均滤波法
1、把连续N个采集值看成一个队列,每次采集到的新数据放入队尾,并扔掉原来队首的数据。把队列中的N个数据进行平均计算,即可获得新的滤波结果。
2、例程
#define N 12
uchar Data[];
uchar Gilde(Data[])
{
ucahr i,Value,sum;
sum=0;
Data[N]=GetAD();
for(i=0; i><N; i++)
{
Data=Data[i+1];//所有数据左移,低位仍掉
sum+=Data;
}
Value=sum/N;
return(Value);
}
五、中位值平均滤波法
1、中位值平均滤波法又称脉冲干扰平均滤波法,相当于“中位值滤波法”+“算术平均滤波法”。
连续采集N个数据,去掉一个最大和最小值,然后计算N-2个数的平均值。
2、例程
#define N 12
uchar Middle()
{
ucahr i,j,k,l;
uchar temp;
uchar ArrDataBuffer[N];
uchar sum,Value;
for(i=0; i><N; i++) //一次采集N个数据,存入数组
{
ArrDataBuffer=GetAD();
Delay();
}
for(j=0; j><N-1; j++) //采样值由小到大排列
{
for(k=0; k><N-j-1; k++)
{
if(ArrDataBuffer[k]>ArrDataBuffer[k+1])
{
temp=ArrDataBuffer[k];
ArrDataBuffer[k]=ArrDataBuffer[k+1];
ArrDataBuffer[k+1]=temp;
}
}
}
for(l=1; l<N-1; l++)
{
sum=ArrDataBuffer[l];
}
Value=Sum/(N-2);
return(Value);
}
六、递推中位值平均滤波法
1、相当于“中位值滤波法”+“递推平均滤波法”。这种方法把连续N个值看成一个队列,每次采集到一个新数据放入队尾,并扔掉原来队首的值。 把队列中的N个数据先去掉一个最大值和最小值,然后计算N-2个数据的平均值。
2、例程
char Filter()
{
char max.min;
int sum;
char i;
QUEUE[0]=NewData;
max=QUEUE[0];
min=QUEUE[0];
sum=QUEUE[0];
for(i=n-1; i!=0; i--)
{
if(QUEUE>max)
{
max=QUEUE;
}
else if(QUEUE<min)
{
min=QUEUE;
}
sum+=QUEUE;
QUEUE=QUEUE[i-1];
}
i=n-2;
sum=sum-max-min+i/2;//加入(n-2)/2目的为了四舍五入
sum=sum/i;
return(sum);
}
七、限幅平均滤波法
1、相当于“限幅滤波法”+“递推平均滤波法”。每次采样先进行限幅处理,再进行队列平均滤波处理。
2、例程
#define A 10
#define N 12
uchar Data[N];
uchar Limit()
{
ucahr i,Value,sum;
Data[N]=GetAD();
if(((Data[N]-Data[N-1])>A)||((Data[N-1]-Data[N])>A))
{
Data[N]=Data[N-1];
}
else
{
Data[N]=NewValue;
}
for(i=0; i<N; i++)
{
Data=Data[i+1];
sum+=Data;
}
Value=sum/N;
return(Value);
}
八、一阶滞后滤波法
1、本次结果滤波结果=a*本次采样值+(1-a)*上次结果。
a代表滤波系数,a=0--1。
2、例程
#define a 128
uchar Value;
ucahr OneFactorialFiler()
{
uchar NewValue;
uchar ReturnValue;
NewValue=GetAD();
ReturnValue=(255-a)*NewValue+a*Value;
ReturnValue/=255;
return(ReturnValue);
}
九、加权递推平均滤波法
1、加权递推平均滤波法是对递推平均滤波法的改进,即不同时刻的数据加以不同的权。通常是越接近现时刻的数据,权取得越大。给予新采样值的权系数越大,则灵敏度越高,但信号的平滑度越低。
2、例程
#define N 10
#define CoeSum 55
const Coefficient[N]= {1,2,3,4,5,6,7,8,9,10};
uchar Data[N];
uchar AAGAFilter()
{
uchar i,Value,sum;
sum=0;
Data[N]=GetAD();
for(i=0; i><N; i++)
{
Data=Data[i+1];
sum+=Data*Coefficient;
}
Value=sum/CoeSum;
return(Value);
}
十、消抖滤波法
1、将每次采样值与当前有效值比较,如果采样值=当前有效值,则计数器清零,否则计数器加1。然后,判断计数器是否>=上限N(溢出)。如果溢出,将本次值替换当前有效值,并清计数器。
2、例程
#define N 20
uchar count;
uchar Value;
uchar Avoid()
{
uchar NewValue;
if(NewValue==Value)
{
count=0;
}
else
{
count++;
if(count>N)
{
count=0;
Value=NewValue;
}
}
return(Value);
}
加载中...
查看其它5个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
一、限幅滤波法
1、
先根据经验判断,确定两次采样允许的最大偏差值,设为A。
每次检测到新采样值时进行判断:
(1)如果本次新采样值与上一次滤波效果之差<=A,则本次采样值有效,令本次滤波结果=新采样值;
(2)如果本次采样值与上次滤波结果之差>A,则本次采样值无效,放弃本次采样值,本次滤波结果=上次滤波结果。
2、例程
#define A 10
uchar Value; //上次采样有效值
uchar AmplitudeLimiterFilter()
{
uchar NewValue,ReturnValue;
NewValue=GetAD(); //本次采样值
if(((NewValue-Value)>A)||((Value-NewValue)>A))
{
ReturnValue=Value;
}
else
{
ReturnValue=NewValue;
}
return(ReturnValue);
}
二、中位值滤波法
1、连续采样N次值,把采样值按大小排列,取中间值为本次有效值。
2、例程
#define N 9
unchar MiddleValueFilter()
{
unchar i,j,k;
uchar temp;
uchar ArrDataBuffer[N];
for(i=0; i<N; i++) //一次采集N个数据放入数组中
{
ArrDataBuffer=GetAD();
Delay();
}
for(j=0; j><N-1; j++) //采样值由小到大排列
{
for(k=0; k><N-j-1; k++)
{
if(ArrDataBuffer[k]>ArrDataBuffer[k+1])
{
temp=ArrDataBuffer[k];
ArrDataBuffer[k]=ArrDataBuffer[k+1];
ArrDataBuffer[k+1]=temp;
}
}
}
return(ArrDataBuffer[(N-1)/2]);//取中间值
}
三、算术平均滤波法
1、连续取N个值进行算术平均运算。
N较大时,信号平滑度较高,但灵敏度较低;N较小,信号平滑度低,但灵敏度较高。
2、例程
#define N 12
uchar ArithmeticalAverageValueFilter()
{
uchar i;
uchar Value;
uchar sum;
sum=0;
for(i=0; i<N; i++)
{
sum+=GetAD();
Delay();
}
Value=sum/N;
return(Value);
}
四、递推平均滤波法
1、把连续N个采集值看成一个队列,每次采集到的新数据放入队尾,并扔掉原来队首的数据。把队列中的N个数据进行平均计算,即可获得新的滤波结果。
2、例程
#define N 12
uchar Data[];
uchar Gilde(Data[])
{
ucahr i,Value,sum;
sum=0;
Data[N]=GetAD();
for(i=0; i><N; i++)
{
Data=Data[i+1];//所有数据左移,低位仍掉
sum+=Data;
}
Value=sum/N;
return(Value);
}
五、中位值平均滤波法
1、中位值平均滤波法又称脉冲干扰平均滤波法,相当于“中位值滤波法”+“算术平均滤波法”。
连续采集N个数据,去掉一个最大和最小值,然后计算N-2个数的平均值。
2、例程
#define N 12
uchar Middle()
{
ucahr i,j,k,l;
uchar temp;
uchar ArrDataBuffer[N];
uchar sum,Value;
for(i=0; i><N; i++) //一次采集N个数据,存入数组
{
ArrDataBuffer=GetAD();
Delay();
}
for(j=0; j><N-1; j++) //采样值由小到大排列
{
for(k=0; k><N-j-1; k++)
{
if(ArrDataBuffer[k]>ArrDataBuffer[k+1])
{
temp=ArrDataBuffer[k];
ArrDataBuffer[k]=ArrDataBuffer[k+1];
ArrDataBuffer[k+1]=temp;
}
}
}
for(l=1; l<N-1; l++)
{
sum=ArrDataBuffer[l];
}
Value=Sum/(N-2);
return(Value);
}
六、递推中位值平均滤波法
1、相当于“中位值滤波法”+“递推平均滤波法”。这种方法把连续N个值看成一个队列,每次采集到一个新数据放入队尾,并扔掉原来队首的值。 把队列中的N个数据先去掉一个最大值和最小值,然后计算N-2个数据的平均值。
2、例程
char Filter()
{
char max.min;
int sum;
char i;
QUEUE[0]=NewData;
max=QUEUE[0];
min=QUEUE[0];
sum=QUEUE[0];
for(i=n-1; i!=0; i--)
{
if(QUEUE>max)
{
max=QUEUE;
}
else if(QUEUE<min)
{
min=QUEUE;
}
sum+=QUEUE;
QUEUE=QUEUE[i-1];
}
i=n-2;
sum=sum-max-min+i/2;//加入(n-2)/2目的为了四舍五入
sum=sum/i;
return(sum);
}
七、限幅平均滤波法
1、相当于“限幅滤波法”+“递推平均滤波法”。每次采样先进行限幅处理,再进行队列平均滤波处理。
2、例程
#define A 10
#define N 12
uchar Data[N];
uchar Limit()
{
ucahr i,Value,sum;
Data[N]=GetAD();
if(((Data[N]-Data[N-1])>A)||((Data[N-1]-Data[N])>A))
{
Data[N]=Data[N-1];
}
else
{
Data[N]=NewValue;
}
for(i=0; i<N; i++)
{
Data=Data[i+1];
sum+=Data;
}
Value=sum/N;
return(Value);
}
八、一阶滞后滤波法
1、本次结果滤波结果=a*本次采样值+(1-a)*上次结果。
a代表滤波系数,a=0--1。
2、例程
#define a 128
uchar Value;
ucahr OneFactorialFiler()
{
uchar NewValue;
uchar ReturnValue;
NewValue=GetAD();
ReturnValue=(255-a)*NewValue+a*Value;
ReturnValue/=255;
return(ReturnValue);
}
九、加权递推平均滤波法
1、加权递推平均滤波法是对递推平均滤波法的改进,即不同时刻的数据加以不同的权。通常是越接近现时刻的数据,权取得越大。给予新采样值的权系数越大,则灵敏度越高,但信号的平滑度越低。
2、例程
#define N 10
#define CoeSum 55
const Coefficient[N]= {1,2,3,4,5,6,7,8,9,10};
uchar Data[N];
uchar AAGAFilter()
{
uchar i,Value,sum;
sum=0;
Data[N]=GetAD();
for(i=0; i><N; i++)
{
Data=Data[i+1];
sum+=Data*Coefficient;
}
Value=sum/CoeSum;
return(Value);
}
十、消抖滤波法
1、将每次采样值与当前有效值比较,如果采样值=当前有效值,则计数器清零,否则计数器加1。然后,判断计数器是否>=上限N(溢出)。如果溢出,将本次值替换当前有效值,并清计数器。
2、例程
#define N 20
uchar count;
uchar Value;
uchar Avoid()
{
uchar NewValue;
if(NewValue==Value)
{
count=0;
}
else
{
count++;
if(count>N)
{
count=0;
Value=NewValue;
}
}
return(Value);
}
一周热门 更多>