② 下面的图4显示了第三步完成以后存储器中的数据情况,RP[k]和IP[k]存储在
2200h2201h2202h2203h2204h2205h2206h2207h2208h2209h220Ah220BhRP[0]=R[0]IP[0]=I[0]RP[1]IP[1]RP[2]IP[2]RP[3]IP[3]RP[4]IP[4]RP[5]IP[5]22FEh22FFh2300h2301h2302h2303h2304h2305h2306h2307h2308h2309h230Ah230BhRP[127]IP[127]a[0]a[1]IM[127]RM[127]IM[126]RM[126]IM[125]RM[125]IM[124]RM[124]IM[123]RM[123]...23FEh23FFhIM[1]RM[1]上半部分,RM[k] 和IM[k]存储在下半部分。
图4
这一过程的程序代码如下所示:
unpack
131
.asg AR2,XP_k .asg AR3,XP_Nminusk .asg AR6,XM_k .asg AR7,XM_Nminusk
STM #fft_data+2,XP_k
; AR2指向R[k] (temp RP[k]) ; AR3指向 R[N-K] (temp RP[N-K])
STM #fft_data+2*K_FFT_SIZE-2,XP_Nminusk
STM #fft_data+2*K_FFT_SIZE+3,XM_Nminusk ; AR7指向 temp RM[N-K] STM #fft_data+4*K_FFT_SIZE-1,XM_k STM #-2+K_FFT_SIZE/2,BRC RPTBD phase3end-1
; AR6指向temp RM[K] ; 设置块循环计数器
; 从以下指令到phase3end-1处一直 ; 重复执行BRC中规定的次数
STM #3,AR0
; 设置AR0以备下面程序寻址使用 ; A := R[k]+R[N-K] = 2*RP[k] ; B := R[k]-R[N-K]= 2*RM[k] ; 在AR[k]处存储RP[k]
; 在AR[N-K]处存储RP[N-K]=RP[k] ; 在AI[2N-K]处存储RM[k] ; B := R[N-K]-R[k] =2*RM[N-K] ; 在AI[N+k]处存储RM[N-K] ; A := I[k]+I[N-K] = 2*IP[k] ; B := I[k]-I[N-K] =2*IM[k] ; 在AI[k]处存储IP[k]
; 在AI[N-K]处存储IP[N-K]=IP[k] ; 在AR[2N-K]处存储IM[k] ; B := I[N-K]-I[k] =2*IM[N-K] ; 在AR[N+k]处存储IM[N-K]
ADD *XP_k,*XP_Nminusk,A SUB *XP_k,*XP_Nminusk,B STH A,ASM,*XP_k+
STH A,ASM,*XP_Nminusk+ STH B,ASM,*XM_k-
NEG B
STH B,ASM,*XM_Nminusk- ADD *XP_k,*XP_Nminusk,A SUB *XP_k,*XP_Nminusk,B STH A,ASM,*XP_k+
STH A,ASM,*XP_Nminusk-0
STH B,ASM,*XM_k- NEG B
STH B,ASM,*XM_Nminusk+0 phase3end:
第四步,产生最后的N = 256点的复数FFT结果
132
产生2N = 256个点的复数输出,它与原始的256个点的实输入序列的DFT一致。输出驻留在数据缓冲器中。
① 通过下面的公式由RP[k]、RM[n]、IP[n]和IM[n]四个序列可以计算出a[n]的DFT:
AR[k] = AR[2N-k] = RP[k] + cos(kπ/N) * IP[k] - sin(kπ/N) * RM[k] AI[k] = -AI[2N-k] = IM[k] - cos(kπ/N) * RM[k] - sin(kπ/N) * IP[k] AR[0] = RP[0] + IP[0] AI[0] = IM[0] - RM[0] AR[N] = R[0] - I[0] AI[N] = 0 其中:
A[k] = A[2N-k] = AR[k] + j AI[k] = F{a(n)}
② 实数FFT输出按照实数/虚数的自然顺序填满整个4N=512个字节的数据处理缓冲器。如图5所示。
133
2200h2201h2202h2203h2204h2205hAR[0]AI[0]AR[1]AI[1]AR[2]AI[2]22FFh2300h2301h2302h2303h2304h2305hAI[127]AR[128]AI[128]AR[129]AI[129]AR[200]AI[200]23FFh图5
AI[255]这一段程序可以和上面的步骤3的程序合成一个子程序unpack,这一步的程序代码如下:
ST #0,*XM_k-
ST #0,*XM_k
; RM[N/2]=0 ; IM[N/2]=0
; 计算AR[0],AI[0], AR[N], AI[N] .asg AR2,AX_k .asg AR4,IP_0 .asg AR5,AX_N STM #fft_data,AX_k STM #fft_data+1,IP_0
; AR2指向AR[0] (temp RP[0]) ; AR4指向AI[0] (temp IP[0]) ; AR5指向AI[N] ; A := RP[0]+IP[0]
STM #fft_data+2*K_FFT_SIZE+1,AX_N ADD *AX_k,*IP_0,A
134
SUB *AX_k,*IP_0,B STH A,ASM,*AX_k+ ST #0,*AX_k
; B := RP[0]-IP[0] ; AR[0] = (RP[0]+IP[0])/2 ; AI[0] = 0
; AI[N] = 0
MVDD *AX_k+,*AX_N- STH B,ASM,*AX_N
; 计算最后的输出值AR[k], AI[k] .asg AR3,AX_2Nminusk .asg AR4,COS .asg AR5,SIN
; AR[N] = (RP[0]-IP[0])/2
STM #fft_data+4*K_FFT_SIZE-1,AX_2Nminusk ; AR3指向AI[2N-1](temp RM[1])
; AR4指向cos(k*π/N)
STM #cos_table+K_TWID_TBL_SIZE/K_FFT_SIZE,COS
STM #sine_table+K_TWID_TBL_SIZE/K_FFT_SIZE,SIN ; AR5指向sin(k*π/N) STM #K_FFT_SIZE-2,BRC RPTBD phase4end-4
STM #K_TWID_TBL_SIZE/K_FFT_SIZE,AR0
135
; AR0中存入旋转因子表的大
;小以备循环寻址时使用 ; A := RP[k] ||修改AR2指向IP[k] ; A :=A+cos(k*π/N)*IP[k] ; A := A-sin(k*π/N)*RM[k] || ;修改AR3指向IM[k]
; B := IM[k] ||修改AR3指向RM[k] ; B := B-sin(k*π/N)*IP[k] || ;修改AR2指向RP[k] ; B := B-cos(k*π/N)*RM[k] ; AR[k] = A/2 ; AI[k] = B/2 ; B := -B
; AI[2N-K] = -AI[k]= B/2
; AR[2N-K] = AR
LD *AX_k+,16,A
MACR *COS,*AX_k,A
MASR *SIN,*AX_2Nminusk-,A
LD *AX_2Nminusk+,16,B
MASR *SIN+0%,*AX_k-,B
MASR *COS+0%,*AX_2Nminusk,B STH A,ASM,*AX_k+ STH B,ASM,*AX_k+ NEG B
STH B,ASM,*AX_2Nminusk - STH A,ASM,*AX_2Nminusk-