首页/文章/ 详情

DSP的FFT算法

1年前浏览2123

DSP的FFT算法


 
  1. #ifndef ZX_FFT_H_

  2. #define ZX_FFT_H_


  3. typedef float          FFT_TYPE;


  4. #ifndef PI

  5. #define PI             (3.14159265f)

  6. #endif


  7. typedef struct complex_st {

  8. FFT_TYPE real;

  9. FFT_TYPE img;

  10. } complex;


  11. int fft(complex *x, int N);

  12. int ifft(complex *x, int N);

  13. void zx_fft(void);


  14. #endif /* ZX_FFT_H_ */


  
  1. /*

  2. * zx_fft.c

  3. *

  4. * Implementation of Fast Fourier Transform(FFT)

  5. * and reversal Fast Fourier Transform(IFFT)

  6. *

  7. *  Created on: 2013-8-5

  8. *      Author: monkeyzx

  9. */


  10. #include "zx_fft.h"

  11. #include <math.h>

  12. #include <stdlib.h>


  13. /*

  14. * Bit Reverse

  15. * === Input ===

  16. * x : complex numbers

  17. * n : nodes of FFT. @N should be power of 2, that is 2^(*)

  18. * l : count by bit of binary format, @l=CEIL{log2(n)}

  19. * === Output ===

  20. * r : results after reversed.

  21. * Note: I use a local variable @temp that result @r can be set

  22. * to @x and won't overlap.

  23. */

  24. static void BitReverse(complex *x, complex *r, int n, int l)

  25. {

  26. int i = 0;

  27. int j = 0;

  28. short stk = 0;

  29. static complex *temp = 0;


  30. temp = (complex *)malloc(sizeof(complex) * n);

  31. if (!temp) {

  32. return;

  33. }


  34. for(i=0; i<n; i++) {

  35. stk = 0;

  36. j = 0;

  37. do {

  38. stk |= (i>>(j++)) & 0x01;

  39. if(j<l)

  40. {

  41. stk <<= 1;

  42. }

  43. }while(j<l);


  44. if(stk < n) {             /* 满足倒位序输出 */

  45. temp[stk] = x[i];

  46. }

  47. }

  48. /* copy @temp to @r */

  49. for (i=0; i<n; i++) {

  50. r[i] = temp[i];

  51. }

  52. free(temp);

  53. }


  54. /*

  55. * FFT Algorithm

  56. * === Inputs ===

  57. * x : complex numbers

  58. * N : nodes of FFT. @N should be power of 2, that is 2^(*)

  59. * === Output ===

  60. * the @x contains the result of FFT algorithm, so the original data

  61. * in @x is destroyed, please store them before using FFT.

  62. */

  63. int fft(complex *x, int N)

  64. {

  65. int i,j,l,ip;

  66. static int M = 0;

  67. static int le,le2;

  68. static FFT_TYPE sR,sI,tR,tI,uR,uI;


  69. M = (int)(log(N) / log(2));


  70. /*

  71. * bit reversal sorting

  72. */

  73. BitReverse(x,x,N,M);


  74. /*

  75. * For Loops

  76. */

  77. for (l=1; l<=M; l++) {   /* loop for ceil{log2(N)} */

  78. le = (int)pow(2,l);

  79. le2 = (int)(le / 2);

  80. uR = 1;

  81. uI = 0;

  82. sR = cos(PI / le2);

  83. sI = -sin(PI / le2);

  84. for (j=1; j<=le2; j++) {   /* loop for each sub DFT */

  85. //jm1 = j - 1;

  86. for (i=j-1; i<=N-1; i+=le) {  /* loop for each butterfly */

  87. ip = i + le2;

  88. tR = x[ip].real * uR - x[ip].img * uI;

  89. tI = x[ip].real * uI + x[ip].img * uR;

  90. x[ip].real = x[i].real - tR;

  91. x[ip].img = x[i].img - tI;

  92. x[i].real += tR;

  93. x[i].img += tI;

  94. }  /* Next i */

  95. tR = uR;

  96. uR = tR * sR - uI * sI;

  97. uI = tR * sI + uI *sR;

  98. } /* Next j */

  99. } /* Next l */


  100. return 0;

  101. }


  102. /*

  103. * Inverse FFT Algorithm

  104. * === Inputs ===

  105. * x : complex numbers

  106. * N : nodes of FFT. @N should be power of 2, that is 2^(*)

  107. * === Output ===

  108. * the @x contains the result of FFT algorithm, so the original data

  109. * in @x is destroyed, please store them before using FFT.

  110. */

  111. int ifft(complex *x, int N)

  112. {

  113. int k = 0;


  114. for (k=0; k<=N-1; k++) {

  115. x[k].img = -x[k].img;

  116. }


  117. fft(x, N);    /* using FFT */


  118. for (k=0; k<=N-1; k++) {

  119. x[k].real = x[k].real / N;

  120. x[k].img = -x[k].img / N;

  121. }


  122. return 0;

  123. }


  124. /*

  125. * Code below is an example of using FFT and IFFT.

  126. */

  127. #define  SAMPLE_NODES              (128)

  128. complex x[SAMPLE_NODES];

  129. int INPUT[SAMPLE_NODES];

  130. int OUTPUT[SAMPLE_NODES];


  131. static void MakeInput()

  132. {

  133. int i;


  134. for ( i=0;i<SAMPLE_NODES;i++ )

  135. {

  136. x[i].real = sin(PI*2*i/SAMPLE_NODES);

  137. x[i].img = 0.0f;

  138. INPUT[i]=sin(PI*2*i/SAMPLE_NODES)*1024;

  139. }

  140. }


  141. static void MakeOutput()

  142. {

  143. int i;


  144. for ( i=0;i<SAMPLE_NODES;i++ )

  145. {

  146. OUTPUT[i] = sqrt(x[i].real*x[i].real + x[i].img*x[i].img)*1024;

  147. }

  148. }


  149. void zx_fft(void)

  150. {

  151. MakeInput();


  152. fft(x,128);

  153. MakeOutput();


  154. ifft(x,128);

  155. MakeOutput();

  156. }


程序在TMS320C6713上实验,主函数中调用zx_fft()函数即可。


FFT的采样点数为128,输入信号的实数域为正弦信号,虚数域为0,数据精度定义FFT_TYPE为float类型,MakeInput和MakeOutput函数分别用于产生输入数据INPUT和输出数据OUTPUT的函数,便于使用CCS 的Graph功能绘制波形图。这里调试时使用CCS v5中的Tools -> Graph功能得到下面的波形图(怎么用自己琢磨,不会的使用CCS 的Help)。

输入波形


输入信号的频域幅值表示


FFT运算结果


对FFT运算结果逆变换(IFFT)



如何检验运算结果是否正确呢?有几种方法:

(1)使用matlab验证,下面为相同情况的matlab图形验证代码

  
  1. SAMPLE_NODES = 128;

  2. i = 1:SAMPLE_NODES;

  3. x = sin(pi*2*i / SAMPLE_NODES);


  4. subplot(2,2,1); plot(x);title('Inputs');

  5. axis([0 128 -1 1]);


  6. y = fft(x, SAMPLE_NODES);

  7. subplot(2,2,2); plot(abs(y));title('FFT');

  8. axis([0 128 0 80]);


  9. z = ifft(y, SAMPLE_NODES);

  10. subplot(2,2,3); plot(abs(z));title('IFFT');

  11. axis([0 128 0 1]);

说明:本文来源网络电力电子变流器中观点仅供分享交流,不代表本公 众 号立场,转载请注明出处,如涉及版权等问题,请您告知,我们将及时处理。


- END -

来源:电力电子技术与新能源
燃料电池电源电路汽车电力电子MATLAB新能源电机太阳能Fourier Transform控制
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2023-05-18
最近编辑:1年前
获赞 154粉丝 261文章 2060课程 0
点赞
收藏
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈