⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 int_fft.lst

📁 基于8051F单片机,实现1024点的FFT 用C 语言实现的.效果与FPGA实现相同.
💻 LST
📖 第 1 页 / 共 2 页
字号:
C51 COMPILER V8.02   INT_FFT                                                               05/09/2008 21:51:23 PAGE 1   


C51 COMPILER V8.02, COMPILATION OF MODULE INT_FFT
OBJECT MODULE PLACED IN Int_FFT.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE Int_FFT.c BROWSE DEBUG OBJECTEXTEND

line level    source

   1          #include "common.h"
   2          #include "Int_FFT.h"
   3          #include "adc0.h"
   4          //-----------------------------------------------------------------------------
   5          // Int_FFT
   6          //-----------------------------------------------------------------------------
   7          //
   8          // Performs a Radix-2 Decimation-In-Time FFT on the input array ReArray[]
   9          //
  10          // During each stage of the FFT, the values are calculated using a set of
  11          // "Butterfly" equations, as listed below:
  12          //
  13          // Re1 = Re1 + (Cos(x)*Re2 + Sin(x)*Im2)
  14          // Re2 = Re1 - (Cos(x)*Re2 + Sin(x)*Im2)
  15          // Im1 = Im1 + (Cos(x)*Im2 - Sin(x)*Re2)
  16          // Im2 = Im1 - (Cos(x)*Im2 - Sin(x)*Re2)
  17          //
  18          // The routine implements this calculation using the following values:
  19          //
  20          // Re1 = ReArray[indexA], Re2 = ReArray[indexB]
  21          // Im1 = ImArray[indexA], Im2 = ImArray[indexB]
  22          // x = the angle: 2*pi*(sin_index/NUM_FFT), in radians.  The necessary values
  23          //    are stored in code space in the SinTable[] array.
  24          //
  25          //
  26          // Key Points for using this FFT routine:
  27          //
  28          // 1) It expects REAL data (in ReArray[]), in 2's complement, 16-bit binary
  29          //    format and assumes a value of 0 for all imaginary locations
  30          //    (in ImArray[]).
  31          //
  32          // 2) It expects the REAL input data to be sorted in bit-reversed index order.
  33          //
  34          // 3) SIN and COS values are retrieved and calculated from a table consisting
  35          //    of 1/4 of a period of a SIN function.
  36          //
  37          // 4) It is optimized to use integer math only (no floating-point operations),
  38          //    and for storage space.  The input, all intermediate stages, and the
  39          //    output of the FFT are stored as 16-bit INTEGER values. This limits the
  40          //    precision of the routine.  When using input data of less than 16-bits,
  41          //    the best results are produced by left-justifying the data prior to
  42          //    windowing and performing the FFT.
  43          //
  44          // 5) The algorithm is a Radix-2 type, meaning that the number of samples must
  45          //    be 2^N, where N is an integer.  The minimum number of samples to process
  46          //    is 4.  The constant NUM_FFT contains the number of samples to process.
  47          //
  48          //
  49          
  50          int xdata Real[NUM_FFT] _at_ DATA_BEGIN;
  51          int xdata Imag[NUM_FFT] _at_ (DATA_BEGIN + (NUM_FFT * 2));
  52          
  53          void Int_FFT(int ReArray[], int ImArray[])
  54          {
  55   1      
C51 COMPILER V8.02   INT_FFT                                                               05/09/2008 21:51:23 PAGE 2   

  56   1      #if (NUM_FFT >= 512)
  57   1      unsigned int sin_index, g_cnt, s_cnt;        // Keeps track of the proper index
  58   1      unsigned int indexA, indexB;                 // locations for each calculation
  59   1      #endif
  60   1      
  61   1      #if (NUM_FFT <= 256)
              unsigned char sin_index, g_cnt, s_cnt;       // Keeps track of the proper index
              unsigned char indexA, indexB;                // locations for each calculation
              #endif
  65   1      
  66   1      unsigned int group = NUM_FFT/4, stage = 2;
  67   1      long CosVal, SinVal;
  68   1      long TempImA, TempImB, TempReA, TempReB, TempReA2, TempReB2;
  69   1      IBALONG ReTwid, ImTwid, TempL;
  70   1      
  71   1      // FIRST STAGE - optimized for REAL input data only.  This will set all
  72   1      // Imaginary locations to zero.
  73   1      //
  74   1      // Shortcuts have been taken to remove unnecessary multiplications during this
  75   1      // stage. The angle "x" is 0 radians for all calculations at this point, so
  76   1      // the SIN value is equal to 0.0 and the COS value is equal to 1.0.
  77   1      // Additionally, all Imaginary locations are assumed to be '0' in this stage of
  78   1      // the algorithm, and are set to '0'.
  79   1      
  80   1         indexA = 0;
  81   1         for (g_cnt = 0; g_cnt < NUM_FFT/2; g_cnt++)
  82   1         {
  83   2            indexB = indexA + 1;
  84   2      
  85   2            TempReA = ReArray[indexA];
  86   2            TempReB = ReArray[indexB];
  87   2      
  88   2            // Calculate new value for ReArray[indexA]
  89   2            TempL.l = (long)TempReA + TempReB;
  90   2            if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
  91   2               TempReA2 = (TempL.l >> 1) + 1;
  92   2            else TempReA2 = TempL.l >> 1;
  93   2      
  94   2            // Calculate new value for ReArray[indexB]
  95   2            TempL.l = (long)TempReA - TempReB;
  96   2            if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
  97   2               ReArray[indexB] = (TempL.l >> 1) + 1;
  98   2            else ReArray[indexB] = TempL.l >> 1;
  99   2      
 100   2            ReArray[indexA] = TempReA2;
 101   2      
 102   2            ImArray[indexA] = 0;                   // set Imaginary locations to '0'
 103   2            ImArray[indexB] = 0;
 104   2      
 105   2            indexA = indexB + 1;
 106   2         }
 107   1      
 108   1      // END OF FIRST STAGE
 109   1      
 110   1      
 111   1      while (stage <= NUM_FFT/2)
 112   1      {
 113   2         indexA = 0;
 114   2         sin_index = 0;
 115   2      
 116   2         for (g_cnt = 0; g_cnt < group; g_cnt++)
 117   2         {
C51 COMPILER V8.02   INT_FFT                                                               05/09/2008 21:51:23 PAGE 3   

 118   3            for (s_cnt = 0; s_cnt < stage; s_cnt++)
 119   3            {
 120   4               indexB = indexA + stage;
 121   4      
 122   4               TempReA = ReArray[indexA];
 123   4               TempReB = ReArray[indexB];
 124   4               TempImA = ImArray[indexA];
 125   4               TempImB = ImArray[indexB];
 126   4      
 127   4      // The following first checks for the special cases when the angle "x" is
 128   4      // equal to either 0 or pi/2 radians.  In these cases, unnecessary
 129   4      // multiplications have been removed to improve the processing speed.
 130   4      
 131   4               if (sin_index == 0)  // corresponds to "x" = 0 radians
 132   4               {
 133   5      
 134   5                  // Calculate new value for ReArray[indexA]
 135   5                  TempL.l = (long)TempReA + TempReB;
 136   5                  if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
 137   5                     TempReA2 = (TempL.l >> 1) + 1;
 138   5                  else TempReA2 = TempL.l >> 1;
 139   5      
 140   5                  // Calculate new value for ReArray[indexB]
 141   5                  TempL.l = (long)TempReA - TempReB;
 142   5                  if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
 143   5                     TempReB2 = (TempL.l >> 1) + 1;
 144   5                  else TempReB2 = TempL.l >> 1;
 145   5      
 146   5                  // Calculate new value for ImArray[indexB]
 147   5                 TempL.l = (long)TempImA - TempImB;
 148   5                  if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
 149   5                     TempImB = (TempL.l >> 1) + 1;
 150   5                  else TempImB = TempL.l >> 1;
 151   5      
 152   5                  // Calculate new value for ImArray[indexA]
 153   5                  TempL.l = (long)TempImA + TempImB;
 154   5                  if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
 155   5                     TempImA = (TempL.l >> 1) + 1;
 156   5                  else TempImA = TempL.l >> 1;
 157   5      
 158   5               }
 159   4               else if (sin_index == NUM_FFT/4) // corresponds to "x" = pi/2 radians
 160   4               {
 161   5      
 162   5                  // Calculate new value for ReArray[indexB]
 163   5                  TempL.l = (long)TempReA - TempImB;
 164   5                  if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
 165   5                  TempReB2 = (TempL.l >> 1) + 1;
 166   5                  else TempReB2 = TempL.l >> 1;
 167   5      
 168   5                  // Calculate new value for ReArray[indexA]
 169   5                  TempL.l = (long)TempReA + TempImB;
 170   5                  if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
 171   5                     TempReA2 = (TempL.l >> 1) + 1;
 172   5                  else TempReA2 = TempL.l >> 1;
 173   5      
 174   5                  // Calculate new value for ImArray[indexB]
 175   5                  TempL.l = (long)TempImA + TempReB;
 176   5                  if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
 177   5                     TempImB = (TempL.l >> 1) + 1;
 178   5                  else TempImB = TempL.l >> 1;
 179   5      
C51 COMPILER V8.02   INT_FFT                                                               05/09/2008 21:51:23 PAGE 4   

 180   5                  // Calculate new value for ImArray[indexA]
 181   5                  TempL.l = (long)TempImA - TempReB;
 182   5                  if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
 183   5                     TempImA = (TempL.l >> 1) + 1;
 184   5                  else TempImA = TempL.l >> 1;
 185   5      
 186   5               }
 187   4      
 188   4               else
 189   4               {
 190   5                  // If no multiplication shortcuts can be taken, the SIN and COS
 191   5                  // values for the Butterfly calculation are fetched from the
 192   5                  // SinTable[] array.
 193   5      
 194   5                  if (sin_index > NUM_FFT/4)
 195   5                  {
 196   6                     SinVal = SinTable[(NUM_FFT/2) - sin_index];
 197   6                     CosVal = -SinTable[sin_index - (NUM_FFT/4)];
 198   6                  }
 199   5                  else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -