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

📄 main.c

📁 基于msp4301611 的AD转换 及 FFT 算法
💻 C
📖 第 1 页 / 共 2 页
字号:
// Im1 = ImArray[indexA], Im2 = ImArray[indexB]
// x = the angle: 2*pi*(sin_index/NUM_FFT), in radians.  The necessary values
//    are stored in code space in the SinTable[] array.
//
//
// Key Points for using this FFT routine:
//
// 1) It expects REAL data (in ReArray[]), in 2's complement, 16-bit binary
//    format and assumes a value of 0 for all imaginary locations
//    (in ImArray[]).
//
// 2) It expects the REAL input data to be sorted in bit-reversed index order.
//
// 3) SIN and COS values are retrieved and calculated from a table consisting
//    of 1/4 of a period of a SIN function.
//
// 4) It is optimized to use integer math only (no floating-point operations),
//    and for storage space.  The input, all intermediate stages, and the
//    output of the FFT are stored as 16-bit INTEGER values. This limits the
//    precision of the routine.  When using input data of less than 16-bits,
//    the best results are produced by left-justifying the data prior to
//    windowing and performing the FFT.
//
// 5) The algorithm is a Radix-2 type, meaning that the number of samples must
//    be 2^N, where N is an integer.  The minimum number of samples to process
//    is 4.  The constant NUM_FFT contains the number of samples to process.
//
//
void Int_FFT(  int ReArray[],  int ImArray[])
{

#if (NUM_FFT >= 512)
unsigned int sin_index, g_cnt, s_cnt;        // Keeps track of the proper index
unsigned int indexA, indexB;                 // locations for each calculation
#endif

#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

unsigned int group = NUM_FFT/4, stage = 2;
long CosVal, SinVal;
long TempImA, TempImB, TempReA, TempReB, TempReA2, TempReB2;
IBALONG ReTwid, ImTwid, TempL;

// FIRST STAGE - optimized for REAL input data only.  This will set all
// Imaginary locations to zero.
//
// Shortcuts have been taken to remove unnecessary multiplications during this
// stage. The angle "x" is 0 radians for all calculations at this point, so
// the SIN value is equal to 0.0 and the COS value is equal to 1.0.
// Additionally, all Imaginary locations are assumed to be '0' in this stage of
// the algorithm, and are set to '0'.

   indexA = 0;
   for (g_cnt = 0; g_cnt < NUM_FFT/2; g_cnt++)
   {
      indexB = indexA + 1;

      TempReA = ReArray[indexA];
      TempReB = ReArray[indexB];

      // Calculate new value for ReArray[indexA]
      TempL.l = (long)TempReA + TempReB;
      if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
         TempReA2 = (TempL.l >> 1) + 1;
      else TempReA2 = TempL.l >> 1;

      // Calculate new value for ReArray[indexB]
      TempL.l = (long)TempReA - TempReB;
      if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
         ReArray[indexB] = (TempL.l >> 1) + 1;
      else ReArray[indexB] = TempL.l >> 1;

      ReArray[indexA] = TempReA2;

      ImArray[indexA] = 0;                   // set Imaginary locations to '0'
      ImArray[indexB] = 0;

      indexA = indexB + 1;
   }

// END OF FIRST STAGE


while (stage <= NUM_FFT/2)
{
   indexA = 0;
   sin_index = 0;

   for (g_cnt = 0; g_cnt < group; g_cnt++)
   {
      for (s_cnt = 0; s_cnt < stage; s_cnt++)
      {
         indexB = indexA + stage;

         TempReA = ReArray[indexA];
         TempReB = ReArray[indexB];
         TempImA = ImArray[indexA];
         TempImB = ImArray[indexB];

// The following first checks for the special cases when the angle "x" is
// equal to either 0 or pi/2 radians.  In these cases, unnecessary
// multiplications have been removed to improve the processing speed.

         if (sin_index == 0)  // corresponds to "x" = 0 radians
         {

            // Calculate new value for ReArray[indexA]
            TempL.l = (long)TempReA + TempReB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
               TempReA2 = (TempL.l >> 1) + 1;
            else TempReA2 = TempL.l >> 1;

            // Calculate new value for ReArray[indexB]
            TempL.l = (long)TempReA - TempReB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
               TempReB2 = (TempL.l >> 1) + 1;
            else TempReB2 = TempL.l >> 1;

            // Calculate new value for ImArray[indexB]
           TempL.l = (long)TempImA - TempImB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
               TempImB = (TempL.l >> 1) + 1;
            else TempImB = TempL.l >> 1;

            // Calculate new value for ImArray[indexA]
            TempL.l = (long)TempImA + TempImB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
               TempImA = (TempL.l >> 1) + 1;
            else TempImA = TempL.l >> 1;

         }
         else if (sin_index == NUM_FFT/4) // corresponds to "x" = pi/2 radians
         {

            // Calculate new value for ReArray[indexB]
            TempL.l = (long)TempReA - TempImB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
               TempReB2 = (TempL.l >> 1) + 1;
            else TempReB2 = TempL.l >> 1;

            // Calculate new value for ReArray[indexA]
            TempL.l = (long)TempReA + TempImB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
               TempReA2 = (TempL.l >> 1) + 1;
            else TempReA2 = TempL.l >> 1;

            // Calculate new value for ImArray[indexB]
            TempL.l = (long)TempImA + TempReB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
               TempImB = (TempL.l >> 1) + 1;
            else TempImB = TempL.l >> 1;

            // Calculate new value for ImArray[indexA]
            TempL.l = (long)TempImA - TempReB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
               TempImA = (TempL.l >> 1) + 1;
            else TempImA = TempL.l >> 1;

         }

         else
         {
            // If no multiplication shortcuts can be taken, the SIN and COS
            // values for the Butterfly calculation are fetched from the
            // SinTable[] array.

            if (sin_index > NUM_FFT/4)
            {
               SinVal = SinTable[(NUM_FFT/2) - sin_index];
               CosVal = -SinTable[sin_index - (NUM_FFT/4)];
            }
            else
            {
               SinVal = SinTable[sin_index];
               CosVal = SinTable[(NUM_FFT/4) - sin_index];
            }

            // The SIN and COS values are used here to calculate part of the
            // Butterfly equation
            ReTwid.l = ((long)TempReB * CosVal) +
                  ((long)TempImB * SinVal);

            ImTwid.l = ((long)TempImB * CosVal) -
                  ((long)TempReB * SinVal);

            // Using the values calculated above, the new variables
            // are computed

            // Calculate new value for ReArray[indexA]
            TempL.i[0] = 0;
            TempL.i[1] = TempReA;
            TempL.l = TempL.l >> 1;
            ReTwid.l += TempL.l;
            if ((ReTwid.l < 0)&&(ReTwid.i[0]))
               TempReA2 = ReTwid.i[1] + 1;
            else TempReA2 = ReTwid.i[1];

            // Calculate new value for ReArray[indexB]
            TempL.l = TempL.l << 1;
            TempL.l -= ReTwid.l;
            if ((TempL.l < 0)&&(TempL.i[0]))
               TempReB2 = TempL.i[1] + 1;
            else TempReB2 = TempL.i[1];

            // Calculate new value for ImArray[indexA]
            TempL.i[0] = 0;
            TempL.i[1] = TempImA;
            TempL.l = TempL.l >> 1;
            ImTwid.l += TempL.l;
            if ((ImTwid.l < 0)&&(ImTwid.i[0]))
               TempImA = ImTwid.i[1] + 1;
            else TempImA = ImTwid.i[1];

            // Calculate new value for ImArray[indexB]
            TempL.l = TempL.l << 1;
            TempL.l -= ImTwid.l;
            if ((TempL.l < 0)&&(TempL.i[0]))
               TempImB = TempL.i[1] + 1;
            else TempImB = TempL.i[1];

         }

         ReArray[indexA] = TempReA2;
         ReArray[indexB] = TempReB2;
         ImArray[indexA] = TempImA;
         ImArray[indexB] = TempImB;

         indexA++;
         sin_index += group;
      }                                      // END of stage FOR loop (s_cnt)
      indexA = indexB + 1;
      sin_index = 0;
   }                                         // END of group FOR loop (g_cnt)

   group /= 2;
   stage *= 2;
}                                            // END of While loop

}  // END Int_FFT



float cal_kk(unsigned char i)
{
  float  k11,t0,t1,t2;
  t0=*((float*)(Imag+512+2*(i-1)));
  t1=*((float*)(Imag+512+2*(i)));
  t2=*((float*)(Imag+512+2*(i+1)));

  if(t2>=t0)
  k11= t2/(t1+t2);
  else
  k11=-t0/(t1+t0);
  return(k11);
}
float abs1(unsigned char i)
{
  float  ff;
  long  kk;
           
  kk = ((long)Real[i] * Real[i]) + ((long)Imag[i] * Imag[i]);

  if(i==0)
  ff=  sqrt((float)kk);
  else 
  ff=2*sqrt((float)kk);  //|y(k)|/(1/2)  gain == 1/2;// -32768=<ff<=32767  
  return(ff);
}
float cal_f(unsigned char i )
{
  float ff;   
  ff=( (float)i+ cal_kk(i) )*fs/NUM_FFT;  
  if(ff<0.0)
  ff=0.0;
  if(i==0)
  ff=0.0;
  return(ff);
}
float cal_amp(unsigned char i)
{
   float am,b;   
   b = 3.141592654*cal_kk(i);
   am= b/sin(b)* (*((float*)(Imag+512+2*(i))))/32768.0*2.448;   
   if(i==0)
   am=0.0; 
   return(am);
}


void cal_fft(void)
{
    float  temp,max;
	unsigned int   i;
	//unsigned  char   a,b;
	
	max=0.0;	
	for(i=0;i<256;i++)
	{	 
	  temp=abs1(i);	  
	  //*********************//
	  *((float*)(Imag+512+2*i)) = temp;//
	  //*********************//
	  if( temp > max && (i!=0)  )
	  {
	    max=temp;
		index=i;
	  }	  
	}

	/*
        //for test **********************
	if(status==test_mode)
        {
	   max=0.0;temp =0.0;
	     if(enable)
		 {
			 if(ptr3==0)
			 fl=set_buffer_to_float();
			 if(ptr3==1)
		     fh=set_buffer_to_float1();		
			 dex=0;
			 if(fh>=fl)
			 {			 		 
				 a = (unsigned  char)(fl/(fs/N)); //
				 b = (unsigned  char)(fh/(fs/N)); //
				 for(i=a;i<=b;i++)
				 {
				   WDTCN = 0xA5;
				   temp=abs1(i);
			       if( temp > max && (i!=0) )
			       {
			          max=temp;
				      dex = i;
			       }	  					    
				 }
			 }		 		 		 
		 }		 
    }*/
        
}




















⌨️ 快捷键说明

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