app_fft.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "app_fft.h"
  2. #include "FreeRTOS.h"
  3. #include "queue.h"
  4. #include "string.h"
  5. #include <math.h>
  6. #include "stdlib.h"
  7. #include "hal_sc7a20.h"
  8. #define FFT_SIZE 128
  9. #define PI 3.14159265358979
  10. creal_T S0[FFT_SIZE];
  11. creal_T S1[FFT_SIZE];
  12. creal_T S2[FFT_SIZE];
  13. QueueHandle_t FFT_DataQueueHandle;
  14. static void cmul(creal_T a,creal_T b,creal_T *c)
  15. {
  16. c->re = a.re * b.re - a.im * b.im;
  17. c->im = a.re * b.im + a.im * b.re;
  18. }
  19. static void cadd(creal_T a,creal_T b,creal_T *c)
  20. {
  21. c->re = a.re + b.re;
  22. c->im = a.im + b.im;
  23. }
  24. static void csub(creal_T a,creal_T b,creal_T *c)
  25. {
  26. c->re = a.re - b.re;
  27. c->im = a.im - b.im;
  28. }
  29. static void RaderReverse(creal_T *X, uint16_T N)
  30. {
  31. uint16_T i;
  32. uint16_T j;
  33. uint16_T k;
  34. creal_T temp;
  35. j = N/2;
  36. for(i = 1; i < N - 1; i++)
  37. {
  38. if(i < j)
  39. {
  40. temp = X[j];
  41. X[j] = X[i];
  42. X[i] = temp;
  43. }
  44. k = N/2;
  45. while(k <= j)
  46. {
  47. j = j - k;
  48. k = k/2;
  49. }
  50. j = j + k;
  51. }
  52. }
  53. static int fft_cmp(const void*p1,const void*p2)
  54. {
  55. return (*(struct _fft_Freq*)p2).amp>(*(struct _fft_Freq*)p1).amp ? 1 : -1;
  56. }
  57. static void fft(fft_type *fft_data,creal_T *X, creal_T *W, uint16_T N, real_T *returnFreq, real_T *returnP) // N为偶数
  58. {
  59. uint16_T i = 0;
  60. uint16_T j = 0;
  61. uint16_T k = 0;
  62. uint16_T l = 0;
  63. creal_T up;
  64. creal_T down;
  65. creal_T product;
  66. // 变换
  67. RaderReverse(X, N);
  68. for (i = 0; i < log(N) / log(2); i++)
  69. {
  70. l = 1 << i;
  71. for (j = 0; j < N; j += 2 * l)
  72. {
  73. for (k = 0; k < l; k++)
  74. {
  75. cmul(X[j + k + l], W[N * k / 2 / l], &product);
  76. cadd(X[j + k], product, &up);
  77. csub(X[j + k], product, &down);
  78. X[j + k] = up;
  79. X[j + k + l] = down;
  80. }
  81. }
  82. }
  83. // 计算幅值
  84. for (i = 0; i < N/2+1; i++)
  85. {
  86. if(i==0||i==N/2)
  87. {
  88. fft_data[i].amp = sqrt((X[i].im) * (X[i].im) + (X[i].re) * (X[i].re)) / N;
  89. }
  90. else
  91. {
  92. fft_data[i].amp = 2*sqrt((X[i].im) * (X[i].im) + (X[i].re) * (X[i].re)) / N;
  93. }
  94. }
  95. // 从大到小 排序
  96. qsort(fft_data,sizeof(fft_data) / sizeof(fft_data[0]),sizeof(fft_data[0]),fft_cmp);
  97. for (i = 0; i < 5; i++)
  98. {
  99. returnFreq[i] = fft_data[i].freq;
  100. returnP[i] = fft_data[i].amp;
  101. }
  102. }
  103. void fft_task(void *pvParameters)
  104. {
  105. uint16_t i = 0;
  106. uint16_t freq = 500;
  107. creal_T W[FFT_SIZE];
  108. fft_type fft_data[FFT_SIZE/2+1];
  109. int16_t sc7a20_data_test[3];
  110. fft_data_t fft_data_sort;
  111. // 计算频率
  112. for (i = 0; i < FFT_SIZE / 2 + 1; i++)
  113. {
  114. fft_data[i].freq = freq * i / FFT_SIZE;
  115. }
  116. for (i = 0; i < FFT_SIZE; i++)
  117. {
  118. W[i].re = cos(2 * PI / FFT_SIZE * i);
  119. W[i].im = -sin(2 * PI / FFT_SIZE * i);
  120. }
  121. FFT_DataQueueHandle = xQueueCreate(1, sizeof(fft_type));
  122. SC7A20_Init();
  123. while(1)
  124. {
  125. for(int i = 0;i < FFT_SIZE;i++)
  126. {
  127. SC7A20_GetInfo(sc7a20_data_test);
  128. S0[i].re = (real_T)sc7a20_data_test[0];
  129. S0[i].im=0;
  130. S1[i].re = (real_T)sc7a20_data_test[1];
  131. S1[i].im=0;
  132. S2[i].re = (real_T)sc7a20_data_test[2];
  133. S2[i].im=0;
  134. //memcpy(xyzData,sc7a20_data_test,sizeof(xyzData)); //原始值发送
  135. vTaskDelay(1);
  136. }
  137. fft(fft_data,S0,W,FFT_SIZE,fft_data_sort.returnFreq[0],fft_data_sort.returnP[0]);
  138. fft(fft_data,S1,W,FFT_SIZE,fft_data_sort.returnFreq[1],fft_data_sort.returnP[1]);
  139. fft(fft_data,S2,W,FFT_SIZE,fft_data_sort.returnFreq[2],fft_data_sort.returnP[2]);
  140. xQueueOverwrite(FFT_DataQueueHandle,&fft_data);
  141. vTaskDelay(1000);
  142. }
  143. }