8471|12

55

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

关于fft [复制链接]

今天碰到一个问题,由于处理需要用到fft变换所以采用了一下的fft函数,函数在vc上运行正确,在我的ST STM32F10xxE上运行,结果运行函数不正确,应该是编译器的问题,但是不知道有什么方法可以修改一下函数使得结果正确,望高手解答,谢谢各位了!
(另外,stm32虽然出了函数库,但是fft的用于5.20版本的iar,实在是没有板子的驱动阿。。。。 )

// 入口参数: 
// l: l = 0, 傅立叶变换; l = 1, 逆傅立叶变换
// il: il = 0,不计算傅立叶变换或逆变换模和幅角;il = 1,计算模和幅角
// n: 输入的点数,为偶数,一般为32,64,128,...,1024等
// k: 满足n=2^k(k>0),实质上k是n个采样数据可以分解为偶次幂和奇次幂的次数
// pr[]: l=0时,存放N点采样数据的实部
// l=1时, 存放傅立叶变换的N个实部
// pi[]: l=0时,存放N点采样数据的虚部 
// l=1时, 存放傅立叶变换的N个虚部
//
// 出口参数:
// fr[]: l=0, 返回傅立叶变换的实部
// l=1, 返回逆傅立叶变换的实部
// fi[]: l=0, 返回傅立叶变换的虚部
// l=1, 返回逆傅立叶变换的虚部
// pr[]: il = 1,l = 0 时,返回傅立叶变换的模
// il = 1,l = 1 时,返回逆傅立叶变换的模
// pi[]: il = 1,l = 0 时,返回傅立叶变换的辐角
// il = 1,l = 1 时,返回逆傅立叶变换的辐角


void kbfft(double *pr,double *pi,int n,int k,double *fr,double *fi,int l,int il)

    int it,m,is,i,j,nv,l0;
    double p,q,s,vr,vi,poddr,poddi;
    
    //排序
    for (it=0; it<=n-1; it++) 
      { m=it; is=0;
        for (i=0; i<=k-1; i++)
          { j=m/2; is=2*is+(m-2*j); m=j;
            fr[it]=pr[is]; fi[it]=pi[is];
          }
      }
    
    //蝶形运算
    pr[0]=1.0; pi[0]=0.0;
    p=6.283185306/(1.0*n);
    pr[1]=cos(p); pi[1]=-sin(p);
    if (l!=0) pi[1]=-pi[1];
    for (i=2; i<=n-1; i++)
      { p=pr[i-1]*pr[1]; q=pi[i-1]*pi[1];
        s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);
        pr=p-q; pi=s-p-q;
      }
    for (it=0; it<=n-2; it=it+2)
      { vr=fr[it]; vi=fi[it];
        fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1];
        fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1];
      }
    m=n/2; nv=2;
    for (l0=k-2; l0>=0; l0--)
      { m=m/2; nv=2*nv;
        for (it=0; it<=(m-1)*nv; it=it+nv)
          for (j=0; j<=(nv/2)-1; j++)
            { p=pr[m*j]*fr[it+j+nv/2];
              q=pi[m*j]*fi[it+j+nv/2];
              s=pr[m*j]+pi[m*j];
              s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]);
              poddr=p-q; poddi=s-p-q;
              fr[it+j+nv/2]=fr[it+j]-poddr;
              fi[it+j+nv/2]=fi[it+j]-poddi;
              fr[it+j]=fr[it+j]+poddr;
              fi[it+j]=fi[it+j]+poddi;
            }
      }
    if (l!=0)
      for (i=0; i<=n-1; i++)
        { fr=fr/(1.0*n);
          fi=fi/(1.0*n);
        }
    if (il!=0)
      for (i=0; i<=n-1; i++)
        { pr=sqrt(fr*fr+fi*fi);
          pr=(pr/(n/2)); //各次谐波幅值,其中pr[1]为基波幅值
          if (fabs(fr)<0.000001*fabs(fi))//fabs()
            { if ((fi*fr)>0) pi=90.0;
              else pi=-90.0;
            }
          else
            pi=atan(fi/fr)*360.0/6.283185306;
        }
    return;
}
此帖出自stm32/stm8论坛

最新回复

                                 很久没来,最后将程序实验了一下,确实是可行的,之前不能运行是因为我没有加一个头文件math.h,算出结果可能还是有误差,凑合着用下应该还行,大家有用过发现问题的可以指导一下^_^   详情 回复 发表于 2008-12-30 17:23
点赞 关注
 

回复
举报

71

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

这个FFT 是给人笑话的。

                                 STM32有FFT库,使用就可以了。
此帖出自stm32/stm8论坛
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

还有,STM32的FFT与IAR软件版本无关

                                 可以用KEIL,IAR,与版本没多大关系的。
此帖出自stm32/stm8论坛
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

4
 

固件库不是要5.0以上版本的IAR才能使用吗?

                                 另外,用的万利的板子采用iar5.2的时候驱动似乎不能上,显示驱动出错
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

5
 

STM32的 FFT函数是可以纯软件仿真的!

                                 fft与开发板硬件无关,可以用软件仿真。
此帖出自stm32/stm8论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

6
 

谢谢netjob耐心的解答

                                 但是现在需要在硬件上使用,现在就不知道应该怎样做了
此帖出自stm32/stm8论坛
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

7
 

你这个还double,stm32那速度哪里受得了

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(中级)

8
 

运行时间感觉很短的

                                 运行时间感觉很短的,1024个点也就一秒钟多一点就可以了
此帖出自stm32/stm8论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

9
 

你这个程序根本就编译不了!N多错误。

”函数在vc上运行正确“!

本来想测试一下的!
此帖出自stm32/stm8论坛
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

10
 

我是lz,不好意思,之前是个子函数,这个是我运行成功的程

#include "stdafx.h"
#include "math.h"

#define fftBufferSize 256
double fpr[fftBufferSize]={0};
double fpi[fftBufferSize]={0};
double ffr[fftBufferSize]={0}; 
double ffi[fftBufferSize]={0};
void kbfft(double *pr,double *pi,int n,int k,double *fr,double *fi,int l,int il);
int main(int argc, char* argv[])
{
    int i;
    
    for (i=0;i<=(fftBufferSize/2);i++)
  {
    fpr=(float)i/64.0;
    fpr[fftBufferSize-i]=(float)i/64.0;
  }
    kbfft(fpr,fpi,256,8,ffr,ffi,0,1);
    return 0;
}
    // 入口参数: 
// l: l = 0, 傅立叶变换; l = 1, 逆傅立叶变换
// il: il = 0,不计算傅立叶变换或逆变换模和幅角;il = 1,计算模和幅角
// n: 输入的点数,为偶数,一般为32,64,128,...,1024等
// k: 满足n=2^k(k>0),实质上k是n个采样数据可以分解为偶次幂和奇次幂的次数
// pr[]: l=0时,存放N点采样数据的实部
// l=1时, 存放傅立叶变换的N个实部
// pi[]: l=0时,存放N点采样数据的虚部 
// l=1时, 存放傅立叶变换的N个虚部
//
// 出口参数:
// fr[]: l=0, 返回傅立叶变换的实部
// l=1, 返回逆傅立叶变换的实部
// fi[]: l=0, 返回傅立叶变换的虚部
// l=1, 返回逆傅立叶变换的虚部
// pr[]: il = 1,l = 0 时,返回傅立叶变换的模
// il = 1,l = 1 时,返回逆傅立叶变换的模
// pi[]: il = 1,l = 0 时,返回傅立叶变换的辐角
// il = 1,l = 1 时,返回逆傅立叶变换的辐角
void kbfft(double *pr,double *pi,int n,int k,double *fr,double *fi,int l,int il)

    int it,m,is,i,j,nv,l0;
    double p,q,s,vr,vi,poddr,poddi;
    
    //排序
    for (it=0; it<=n-1; it++) 
      { m=it; is=0;
        for (i=0; i<=k-1; i++)
          { j=m/2; is=2*is+(m-2*j); m=j;
            fr[it]=pr[is]; fi[it]=pi[is];
          }
      }
    
    //蝶形运算
    pr[0]=1.0; pi[0]=0.0;
    p=6.283185306/(1.0*n);
    pr[1]=cos(p); pi[1]=-sin(p);
    if (l!=0) pi[1]=-pi[1];
    for (i=2; i<=n-1; i++)
      { p=pr[i-1]*pr[1]; q=pi[i-1]*pi[1];
        s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);
        pr=p-q; pi=s-p-q;
      }
    for (it=0; it<=n-2; it=it+2)
      { vr=fr[it]; vi=fi[it];
        fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1];
        fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1];
      }
    m=n/2; nv=2;
    for (l0=k-2; l0>=0; l0--)
      { m=m/2; nv=2*nv;
        for (it=0; it<=(m-1)*nv; it=it+nv)
          for (j=0; j<=(nv/2)-1; j++)
            { p=pr[m*j]*fr[it+j+nv/2];
              q=pi[m*j]*fi[it+j+nv/2];
              s=pr[m*j]+pi[m*j];
              s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]);
              poddr=p-q; poddi=s-p-q;
              fr[it+j+nv/2]=fr[it+j]-poddr;
              fi[it+j+nv/2]=fi[it+j]-poddi;
              fr[it+j]=fr[it+j]+poddr;
              fi[it+j]=fi[it+j]+poddi;
            }
      }
    if (l!=0)
      for (i=0; i<=n-1; i++)
        { fr=fr/(1.0*n);
          fi=fi/(1.0*n);
        }
    if (il!=0)
      for (i=0; i<=n-1; i++)
        { pr=sqrt(fr*fr+fi*fi);
          pr=(pr/(n/2)); //各次谐波幅值,其中pr[1]为基波幅值
          if (fabs(fr)<0.000001*fabs(fi))//fabs()
            { if ((fi*fr)>0) pi=90.0;
              else pi=-90.0;
            }
          else
            pi=atan(fi/fr)*360.0/6.283185306;
        }
    return;
}
此帖出自stm32/stm8论坛
 
 
 

回复

89

帖子

0

TA的资源

一粒金砂(初级)

11
 

完全错误的程序!哈哈!

                                 啥子程序来的?
此帖出自stm32/stm8论坛
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

12
 

在vc上运行与在stm32上运行结果确实不一样

                                 这个程序是网上找的,或者有高手能提供一个可用的fft程序么?谢谢大家
此帖出自stm32/stm8论坛
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

13
 

后续的结果

                                 很久没来,最后将程序实验了一下,确实是可行的,之前不能运行是因为我没有加一个头文件math.h,算出结果可能还是有误差,凑合着用下应该还行,大家有用过发现问题的可以指导一下^_^
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表