牛人有没有关于fft使用的程序

2019-07-15 23:24发布

单片机显示音乐频谱,FFT这卡住了,求帮帮忙
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
chen499103
1楼-- · 2019-07-16 23:18
这个你参考下:
  1. #include <reg52.h>
  2. #include <intrins.h>


  3. #include<math.h>

  4. #define PI 3.14159               //定义圆周率值
  5. #define FFT_N 32                                                  //定义福利叶变换的点数

  6. struct compx {float real,imag;};                                    //定义一个复数结构
  7. struct compx s[FFT_N];                                              //FFT输入和输出:从S[1]开始存放,根据大小自己定义



  8. struct compx EE(struct compx a,struct compx b)     
  9. {
  10. struct compx c;
  11. c.real=a.real*b.real-a.imag*b.imag;
  12. c.imag=a.real*b.imag+a.imag*b.real;
  13. return(c);
  14. }


  15. void FFT(struct compx *xin)
  16. {
  17.   int f,m,nv2,nm1,i,k,l,j=0;
  18.   struct compx u,w,t;
  19.   
  20.    nv2=FFT_N/2;                  //变址运算,即把自然顺序变成倒位序,采用雷德算法
  21.    nm1=FFT_N-1;
  22.    for(i=0;i<nm1;i++)      
  23.    {
  24.     if(i<j)                    //如果i<j,即进行变址
  25.      {
  26.       t=xin[j];         
  27.       xin[j]=xin[i];
  28.       xin[i]=t;
  29.      }
  30.     k=nv2;                    //求j的下一个倒位序
  31.     while(k<=j)               //如果k<=j,表示j的最高位为1  
  32.      {         
  33.       j=j-k;                 //把最高位变成0
  34.       k=k/2;                 //k/2,比较次高位,依次类推,逐个比较,直到某个位为0
  35.      }
  36.    j=j+k;                   //把0改为1
  37.   }
  38.                         
  39.   {
  40.    int le,lei,ip;                            //FFT运算核,使用蝶形运算完成FFT运算
  41.     f=FFT_N;
  42.    for(l=1;(f=f/2)!=1;l++)                  //计算l的值,即计算蝶形级数
  43.            ;
  44.   for(m=1;m<=l;m++)                         // 控制蝶形结级数
  45.    {                                        //m表示第m级蝶形,l为蝶形级总数l=log(2)N
  46.     le=2<<(m-1);                            //le蝶形结距离,即第m级蝶形的蝶形结相距le点
  47.     lei=le/2;                               //同一蝶形结中参加运算的两点的距离
  48.     u.real=1.0;                             //u为蝶形结运算系数,初始值为1
  49.     u.imag=0.0;
  50.     w.real=cos(PI/lei);                     //w为系数商,即当前系数与前一个系数的商
  51.     w.imag=-sin(PI/lei);
  52.     for(j=0;j<=lei-1;j++)                   //控制计算不同种蝶形结,即计算系数不同的蝶形结
  53.      {
  54.       for(i=j;i<=FFT_N-1;i=i+le)            //控制同一蝶形结运算,即计算系数相同蝶形结
  55.        {
  56.         ip=i+lei;                           //i,ip分别表示参加蝶形运算的两个节点
  57.         t=EE(xin[ip],u);                    //蝶形运算,详见公式
  58.         xin[ip].real=xin[i].real-t.real;
  59.         xin[ip].imag=xin[i].imag-t.imag;
  60.         xin[i].real=xin[i].real+t.real;
  61.         xin[i].imag=xin[i].imag+t.imag;
  62.        }
  63.       u=EE(u,w);                           //改变系数,进行下一个蝶形运算
  64.      }
  65.    }
  66.   }

  67. }


  68. void main()  
  69. {
  70.   unsigned char i;
  71.   for(i=0;i<FFT_N;i++)                           //给结构体赋值
  72.   {
  73.      s[i].real=sin(2*PI*i/FFT_N); //实部为正弦波FFT_N点采样,赋值为1
  74.      s[i].imag=0;                                //虚部为0
  75.   }

  76.   FFT(s);                                        //进行快速福利叶变换

  77.   for(i=0;i<FFT_N;i++)                           //求变换后结果的模值,存入复数的实部部分
  78.   s[i].real=sqrt(s[i].real*s[i].real+s[i].imag*s[i].imag);

  79.    while(1);
  80. }
复制代码

一周热门 更多>