这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 下载专区 » TMS320LF2407上实现快速傅里叶变换(FFT)

共3条 1/1 1 跳转至

TMS320LF2407上实现快速傅里叶变换(FFT)

菜鸟
2009-07-31 10:19:17     打赏

//TMS320LF2407上实现快速傅里叶变换(FFT)

//FFT的程序代码
//(1)主程序
#include     "f2407_c.h"
#include     "math.h"
#define      N     32   //    FFT变换的点数 
extern     void   fft(void);      
extern     void   resave(void); 
interrupt    void  phantom(void); 
void      sysinit(void);
extern    int input[2*N];    //    输入数据的存储数组
int      indati[N]={0};        
//    -----------------------------------------------------------------------------------
//    128 点 FFT所需的数据
//    采样函数:x=1/4+1/4cos(3*2*pi*f*t)+1/4cos(6*2*pi*f*t)+1/4cos(9*2*pi*f*t);
//    f=50Hz
//    -----------------------------------------------------------------------------------
/*    int indatr[N]={16394,15871,14425,12398,10276    ,8584   ,7767   ,8088    ,9557  ,
                     11913   , 14660    ,17155 ,   18724  ,  18802  ,  17044 ,   13411   , 8197 ,  1995 ,
                     -4389   ,-10071,   -14231  , -16255   ,-15844,   -13057   ,-8309 ,  -2296,   4125  ,
                     10079,    14819,    17843  ,  18969,    18342 ,   16394   ,13739 ,   11055   , 8950 
                     7848,   7921  ,  9070 ,   10961,    13110  ,  14992 ,   16159 ,   16334   ,547,
                     13792   , 11675  ,  9640 ,   8197  ,  7741,    8457,    10264  ,  12815  ,  15554 ,  
                     17812   ,18939  ,  18429  ,  16034  ,  11825 ,   6203  , -156,   -6405,   -11662  ,
                     -15165  , -16394 ,  -15165   ,-11662  , -6405  , -156  ,  6203 ,   11825  ,  16034,
                     18429,    18939  ,  17812  ,  15554 ,   12815   ,10264  ,  8457  ,  7741  , 8197,
                     9640 ,   11675,    13792,    15479 ,   16334 ,   16159,    14992  ,13110  ,  10961  ,
                     9070   ,7921 ,   7848  ,  8950 ,   11055 ,   13739  ,  16393  ,  18342 ,   18969   ,
                     17843  ,  14819  ,  10079   ,4125 ,  -2296 ,  -8309 ,  -13057  , -15844  , -16255  ,
                     -14231 ,  -10071   ,-4389  ,  1995 ,   8197   , 13411 ,   17044 ,   18802 ,   18724  ,
                     17155  ,  14660  ,  11913 ,   9557   ,8088  ,  7767,    8584   , 10276 ,   12398 ,
                     14425  ,  15871             ,
                     };*/
//   -----------------------------------------------------------------------------------
//   32点FFT所需的数据
//   采样函数:x=1/4+1/4cos(3*2*pi*f*t)+1/4cos(6*2*pi*f*t)+1/4cos(9*2*pi*f*t);
//   f=50Hz ;pi=π;
//   -----------------------------------------------------------------------------------
/*  int indatr[N]={16384, 10270,9551 ,18713 , 8192 ,-14222,-8304,14810,16384,7843,13102 ,15469,8192,12807,
                   18418,-0156,-16384,-0156,-16384, -0156,18418,12807,8192,15469,13102,7843,16383,14810,
                   -8304,-14222,8192,18713,9551,10270,
};*/

int indatr[N]={0x07ff, 0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,
               0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x07ff,0x0F801,
               0x0F801,0x0F801,0x0F801,0x0F801,0x0F801,0x0F801,0x0F801,
               0x0F801,0x0F801,0x0F801,0x0F801,0x0F801,0x0F801,0x0F801,
               0x0F801,
}; 

//   -----------------------------------------------------------------------------------                             

//    64点 FFT所需的数据
//   采样函数:x=1/4+1/4cos(3*2*pi*f*t)+1/4cos(6*2*pi*f*t)+1/4cos(9*2*pi*f*t);
//   f=50Hz
//   -----------------------------------------------------------------------------------
/*    int indatr[N]={16384 ,  14416,   10270,   7762,   9551 ,  14651 ,  18713,   17034,   8192 , -4387  ,-14222,-15834  ,-8304   ,4123  , 14810   ,18957 ,  16384  , 1
//   ---------------------------------------------------------------
//    128 点 FFT的sin 和 cos值存储表
//   ---------------------------------------------------------------
/*    const int sintab[N]={0x07fff,0x0,0x07fd9,0x0f9b9,0x07f62,0x0f375,0x07e9d,0x0ed38,
  0x07d8a,0x0e708,0x07c2a,0x0e0e7,0x07a7d,0x0dad8,0x07885,0x0d4e1,
  0x07642,0x0cf05,0x073b6,0x0c946,0x070e3,0x0c3aa,0x06dca,0x0be32,
  0x06A6C,0x0B8E4,0x066CE,0x0B3C1,0x062F1,0x0AECD,0x05ED6,0x0AA0C,
  0x05A81,0x0A57F,0x055F4,0x0A12A,0x05133,0x09D0F,0x04C3F,0x09932,
  0x0471C,0x09594,0x041CD,0x09237,0x03C56,0x08F1F,0x036B9,0x08C4B,
  0x030FB,0x089C0,0x02B1E,0x0877D,0x02527,0x08584,0x01F19,0x083D7,
  0x018F8,0x08277,0x012C7,0x08164,0x00C8B,0x0809F,0x00647,0x08029,
  0x00000,0x08001,0x0F9B9,0x08029,0x0F375,0x0809F,0x0ED39,0x08164,
  0x0E708,0x08277,0x0E0E7,0x083D7,0x0DAD9,0x08584,0x0D4E2,0x0877D,
  0x0CF05,0x089C0,0x0C947,0x08C4B,0x0C3AA,0x08F1F,0x0BE33,0x09237,
  0x0B8E4,0x09594,0x0B3C1,0x09932,0x0AECD,0x09D0F,0x0AA0C,0x0A12A,
  0x0A57F,0x0A57F,0x0A12A,0x0AA0C,0x09D0F,0x0AECD,0x09932,0x0B3C1,
  0x09594,0x0B8E4,0x09237,0x0BE33,0x08F1F,0x0C3AA,0x08C4B,0x0C947,
  0x089C0,0x0CF05,0x0877D,0x0D4E2,0x08584,0x0DAD9,0x083D7,0x0E0E7,
  0x08277,0x0E708,0x08164,0x0ED39,0x0809F,0x0F375,0x08029,0x0F9B9
};*/
//   ---------------------------------------------------------------
//   64点 FFT的sin 和 cos值存储表
//   ---------------------------------------------------------------   
/*    const int sintab[N]={ 0x7FFF,0x0000,0x7F61 ,0xF375,0x7D89 ,0xE708 ,0x7A7C ,0xDAD9,0x7640,0xCF05 ,0x70E1 ,0xC3AA ,0x6A6C ,0xB8E4 ,0x62F1 ,0xAECD ,
0x5A81,0xA57F,0x5133,0x9D0F,0x471C ,0x9594, 0x3C56, 0x8F1F,
0x30FB,0x89C0 ,0x2527,0x8584 ,0x18F8 ,0x8277 ,0x0C8B ,0x809F,
0x0000 ,0x8001,0xF375,0x809F,0xE708 ,0x8277 ,0xDAD9 ,0x8584,
0xCF05 ,0x89C0 ,0xC3AA,0x8F1F,0xB8E4 ,0x9594 ,0xAECD ,0x9D0F,
0xA57F,0xA57F,0x9D0F,0xAECD,0x9594 ,0xB8E4 ,0x8F1F ,0xC3AA,
0x89C0,0xCF05,0x8584 ,0xDAD9 ,0x8277 ,0xE708 ,0x809F ,0xF375,};*/
//   ---------------------------------------------------------------
//   32 点 FFT的sin 和 cos值存储表
//   ---------------------------------------------------------------
const int sintab[N]={
   0x7FFF,0x0000,0x7D89,0xE708,0x7640,0xCF05,0x6A6C,0xB8E4,
   0x5A81,0xA57F,0x471C,0x9594,0x30FB,0x89C0,0x18F8,0x8277,
   0x0000,0x8001,0xE708,0x8277,0xCF05,0x89C0,0xB8E4,0x9594,
   0xA57F,0xA57F,0x9594,0xB8E4,0x89C0,0xCF05,0x8277,0xE708,
};
extern int table128[];
extern int nom;      //   当nom=1时,FFT 需要归一化处理
main()
{ int i;  
 double x=0,y;
 nom=1;                  //   需要归一化处理 
 sysinit();
 for(i=0;i<=255;i++)   input[i]=0;   //   清除输入数据
    resave();                   //    把原始的输入数据反序排列                 
 *PCDATDIR=(*PCDATDIR&0x0FF00)|0x01;
 fft( );                       //    进行FFT运算 
 *PCDATDIR=*PCDATDIR&0x0FF00;
}
void  interrupt  phantom(void)

return;
}  
void sysinit(void)

    *SCSR1=0x81FE;
 *WDCR=0x0E8;
 *IFR=0x0FF;
 *IMR=0x0;
 WSGR=0;
 *MCRB=0;
 *PCDATDIR=0x100;
}

 

void interrupt nothing()
{
   return;
}




关键词: TMS320LF2407     实现     快速     傅里叶     变换    

菜鸟
2009-08-06 09:54:51     打赏
2楼

关键函数FFT都没给


菜鸟
2010-06-01 21:59:27     打赏
3楼
函数名: void  fft(void)
; 功能:实现32、64或128采样点的快速傅立叶变换
; 入口条件: 
; _sintab  存放FFT运算中用到的sin和cosin函数值
; _input  存放FFT运算中用到的数据,包括实部和虚部,按二进制反序排列
;    注意:由于"*BR0+"间接寻址方式对_input的地址有特殊的要求,
;    所以最好将数组_input放置在一个独立的块中,如B1块。
; _nom   当_nom=0时,本函数将不对运算结果进行归一化。反之,将对每       
;    一步运算结果进行归一化处理,避免溢出,但是,它会使运算精度降低。
;  N    常数,参与FFT运输的点数,用户可根据需要选择,例如,需要进行128点
;     FFT时,请在本函数中做出如下选择:
; N .set 128
; M .set 7
; 依此类推。
; 出口条件:
; _input  存放FFT的运算结果
; 本函数可供C调用,请用户在C主程序中作以下声明:
; extern void fft(void);
; const int sintab[N]={...};  N为128、64或32
; extern int _input[2*N];
; extern int nom;
;--------------------------------------------------------------------------------------------------
 .def _fft
; 基2时间抽取的128点FFT算法需要定义的各量
; N  .set 128     ; 点数
; M  .set 7        ;  N=2**M
; 基2时间抽取的64点FFT算法需要定义的各量
; N  .set 64                 ; 点数
; M  .set 6                  ; N=2**M
; 基2时间抽取的32点FFT算法需要定义的各量
N  .set 32                 ; 点数
M  .set 5                  ; N=2**M
_input .usect  ".data0",2*N      ;   输入数据      
;     .bss _sintab,N       ;   SIN和COSIN函数的存储表    
  .bss _nom,1            ;   当 _nom=1时,FFT需要归一化处理,为0时则不需要
  .global _fft
  .global _sintab
  .global _input
  .global _nom
  .text    
_fft: 
;   --------------------------------------
;   与C语言兼容的代码部分
;   --------------------------------------
     POPD *+      ;   存储返回地址ADDRESS
     SAR  AR6,*+           ;   存储 AR6
     SAR  AR7,*+           ;   存储 AR7
     SAR  AR0,*+           ;   存储 AR0
     SAR  AR1,*            ;   堆栈分布情况:ADDRESS/AR6/AR7/AR0/AR1
               ;   ARP=AR1,AR1:AR1
     LAR  AR0,#08h          
     LAR  AR3,*0+,AR3    ;   AR3:FP,SP=SP+size(size=frame的长度)
                   ;   ARP=AR3
     LAR  AR2,*       ;   AR2:AR1
     LAR  AR7,#_nom  ;   AR7 指向 _nom
;   -----------------------------------------
;   初始化一些寄存器
;   -----------------------------------------   
  SPLK #(N-1),*+    
  SPLK #(M-1),*+           
            ;   堆栈分布情况:ADDRESS/AR6/AR7
;   /AR0/N/M/Y(其中Y为没有确定的量)
            ;   ARP=AR3,AR2:N,AR3:Y
  SPLK #1,*+,AR2       ;   ID=1,ARP=AR2
            ;   堆栈分布情况:ADDRESS/AR6/AR7/AR0/          ;   N/M/ID/Y    ARP=AR2,AR2:N,AR3:
;   -----------------------------------------
;   FFT运算处理部分
;   -----------------------------------------         
   SETC OVM          ;   使能溢出模式
  SETC SXM       ;   符号扩展使能
  SPM      1           ;   PREG寄存器的输出左移一位,
;   自动将两个Q15相乘后化为Q15的格式
  LACC *+,AR3
  ADD #1
  SACL *+,1,AR2      ;   IW=2*(N+1)
            ;   堆栈分布情况:ADDRESS/AR6/AR7
               ;   /AR0/N/M/ID/IW/Y  
;   ARP:AR2,AR2:M,AR3:Y,
  LAR     AR5,*+       ;   AR5=M,ARP:AR2,AR2:ID,
;   AR3:Y,AR5=M
LOOP3 
  LAR  AR6,#_input       ;   AR6:input-->Ri ,ARP:AR2,
;   AR2:ID,AR3:Y,AR5=M,AR6:input 
  LACC *,1
  SACL    *+        ;   ID=ID*2,ARP:AR2,AR2:IW,
;    AR3:Y,AR5=M,AR6:input
          LACC *,15
          SACH *        ;   IW=IW/2
          LACC *-,15,AR3
          SACH *+,AR2          ;   C2=IW/2
;   堆栈分布情况:ADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/Y
;   ARP:AR2,AR2:ID,AR3:Y,AR5=M,AR6:input
   LAR AR0,*       ;   AR0=ID
LOOP2 
   LAR AR4,#_sintab  ;   AR4:sintab
;  ARP:AR2,AR0=ID,AR2:ID,AR3:Y,AR4:sintab,AR5=M,AR6:input
      LACC  *+,15,AR3
      SACH  *+,AR6             ;   C1=ID/2=1
;   堆栈分布情况:ADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/C1/Y
;  ARP:AR6,AR0=ID,AR2:IW,AR3:Y,AR4:sintab,AR5=M,AR6:input
     MAR *0+,AR4    
;  ARP:AR4,AR0=ID,AR2:IW,AR3:Y,AR4:sintab,AR5=M,AR6=AR6+ID-->Rj
LOOP1 
        LACC  #0
  LT *+,AR6                  ;   TREG=COSαlk
        MPY *+,AR4              ;   Rj* COSαlk,ARP=AR4,AR4:SINαlk,AR6:Ij
  LT  *,AR6
  MPYA  *-,AR3          ;   ACC=ACC+Rj*COSαlk,PREG=Ij*SINαlk
               ;   ARP=AR3,AR4:SINαlk,AR6:Rj
  SPAC            ;   ACC=ACC-Ij*SINαlk
  SACH    *+,AR4          ;   XT=Rj*COSαlk-Ij*SINαlk
;   堆栈分布情况:ADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/C1/XT/Y
;   ARP:AR4,AR0=ID,AR2:IW,AR3:Y,AR4:SINX,AR5=M,AR6:Q.X
    LACC #0
    LT  *-,AR6
    MPY  *+,AR4       ;   Rj*SINαlk,ARP=AR4,AR4:COSαlk,AR6:Ij
    LT  *,AR6
    MPYA *-,AR3        ;   ACC=ACC+Rj*SINαlk,PREG=Ij*COSαlk
              ;   ARP=AR3,AR4:COSαlk,AR6:Rj
    APAC 
    SACH *-,AR7       ;   YT=Rj*SINαlk+Ij*COSαlk
;   堆栈分布情况:ADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/C1/XT/YT
;   ARP:AR7,AR0=ID,AR2:IW,AR3:XT,AR4:COSX,AR5=M,AR6:Q.X
  LACC *,AR6
  BCND D2,NEQ          ;   当_nom不为0时,需要在运算过程中进
;   行归一化操作
;   ----------------------------------------
;   不进行归一化操作程序部分
;   ----------------------------------------
  MAR  *0-        ;   AR6=AR6-ID-->Ri
  LACC *,AR3
  ADD  *,AR6
  SACL *0+,AR3       ;   Ri=Ri+XT
;   ARP:AR3,AR0=ID,AR2:IW,AR3:XT,AR4:COSαlk,AR5=M,AR6:Rj
  SUB  *+,1,AR6
  SACL *+        ;   Rj= Ri+XT -XT*2=Ri-XT,AR6:Ij,AR3:YT
;   ARP:AR6,AR0=ID,AR2:IW,AR3:YT,AR4:COSαlk ,AR5=M,AR6:Ij
  MAR  *0-            ;   AR6:Ii
  LACC *,AR3              
  ADD  *-,AR6
  SACL *0+,AR3       ;   Ii= Ii +YT,AR6:Ij
;   ARP:AR3,AR0=ID,AR2:IW,AR3:XT,AR4:COSαlk,AR5=M,AR6:Ij
  SUB  *,1,AR6    
  SACL *+,0,AR2         ;   Ij= Ii +YT -YT*2=Ii-YT
;   STACK:ADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/C1/XT/YT
;   ARP:AR2,AR0=ID,AR2:IW,AR3:XT,AR4:COSαlk,AR5=M,AR6:NEXT Rj
  B  D                   ;   AR6 指向下一个Rj
;   ---------------------------------------
;   归一化处理程序部分
;   ---------------------------------------
D2  MAR  *0-        ;   AR6-->Ri
  LAC  *,15,AR3
  ADD  *,15,AR6    
  SACH *0+,AR3       ;   Ri =( Ri +XT)/2
;   ARP:AR3,AR0=ID,AR2:IW,AR3:XT,AR4:COSαlk,AR5=M,AR6:Rj 
     SUB  *+,16,AR6
  SACH *+        ;   Rj=Ri-XT,AR6:Ij,AR3:YT
;  ARP:AR6,AR0=ID,AR2:IW,AR3:YT,AR4:COSαlk,AR5=M,AR6:Ij
  MAR  *0-        ;   AR6:Ii
  LACC *,15,AR3
  ADD  *,15,AR6
  SACH *0+,AR3             ;   Ii=(Ii+YT)/2,AR6:Ij
;  ARP:AR3,AR0=ID,AR2:IW,AR3:YT,AR4:COSαlk,AR5=M,AR6:Ij
  SUB  *-,16,AR6
  SACH *+,0,AR2      ;   Ij=Ii-YT
;   STACK:ADDRESS/AR6/AR7/AR0/N/M/ID/IW/C2/C1/XT/YT
;   ARP:AR2,AR0=ID,AR2:IW,AR3:XT,AR4:COSαlk,AR5=M,AR6:下一个Rj
D  
        LAR  AR0,*-,AR4      ;   AR0=IW
;  ARP=AR4,AR0=IW,AR2:ID,AR3:XT,AR4:COSαlk,AR5=M,AR6:下一个Rj
  MAR  *0+,AR2       ;   AR4=AR4+IW-->下一个COSαlk
  LAR  AR0,*       ;   AR0=ID
  ADRK #3        ;   AR2:C1
;  ARP=AR2,AR0=ID,AR2:C1,AR3:XT,AR4:下一个COSαlk,AR5=M,AR6:Rj
     LACC *
     SUB  #1
     SACL *-     ;   C1=C1-1
;   ARP=AR2,AR0=ID,AR2:C2,AR3:XT,AR4:COSαlk,AR5=M,AR6:Rj
     BCND LOOP4,LEQ      ;   跳转至LOOP4,IF C1<0
     MAR  *-,AR4       ;   AR2:IW
;   ARP=AR4,AR0=ID,AR2:IW,AR3:XT,AR4:下一个COSαlk,AR5=M,AR6:Rj
     B  LOOP1               
LOOP4 LACC *
  SUB  #1
  SACL *-,AR3
  MAR     *-,AR2    
;   ARP=AR2,AR0=ID,AR2:IW,AR3:C1,AR4:下一个COSαlk,AR5=M,AR6:Ri
  MAR  *-
        BCND LOOP2,GT
        MAR     *,AR3
        MAR  *-,AR5             
;   ARP=AR5,AR0=ID,AR2:IW,AR3:C2,AR4下一个COSαlk,AR5=M,AR6:Ri
        BANZ LOOP3,*-,AR2
;   ------------------------------------
;   与C语言兼容的代码部分
;   ------------------------------------
     CLRC OVM
     SPM  0          
        MAR  *,AR1
        SBRK #09
        LAR  AR0,*-
        LAR  AR7,*-
        LAR  AR6,*-
        PSHD *
        RET

共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]