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

📄 routine.c

📁 一种适合在单片机上运行的快速傅里叶算法
💻 C
字号:
void Bit_Reverse( int BR_Array[] )
{
          unsigned char  swapA,swapB,sw_cnt ;
          int            TempStore ;

         for(sw_cnt =1 ;sw_cnt <NUM_FFT/2 ;sw_cnt++ )
         {
             swapA = sw_cnt;
             swapB = BRTable[sw_cnt]*2 ;
             if( swapB>swapA )
             {
                 TempStore =BR_Array[ swapA ] ; 
                 BR_Array[ swapA ] = BR_Array[ swapB ] ;
                 BR_Array[ swapB ] = TempStore;
             }
             
             swapA += NUM_FFT/2 ;
             swapB++ ;
             if( swapB>swapA )
             {
                 TempStore =BR_Array[ swapA ] ; 
                 BR_Array[ swapA ] = BR_Array[ swapB ] ;
                 BR_Array[ swapB ] = TempStore;
             }
         }
}

//Int_FFT_A这个算法的循环和教科书上的有些不一样
//有L级运算   有group个蝴蝶运算   每个蝴蝶运算有stage个运算因子
//Int_FFT_A如果改为Int_FFT_B:有L级运算 ,有stage个运算因子 ,每个蝴蝶运算有有group个蝴蝶运算,这样会更加减少计算量
//因为因子的计算是查表进行的,用时很少,所以Int_FFT_B不会比Int_FFT_A快很多,没有必要进行改进了。
void  Int_FFT_A(int ReArray[] , int ImArray[] )
{
      unsigned char sin_index,g_cnt,s_cnt ;
      unsigned char indexA,indexB ;
      unsigned int  group = NUM_FFT/4,  stage = 2  ;
      long          CosVal,SinVal ;
      long          TempImA,  TempImB,  TempReA  ,   TempReB  , TempReA2  ,   TempReB2 ,TempImA2,  TempImB2 ;
      IBALONG       ReTwid ,  ImTwid,   TempL ;
      
      indexA = 0 ;
      for(g_cnt = 0 ; g_cnt < NUM_FFT/2 ; g_cnt++)  //这里是第1层运算,只有一个因子  这个因子有NUM_FFT/2个蝴蝶运算
      {
           indexB = indexA + 1 ;
           TempReA = ReArray[indexA] ;
           TempReB = ReArray[indexB] ; 
           
           TempL.l = (long)TempReA + (long)TempReB ; 
           if( (TempL.l < 0 ) && ( 0x01 & TempL.b[0] ) )
              TempReA2 =  ( TempL.l >> 1 ) + 1 ;
           else
              TempReA2 =   TempL.l >> 1 ;
              
           TempL.l = (long)TempReA - (long)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;
           ImArray[indexB]  = 0;
           
           indexA = indexB + 1 ;
      }
      
      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] ;
                   //计算
                   if(sin_index == 0)  //旋转因子是0    系数是1
                   {
                       //计算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 ;  
                          
                      //计算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 ;   
                      
                      //计算IMarray[indexA]      
                      TempL.l = (long)TempImA  - TempImB ;
                      if( (TempL.l < 0) && (0x01 & TempL.b[0]) )
                          TempImA2 = ( TempL.l >> 1 ) + 1 ;
                      else
                          TempImA2 =  TempL.l >> 1  ; 
                          
                      //计算IMarray[indexB]
                      TempL.l = (long)TempImA  - TempImB ;
                      if( (TempL.l < 0) && (0x01 & TempL.b[0]) )
                          TempImB2 = ( TempL.l >> 1 ) + 1 ;
                      else
                          TempImB2 =  TempL.l >> 1  ;    
                          
                      ReArray[indexA] = TempReA2 ;
                      ReArray[indexB] = TempReB2 ;
                      ImArray[indexA] = TempImA2 ;
                      ImArray[indexB] = TempImB2 ;
                   }
                   else if( sin_index == NUM_FFT/4)   //旋转因子是pi/2   系数是-i
                   {
                       //计算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 ; 
                          
                       //计算Imarray[indexa]
                       TempL.l = (long)TempImA - TempReB ;
                       if( (TempL.l < 0) && (0x01 & TempL.b[0]) )
                          TempImA2 = ( TempL.l >> 1 ) + 1 ;
                       else 
                          TempImA2 =  TempL.l >> 1 ;   
                          
                       //计算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 ; 
                          
                       //计算Imarray[indexb]
                       TempL.l = (long)TempImA + TempReB ;
                       if( (TempL.l < 0) && (0x01 & TempL.b[0]) )
                          TempImB2 = ( TempL.l >> 1 ) + 1 ;
                       else 
                          TempImB2 =  TempL.l >> 1 ; 
                       
                       ReArray[indexA] = TempReA2 ;
                       ReArray[indexB] = TempReB2 ;
                       ImArray[indexA] = TempImA2 ;
                       ImArray[indexB] = TempImB2 ;         
                   }
                   else   //旋转因子不是任何特殊值
                   {
                       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 ];
                       }
                       
                       ReTwid.l = ((long)TempReB * CosVal) +
                                  ((long)TempImB * SinVal)     ;
                       ImTwid.l = ((long)TempImB * CosVal) -
                                  ((long)TempReB * SinVal)     ;
                                  
                       //计算rearray[indexa]   
                       TempL.i[0] = 0 ;
                       TempL.i[1] = TempReA ;
                       TempL.l = TempL.l >> 1;
                       TempL.l += ReTwid.l ;
                       if((TempL.l < 0) && (TempL.i[0]))
                           TempReA2 = TempL.i[1] + 1 ;
                       else
                           TempReA2 = TempL.i[1]  ;
                           
                       //计算IMarray[indexa]
                       TempL.i[0] = 0 ;
                       TempL.i[1] = TempImA ;
                       TempL.l = TempL.l >> 1; 
                       TempL.l += ImTwid.l ; 
                       if((TempL.l < 0) && (TempL.i[0]))
                           TempImA2 = TempL.i[1] + 1 ;
                       else
                           TempImA2 = TempL.i[1]  ; 
                       
                       //计算rearray[indexB]  
                       TempL.i[0] = 0 ;
                       TempL.i[1] = TempReA ;  
                       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]  ;  
                       
                       //计算IMarray[indexB] 
                       TempL.i[0] = 0 ;
                       TempL.i[1] = TempImA ;
                       TempL.l = TempL.l >> 1; 
                       TempL.l -= ImTwid.l ; 
                       if((TempL.l < 0) && (TempL.i[0]))
                           TempImB2 = TempL.i[1] + 1 ;
                       else
                           TempImB2 = TempL.i[1]  ;
                           
                       ReArray[indexA] = TempReA2 ;
                       ReArray[indexB] = TempReB2 ;
                       ImArray[indexA] = TempImA2 ;
                       ImArray[indexB] = TempImB2 ;       
                   }
                 indexA++ ;
                 sin_index += group ;  
               }
               indexA = indexB + 1  ;
               sin_index = 0 ;
            }
            group /= 2 ;    //代表每级运算中有几个蝴蝶运算
            stage *= 2 ;    //代表第几级运算
      }
}


⌨️ 快捷键说明

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