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

📄 fft_new_test.lst

📁 在c8051平台上实现的FFT运算
💻 LST
📖 第 1 页 / 共 2 页
字号:
 224          03.名称:BitReverse
 225             入口:BR_Array[]:
 226                    -操作的对象数组。
 227             出口:无
 228             功能:对经过为反向的地址重新排序
 229                  数组BRTable[]被用来查找哪个值要被交换,只有一半的值被存储在数组中,另一半通过镜像前一半
 230                          得到。
 231          =================================================================================================*/
 232          void BitReverse(int BR_Array[])
 233          {
 234   1      #if(NUM_FFT>=512)
                unsigned int swapA,swapB,sw_cnt;
C51 COMPILER V7.50   FFT_NEW_TEST                                                          07/26/2007 09:57:47 PAGE 5   

              #endif
 237   1      
 238   1      #if(NUM_FFT<=256)
 239   1        unsigned char swapA,swapB,sw_cnt;
 240   1      #endif
 241   1      
 242   1        int TempStore;
 243   1        for(sw_cnt=1;sw_cnt<NUM_FFT/2;sw_cnt++)//第一部分的交换
 244   1        {
 245   2          swapA=sw_cnt;                        //保存当前位置
 246   2          swapB=BRTable[sw_cnt]*2;             //找到位反向索引
 247   2          if(swapB>swapA)                      //如果位反向索引值比当前值大则交换
 248   2          {                                   
 249   3             TempStore=BR_Array[swapA];
 250   3             BR_Array[swapA]=BR_Array[swapB];
 251   3             BR_Array[swapB]=TempStore; 
 252   3          } 
 253   2          swapA+=NUM_FFT/2;                    //第二部分的交换
 254   2          swapB++; 
 255   2          if (swapB>swapA)
 256   2          {
 257   3             TempStore=BR_Array[swapA];
 258   3             BR_Array[swapA]=BR_Array[swapB];
 259   3             BR_Array[swapB]=TempStore;
 260   3          }
 261   2        }
 262   1      }
 263          /*=================================================================================================
 264          04.名称:IntFFT
 265             入口:ReArray[]:
 266                  ImArray[]:
 267             出口:无
 268             功能:FFT函数,对输入数组ReArray[]执行时间抽取的基2的FFT算法。在FFT算法的每一步,都要执行蝶形
 269                  方程:
 270          
 271                           Re1=Re1+(Cos(x)*Re2+Sin(x)*Im2)
 272                       Re2=Re1-(Cos(x)*Re2+Sin(x)*Im2)
 273                       Im1=Im1+(Cos(x)*Im2-Sin(x)*Re2)
 274                       Im2=Im1-(Cos(x)*Im2-Sin(x)*Re2)
 275          
 276                          程序使用如下值计算上式:
 277          
 278                               Re1=ReArray[indexA],Re2=ReArray[indexB]
 279                       Im1=ImArray[indexA],Im2=ImArray[indexB]
 280          
 281                          x =角度: 2*pi*(sin_index/NUM_FFT)单位:弧度;存储在代码空间SinTable[]数组中
 282          
 283                          关键点:
 284                               1. 实部的数据在ReArray[]数组中,2的幂,以16-bit二进制格式存放,虚部假设全为0
 285                                      存放在ImArray[]数组中。
 286                                   2.     实部假设被以位反向格式存储。
 287                                   3. 正弦和余弦值被事先计算好存放在表中,事实上,表中只保存了1/4周期的正弦值。
 288                                   4. 为了优化代码,只用整形数计算(没有浮点操作),这样可以节省存储空间。FFT所
 289                                      有的中间计算结果都以16-bit形式存储,故程序的精度有限。当输入数据少于16-bit
 290                                          时,数据左对齐在执行FFT可产生最好的计算结果。
 291                                   5. FFT的算法为基-2算法,所以,采样点的个数必须为2^N,N为整数。最少的采样点个数
 292                                      为4,常数NUM_FFT定义了采样点的个数。
 293                                   6. 对输入数据进行优化,只有实部输入,虚部全部设置为0。在这一步中,删除了不必要
 294                                      的重复部分,对于角度0这一点的计算,所有的sin值都时0,所有的cos值都是1。另外
 295                                          由于虚部为0,故计算时的值也都为等于0。
 296          =================================================================================================*/
 297          void IntFFT(int ReArray[],int ImArray[])
C51 COMPILER V7.50   FFT_NEW_TEST                                                          07/26/2007 09:57:47 PAGE 6   

 298          {
 299   1      #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
 303   1      
 304   1      #if(NUM_FFT<=256)
 305   1        unsigned char sin_index,g_cnt,s_cnt;         // Keeps track of the proper index
 306   1        unsigned char indexA,indexB;                 // locations for each calculation
 307   1      #endif
 308   1      
 309   1        unsigned int group=NUM_FFT/4,stage=2;
 310   1        long CosVal,SinVal;
 311   1        long TempImA,TempImB,TempReA,TempReB,TempReA2,TempReB2;
 312   1        IBALONG ReTwid,ImTwid,TempL;
 313   1      
 314   1        indexA=0;
 315   1        for(g_cnt=0;g_cnt<NUM_FFT/2;g_cnt++)
 316   1        {
 317   2          indexB=indexA+1;
 318   2          TempReA=ReArray[indexA];
 319   2          TempReB=ReArray[indexB];
 320   2        
 321   2          TempL.l=(long)TempReA+TempReB;                 //计算新的ReArray[indexA]的值
 322   2          if((TempL.l<0)&&(0x01&TempL.b[3])) TempReA2=(TempL.l>>1)+1;
 323   2          else TempReA2=TempL.l>>1;
 324   2           
 325   2          TempL.l=(long)TempReA-TempReB;                 //计算新的ReArray[indexB]的值
 326   2          if((TempL.l<0)&&(0x01&TempL.b[3])) ReArray[indexB]=(TempL.l>>1)+1;
 327   2          else ReArray[indexB]=TempL.l>>1;
 328   2      
 329   2          ReArray[indexA]=TempReA2;
 330   2          ImArray[indexA]=0;                         //将虚部设置为0
 331   2          ImArray[indexB]=0;
 332   2          indexA=indexB+1;
 333   2        }
 334   1        while(stage<=NUM_FFT/2)
 335   1        {
 336   2          indexA=0;
 337   2          sin_index=0;
 338   2          for(g_cnt=0;g_cnt<group;g_cnt++)
 339   2          {
 340   3            for(s_cnt=0;s_cnt<stage;s_cnt++)
 341   3            {
 342   4              indexB=indexA+stage;
 343   4      
 344   4              TempReA=ReArray[indexA];
 345   4              TempReB=ReArray[indexB];
 346   4              TempImA=ImArray[indexA];
 347   4              TempImB=ImArray[indexB];
 348   4      
 349   4              if(sin_index==0)                //"x"=0弧度
 350   4              {
 351   5                TempL.l=(long)TempReA+TempReB;//计算新的ReArray[indexA]的值
 352   5                if((TempL.l<0)&&(0x01&TempL.b[3])) TempReA2=(TempL.l>>1)+1;
 353   5                else TempReA2=TempL.l>>1;
 354   5      
 355   5                TempL.l=(long)TempReA-TempReB;//计算新的ReArray[indexB]的值
 356   5                if((TempL.l<0)&&(0x01&TempL.b[3])) TempReB2=(TempL.l>>1)+1;
 357   5                else TempReB2=TempL.l>>1;
 358   5      
 359   5                TempL.l=(long)TempImA-TempImB;//计算新的ImArray[indexB]的值
C51 COMPILER V7.50   FFT_NEW_TEST                                                          07/26/2007 09:57:47 PAGE 7   

 360   5                if((TempL.l<0)&&(0x01&TempL.b[3])) TempImB=(TempL.l>>1)+1;
 361   5                else TempImB=TempL.l>>1;
 362   5      
 363   5                TempL.l=(long)TempImA+TempImB;//计算新的ImArray[indexA]的值
 364   5                if((TempL.l<0)&&(0x01&TempL.b[3])) TempImA=(TempL.l>>1)+1;
 365   5                else TempImA=TempL.l>>1;
 366   5              }
 367   4              else if(sin_index==NUM_FFT/4)   //"x"=pi/2弧度
 368   4              {
 369   5                TempL.l=(long)TempReA-TempImB;//计算新的ReArray[indexB]的值
 370   5                if((TempL.l<0)&&(0x01&TempL.b[3])) TempReB2=(TempL.l>>1)+1;
 371   5                else TempReB2=TempL.l>>1;
 372   5      
 373   5                TempL.l=(long)TempReA+TempImB;//计算新的ReArray[indexA]的值
 374   5                if((TempL.l<0)&&(0x01&TempL.b[3])) TempReA2=(TempL.l>>1)+1;
 375   5                else TempReA2=TempL.l>>1;
 376   5      
 377   5                TempL.l=(long)TempImA+TempReB;//计算新的ImArray[indexB]的值
 378   5                if((TempL.l<0)&&(0x01&TempL.b[3])) TempImB=(TempL.l>>1)+1;
 379   5                else TempImB=TempL.l>>1;
 380   5      
 381   5                TempL.l=(long)TempImA-TempReB;//计算新的ImArray[indexA]的值
 382   5                if((TempL.l<0)&&(0x01&TempL.b[3])) TempImA=(TempL.l>>1)+1;
 383   5                else TempImA=TempL.l>>1;
 384   5              }
 385   4              else
 386   4              {
 387   5                if(sin_index>NUM_FFT/4)               //如果没有上述情况,蝶形运算中的sin和cos值将通过查表得到。
 388   5                {
 389   6                  SinVal=SinTable[(NUM_FFT/2)-sin_index];
 390   6                  CosVal=-SinTable[sin_index -(NUM_FFT/4)];
 391   6                }
 392   5                else
 393   5                {
 394   6                  SinVal=SinTable[sin_index];
 395   6                  CosVal=SinTable[(NUM_FFT/4)-sin_index];
 396   6                }                                                             //蝶形运算方程通过sin值和cos值来计算
 397   5                ReTwid.l=((long)TempReB*CosVal)+((long)TempImB*SinVal);       
 398   5                ImTwid.l=((long)TempImB*CosVal)-((long)TempReB*SinVal);
 399   5                
 400   5                TempL.i[1]=0;                                 //计算新的ReArray[indexA]的值
 401   5                TempL.i[0]=TempReA;                   
 402   5                TempL.l=TempL.l>>1;
 403   5                ReTwid.l+=TempL.l;
 404   5                if((ReTwid.l<0)&&(ReTwid.i[1])) TempReA2=ReTwid.i[0]+1;
 405   5                else TempReA2=ReTwid.i[0];
 406   5      
 407   5                TempL.l=TempL.l<<1;               //计算新的ReArray[indexB]的值
 408   5                TempL.l-=ReTwid.l;
 409   5                if((TempL.l<0)&&(TempL.i[1]))   TempReB2=TempL.i[0]+1;
 410   5                else TempReB2=TempL.i[0];
 411   5      
 412   5                TempL.i[1]=0;                                 //计算新的ImArray[indexA]的值
 413   5                TempL.i[0]=TempImA;
 414   5                TempL.l=TempL.l>>1;
 415   5                ImTwid.l+=TempL.l;
 416   5                if((ImTwid.l<0)&&(ImTwid.i[1])) TempImA=ImTwid.i[0]+1;
 417   5                else TempImA=ImTwid.i[0];
 418   5      
 419   5                TempL.l= TempL.l<<1;                  //计算新的ImArray[indexB]的值
 420   5                TempL.l-=ImTwid.l;
 421   5                if((TempL.l<0)&&(TempL.i[1]))   TempImB=TempL.i[0]+1;
C51 COMPILER V7.50   FFT_NEW_TEST                                                          07/26/2007 09:57:47 PAGE 8   

 422   5                else TempImB=TempL.i[0];
 423   5              }
 424   4              ReArray[indexA]=TempReA2;
 425   4              ReArray[indexB]=TempReB2;
 426   4              ImArray[indexA]=TempImA;
 427   4              ImArray[indexB]=TempImB;
 428   4              indexA++;
 429   4              sin_index+=group;
 430   4            }
 431   3            indexA=indexB+1;
 432   3            sin_index=0;
 433   3          }
 434   2          group/=2;
 435   2          stage*=2;
 436   2        }
 437   1      }
 438          /*=================================================================================================
 439          12.名称:ADC0_ISR
 440             入口:无
 441             出口:无
 442             功能:ADC0中断服务子程序
 443          =================================================================================================*/
 444          void ADC0_ISR(void) interrupt 15 using 3
 445          {
 446   1        ADCINT=0;                       //清ADC转换标志位
 447   1        Real[ADC_Index]=ADC0;           //存ADC的转换值
 448   1        ADC_Index++;                    //采样次数加1
 449   1        if (ADC_Index>=NUM_FFT)         //达到采样数
 450   1        {
 451   2          Conversion_Set_Complete=1;    //标志主程序
 452   2          EIE2&=~0x02;                  //ADC中断禁能
 453   2        }
 454   1      }
 455          /*-----------------------------------------------------------------------------------------------*/
 456          //FFT_New_Test.c

C51 COMPILATION COMPLETE.  0 WARNING(S),  6 ERROR(S)

⌨️ 快捷键说明

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