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

📄 fft.asm

📁 本源代码是在这款TMS320LF2407的DSP上的FFT算法程序
💻 ASM
字号:
;// -------------------------------------------------------------------------------------------------
;// 函数名:        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

⌨️ 快捷键说明

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