[应用相关] 使用STM32 的DSP库进行FFT变换

[复制链接]
 楼主| wahahaheihei 发表于 2016-11-5 19:28 | 显示全部楼层 |阅读模式
  1. /*
  2. *********************************************************************************************************
  3. FileName:dsp_asm.h
  4. *********************************************************************************************************
  5. */

  6. #ifndef  __DSP_ASM_H__
  7. #define  __DSP_ASM_H__
  8. *********************************************************************************************************
  9. *                                            FUNCTION PROTOTYPES
  10. *********************************************************************************************************
  11. */

  12. void    dsp_asm_test(void);
  13. void  dsp_asm_init(void);

  14. #endif                                                          /* End of module include.                               */
  15. /*8888888888888888888888888888888888888888888888888888888888888888*/
  16. /*8888888888888888888888888888888888888888888888888888888888888888*/
  17. /*
  18. * FileName:dsp_asm.c
  19. * Author:Bobby.Chen
  20. * Email:heroxx@163.com
  21. * Date:2010-08-11
  22. * Description:This file showes how to use the dsp library in mdk project.
  23. *                  使用三角函数生成采样点,供FFT计算
  24. *                  进行FFT测试时,按下面顺序调用函数即可:
  25. *                   dsp_asm_init();
  26. *                   dsp_asm_test();
  27. */
  28. #include "stm32f10x.h"
  29. #include "dsp_asm.h"
  30. #include "stm32_dsp.h"
  31. #include "table_fft.h"
  32. #include <stdio.h>
  33. #include <math.h>


  34. /*
  35. *********************************************************************************************************
  36. *                                           LOCAL CONSTANTS
  37. *********************************************************************************************************
  38. */
  39. #define PI2 6.28318530717959
  40. // Comment the lines that you don't want to use.
  41. // 要模拟FFT,请注释掉其他的预定义
  42. // 此处也可以全部注释掉,在MDK的工程属性->"C/C++"->"Preprocessor Symbols"-"Define:"中添加NPT_XXX项目
  43. // 但是这样做法的缺点是每次修改XXX数据,都会导致MDK下次编译时会编译全部文件,速度太慢。
  44. //#define NPT_64 64
  45. #define NPT_256 256
  46. //#define NPT_1024 1024

  47. // N=64,Fs/N=50Hz,Max(Valid)=1600Hz
  48. // 64点FFt,采样率3200Hz,频率分辨率50Hz,测量最大有效频率1600Hz
  49. #ifdef NPT_64
  50. #define NPT 64
  51. #define Fs  3200
  52. #endif

  53. // N=256,Fs/N=25Hz,Max(Valid)=3200Hz
  54. // 256点FFt,采样率6400Hz,频率分辨率25Hz,测量最大有效频率3200Hz
  55. #ifdef NPT_256
  56. #define NPT 256
  57. #define Fs  6400
  58. #endif

  59. // N=1024,Fs/N=5Hz,Max(Valid)=2560Hz
  60. // 1024点FFt,采样率5120Hz,频率分辨率5Hz,测量最大有效频率2560Hz
  61. #ifdef NPT_1024
  62. #define NPT 1024
  63. #define Fs  5120
  64. #endif

  65. /*
  66. *********************************************************************************************************
  67. *                                       LOCAL GLOBAL VARIABLES
  68. *********************************************************************************************************
  69. */
  70. extern  uint16_t  TableFFT[];
  71. long lBUFIN[NPT];         /* Complex input vector */
  72. long lBUFOUT[NPT];        /* Complex output vector */
  73. long lBUFMAG[NPT];/* Magnitude vector */
  74. /*
  75. *********************************************************************************************************
  76. *                                      LOCAL FUNCTION PROTOTYPES
  77. *********************************************************************************************************
  78. */
  79. void dsp_asm_powerMag(void);

  80. /*
  81. *********************************************************************************************************
  82. *   Initialize data tables for lBUFIN
  83. * 模拟采样数据,采样数据中包含3种频率正弦波:50Hz,2500Hz,2550Hz
  84. * lBUFIN数组中,每个单元数据高字(高16位)中存储采样数据的实部,低字(低16位)存储采样数据的虚部(总是为0)
  85. *********************************************************************************************************
  86. */
  87. void  dsp_asm_init()
  88. {
  89.   u16 i=0;
  90.   float fx;
  91.   for(i=0;i<NPT;i++)
  92.   {
  93.     fx  = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs);
  94.     lBUFIN[i] = ((s16)fx)<<16;
  95.   }
  96. }

  97. /*
  98. *********************************************************************************************************
  99. *   Test FFT,calculate powermag
  100. *   进行FFT变换,并计算各次谐波幅值
  101. *********************************************************************************************************
  102. */
  103. void  dsp_asm_test()
  104. {
  105. // 根据预定义选择合适的FFT函数
  106. #ifdef NPT_64
  107.   cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);
  108. #endif

  109. #ifdef NPT_256
  110.   cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);
  111. #endif

  112. #ifdef NPT_1024
  113.   cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);
  114. #endif

  115.   // 计算幅值
  116.   dsp_asm_powerMag();

  117. //  printf("No. Freq      Power\n");
  118. //  for(i=0;i<NPT/2;i++)
  119. //  {
  120. //    printf("%4d,%4d,%10d,%10d,%10d\n",i,(u16)((float)i*Fs/NPT),lBUFMAG[i],(lBUFOUT[i]>>16),(lBUFOUT[i]&0xffff));
  121. //  }
  122. //  printf("*********END**********\r\n");
  123. }
  124. /*
  125. *********************************************************************************************************
  126. *   Calculate powermag
  127. *   计算各次谐波幅值
  128. *   先将lBUFOUT分解成实部(X)和虚部(Y),然后计算赋值(sqrt(X*X+Y*Y)
  129. *********************************************************************************************************
  130. */
  131. void dsp_asm_powerMag(void)
  132. {
  133.   s16 lX,lY;
  134.   u32 i;
  135.   for(i=0;i<NPT/2;i++)
  136.   {
  137.     lX  = (lBUFOUT[i] << 16) >> 16;
  138.     lY  = (lBUFOUT[i] >> 16);
  139.     {
  140.     float X    = NPT * ((float)lX) /32768;
  141.     float Y    = NPT * ((float)lY) /32768;
  142.     float Mag = sqrt(X*X + Y*Y)/NPT;
  143.     lBUFMAG[i]    = (u32)(Mag * 65536);
  144.     }
  145.   }
  146. }


 楼主| wahahaheihei 发表于 2016-11-5 19:29 | 显示全部楼层

256点FFT运算结果图(局部):

3315212275699508119.bmp

上图中,数组下标X对应的谐波频率为:N×Fs/256=N×6400/256=N*25Hz.

lBUFMAG[2] 对应 2×25 =50Hz谐波幅值

lBUFMAG[100] 对应 100×25=2500Hz谐波幅值

lBUFMAG[102] 对应 102×25=2550Hz谐波幅值


// 1024点FFT运算结果图(局部):

4848687948817826435.bmp

上图中,数组下标X对应的谐波频率为:N×Fs/1024=N×5120/1024=N*5Hz.

lBUFMAG[10] 对应 10×5 =50Hz谐波幅值

lBUFMAG[500] 对应 500×5=2500Hz谐波幅值

lBUFMAG[510] 对应 510×5=2550Hz谐波幅值


该工程中模拟信号源为:4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs)

信号为1个50Hz、1个2500Hz、1个2550Hz的正弦波混合信号,幅值为均为4000。


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

本版积分规则

231

主题

3196

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部