对于和电力设备打交道的单片机程序员来说,不可避免地要对电力信号进行采样处理,以计算电压电流功率,甚至频率,谐波分量,基波含量等等。可能很多人学了书本上的公式,但还是感觉很难把它转化成代码实现工程应用。这里分享一下我以前使用傅里叶变换来计算基波和谐波分量的例子。
先上公式:
图一DFT公式
其中k=0,1,2.....N-1,X(k)表示DFT变换后的数据,x(n)为采样的模拟信号,公式中的x(n)可以为复信号,实际当中x(n)都是实信号,即虚部为0,此时公式可以展开为:
图二DFT展开
可以看到,这就是实部和虚部的累加计算,于是乎把实部和虚部分开来写,方便我们程序实现。
图三实部
图四虚部
sin和cos的值常规做法是建立表格,用查表法,节省计算量,别让单片机太累。至于表格怎么建立嘛,可以使用excel自动计算,直接拷贝出来使用。表格多大取决于咱们对信号的采样点个数,比如采样128点,那么就建立sin_table[128]和cos_table[128]的表格。
下面实现实部和虚部的计算函数
float DFT_Imag(uint16 *sample,uint16 n,uchar k)
{
uint16 i;
float res,temp;
res=0;temp=0;
for(i=0;i<n;i++)
{
temp=*(sample+i)*sin_table[(i*k)%n];
res+=temp;
}
res=res*2/n;
return(res);
}
float DFT_Real(uint16 *sample,uint16 n,uchar k)
{
uint16 i;
float res,temp;
res=0;temp=0;
for(i=0;i<n;i++)
{
temp=*(sample+i)*cos_table[(i*k)%n];
res+=temp;
}
res=res*2/n;
return(res);
}
比如需要计算基波(ad_buff存储128点的采样值)
float Re1,Img1;
Re1=DFT_Real(ad_buff,128,1);
Img1=DFT_Imag(ad_buff,128,1);
Fundamental_wave=sqrt(0.5*(Re1*Re1+Img1*Img1))*factor;
factor为交流信号的校正系数。校正系数需要在标准源下校正得到,并且存储在flash或者eeprom里面,上电读取就可以使用。
当然DFT计算有它的缺点,但是工程应用看得是是否满足需求,很多场合下,使用以上计算已经能满足我们的计算需求了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)