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

📄 fft.asm

📁 DSP的实时FFT程序
💻 ASM
📖 第 1 页 / 共 3 页
字号:
  .WORD   00BED0H
  .WORD   003955H
  .WORD   008327H
  .WORD   0040D5H
  .WORD   00C708H
  .WORD   007C7AH
  .WORD   00BF8CH
  .WORD   003896H
  .WORD   0083EAH
  .WORD   00400EH
  .WORD   00C7D2H
  .WORD   007BACH
  .WORD   00C05DH
  .WORD   0037C1H
  .WORD   0084C2H
  .WORD   003F33H
  .WORD   00C8B1H
  .WORD   007ACAH
  .WORD   00C142H
  .WORD   0036D8H
  .WORD   0085AEH
  .WORD   003E43H
  .WORD   00C9A4H
  .WORD   0079D4H
  .WORD   00C23CH
  .WORD   0035DBH
  .WORD   0086AFH
  .WORD   003D3FH
  .WORD   00CAABH
  .WORD   0078CAH
  .WORD   00C34AH
  .WORD   0034CAH
  .WORD   0087C3H
  .WORD   003C28H
  .WORD   00CBC6H
  .WORD   0077ABH
  .WORD   00C46BH
  .WORD   0033A5H
  .WORD   0088EBH
  .WORD   003AFDH
  .WORD   00CCF4H
  .WORD   00767AH
  .WORD   00C5A0H
  .WORD   00326DH
  .WORD   008A26H
  .WORD   0039BEH
  .WORD   00CE36H
  .WORD   007535H
  .WORD   00C6E8H
  .WORD   003122H
  .WORD   008B75H
  .WORD   00386DH
  .WORD   00CF8BH
  .WORD   0073DDH
  .WORD   00C843H
  .WORD   002FC4H
  .WORD   008CD6H
  .WORD   003708H
  .WORD   00D0F2H
  .WORD   007273H
  .WORD   00C9B1H
  .WORD   002E54H
  .WORD   008E49H
  .WORD   003592H
  .WORD   00D26BH
  .WORD   0070F6H
  .WORD   00CB30H
  .WORD   002CD1H
  .WORD   008FCFH
  .WORD   00340AH
  .WORD   00D3F7H
  .WORD   006F68H
  .WORD   00CCC1H
  .WORD   002B3DH
  .WORD   009166H
  .WORD   003270H
  .WORD   00D593H
  .WORD   006DC8H
  .WORD   00CE64H
  .WORD   002998H
  .WORD   00930EH
  .WORD   0030C5H
  .WORD   00D741H
  .WORD   006C18H
  .WORD   00D017H
  .WORD   0027E2H
  .WORD   0094C7H
  .WORD   002F09H
  .WORD   00D900H
  .WORD   006A57H
  .WORD   00D1DBH
  .WORD   00261BH
  .WORD   009690H
  .WORD   002D3DH
  .WORD   00DACEH
  .WORD   006885H
  .WORD   00D3AFH
  .WORD   002444H
  .WORD   009869H
  .WORD   002B61H
  .WORD   00DCADH
  .WORD   0066A4H
  .WORD   00D593H
  .WORD   00225EH
  .WORD   009A52H
  .WORD   002976H
  .WORD   00DE9BH
  .WORD   0064B4H
  .WORD   00D785H
  .WORD   002069H
  .WORD   009C4AH
  .WORD   00277CH
  .WORD   00E097H
  .WORD   0062B5H
  .WORD   00D987H
  .WORD   001E65H
  .WORD   009E50H
  .WORD   002573H
  .WORD   00E2A2H
  .WORD   0060A8H
  .WORD   00DB96H
  .WORD   001C54H
  .WORD   00A064H
  .WORD   00235DH
  .WORD   00E4BAH
  .WORD   005E8DH
  .WORD   00DDB3H
  .WORD   001A34H
  .WORD   00A285H
  .WORD   002139H
  .WORD   00E6E0H
  .WORD   005C65H
  .WORD   00DFDDH
  .WORD   001808H
  .WORD   00A4B4H
  .WORD   001F09H
  .WORD   00E913H
  .WORD   005A31H
  .WORD   00E214H
  .WORD   0015CFH
  .WORD   00A6EEH
  .WORD   001CCCH
  .WORD   00EB51H
  .WORD   0057F0H
  .WORD   00E456H
  .WORD   00138BH
  .WORD   00A935H
  .WORD   001A84H
  .WORD   00ED9CH
  .WORD   0055A4H
  .WORD   00E6A4H
  .WORD   00113BH
  .WORD   00AB86H
  .WORD   001831H
  .WORD   00EFF1H
  .WORD   00534DH
  .WORD   00E8FDH
  .WORD   000EE1H
  .WORD   00ADE2H
  .WORD   0015D3H
  .WORD   00F250H
  .WORD   0050ECH
  .WORD   00EB60H
  .WORD   000C7CH
  .WORD   00B049H
  .WORD   00136BH
  .WORD   00F4BAH
  .WORD   004E81H
  .WORD   00EDCCH
  .WORD   000A0EH
  .WORD   00B2B8H
  .WORD   0010FAH
  .WORD   00F72CH
  .WORD   004C0DH
  .WORD   00F042H
  .WORD   000797H
  .WORD   00B531H
  .WORD   000E80H
  .WORD   00F9A7H
  .WORD   004990H
  .WORD   00F2C0H
  .WORD   000518H
  .WORD   00B7B1H
  .WORD   000BFEH
  .WORD   00FC2BH
  .WORD   00470CH
  .WORD   00F545H
  .WORD   000291H
  .WORD   00BA39H
  .WORD   000975H
  .WORD   00FEB5H
  .WORD   004480H
  .WORD   00F7D2H
  .WORD   000003H


data_output .usect "data_out",1024

                                             
	.text
;256-Point Real FFT Initialization
	.asg AR1,FFT_TWID_P        
_c_int00:	
;	.sect "rfft_prg"
	LD	#FFT_DP,DP
	STM #SYSTEM_STACK,SP
rfft_task:
;	STM #sine,FFT_TWID_P
;	RPT #K_FFT_SIZE-1 								; move FIR coeffs from program
;	MVPD #sine_table,*FFT_TWID_P+ 					; to data
;	STM #cosine,FFT_TWID_P
;	RPT #K_FFT_SIZE-1 								; move FIR coeffs from program
;	MVPD #cos_table,*FFT_TWID_P+
	STM  #FFT_ORIGIN,AR3 					; to data
	STM  #data_input,AR4 
	RPT	 #K_FFT_SIZE*2-1
	MVDD *AR4+,*AR3+
	CALL  bit_rev
	CALL  fft
	CALL  unpack
	CALLD power   
	STM   #K_ST1,ST1 									; restore the original contents of
	NOP  
	STM   19F0H,AR6   
	NOP
    XOR    A,A 
    RPT   #30
    STL   A,*AR6+ 
	;CALL  find
loop:
    B    loop	 					
													; ST1 since ASM field has changed
	NOP
	NOP
	NOP
	RET 											; return to main program


;=========================================================        
;Bit Reversal Routine      
	.asg AR2,REORDERED_DATA
	.asg AR3,ORIGINAL_INPUT
	.asg AR7,DATA_PROC_BUF
	.def  bit_rev
;	.sect "rfft_prg"
bit_rev:
	SSBX FRCT 
;	ST	 #FFT_ORIGIN,d_input_addr										; fractional mode is on
	STM #FFT_ORIGIN,ORIGINAL_INPUT 				; AR3 -> 1 st original input
	STM #fft_data,DATA_PROC_BUF 					; AR7 -> data processing buffer
	MVMM DATA_PROC_BUF,REORDERED_DATA 				; AR2 -> 1st bit-reversed data
	STM #K_FFT_SIZE-1,BRC
	RPTBD bit_rev_end-1
	STM #K_FFT_SIZE,AR0 							; AR0 = 1/2 size of circ buffer
	MVDD *ORIGINAL_INPUT+,*REORDERED_DATA+
	MVDD *ORIGINAL_INPUT-,*REORDERED_DATA+
	MAR *ORIGINAL_INPUT+0B
bit_rev_end:
	RET 											; return to Real FFT main module

                                                  
                                                  
;=====================================================	
;256-Point Real FFT Routine
 	.asg AR1,GROUP_COUNTER
	.asg AR2,PX
	.asg AR3,QX
	.asg AR4,WR
	.asg AR5,WI
	.asg AR6,BUTTERFLY_COUNTER
	.asg AR7,DATA_PROC_BUF 							; for Stages 1 & 2
	.asg AR7,STAGE_COUNTER 							; for the remaining stages
	.def  fft
;	.sect "rfft_prg"
fft:
; Stage 1 --------------------------------------------
	STM #K_ZERO_BK,BK 								; BK=0 so that *ARn+0% == *ARn+0
	LD #-1,ASM 										; outputs div by 2 at each stage
	MVMM DATA_PROC_BUF,PX 							; PX -> PR
	LD *PX,A 										; A := PR
	STM #fft_data+K_DATA_IDX_1,QX 					; QX -> QR
	STM #K_FFT_SIZE/2-1,BRC
	RPTBD stage1end-1
	STM #K_DATA_IDX_1+1,AR0
	SUB *QX,16,A,B 									; B := PR-QR
	ADD *QX,16,A 									; A := PR+QR
	STH A,ASM,*PX+ 									; PR’:= (PR+QR)/2
	ST B,*QX+ 										; QR’:= (PR-QR)/2
	||LD *PX,A 										; A := PI
	SUB *QX,16,A,B 									; B := PI-QI
	ADD *QX,16,A 									; A := PI+QI
	STH A,ASM,*PX+0 								; PI’:= (PI+QI)/2
	ST B,*QX+0% 									; QI’:= (PI-QI)/2
	||LD *PX,A 										; A := next PR       
stage1end:
; Stage 2 ----------------------------------------------------------------------
	MVMM DATA_PROC_BUF,PX 							; PX -> PR
	STM #fft_data+K_DATA_IDX_2,QX 					; QX -> QR
	STM #K_FFT_SIZE/4-1,BRC
	LD *PX,A 										; A := PR
	RPTBD stage2end-1
	STM #K_DATA_IDX_2+1,AR0
; 1st butterfly
	SUB *QX,16,A,B 									; B := PR-QR
	ADD *QX,16,A 									; A := PR+QR
	STH A,ASM,*PX+ 									; PR’:= (PR+QR)/2
	ST B,*QX+ 										; QR’:= (PR-QR)/2
	||LD *PX,A 										; A := PI
	SUB *QX,16,A,B 									; B := PI-QI
	ADD *QX,16,A 									; A := PI+QI
	STH A,ASM,*PX+ 									; PI’:= (PI+QI)/2
	STH B,ASM,*QX+ 									; QI’:= (PI-QI)/2
; 2nd butterfly
	MAR *QX+
	ADD *PX,*QX,A 									; A := PR+QI
	SUB *PX,*QX-,B 									; B := PR-QI
	STH A,ASM,*PX+ 									; PR’:= (PR+QI)/2
	SUB *PX,*QX,A 									; A := PI-QR
	ST B,*QX 										; QR’:= (PR-QI)/2
	||LD *QX+,B 									; B := QR
	ST A, *PX 										; PI’:= (PI-QR)/2
	||ADD *PX+0%,A 									; A := PI+QR
	ST A,*QX+0% 									; QI’:= (PI+QR)/2
	||LD *PX,A 										; A := PR
stage2end:
; Stage 3 thru Stage logN-1 ----------------------------------------------------
	STM #K_TWID_TBL_SIZE,BK 						; BK = twiddle table size always
	ST #K_TWID_IDX_3,d_twid_idx 					; init index of twiddle table
	STM #K_TWID_IDX_3,AR0 							; AR0 = index of twiddle table
	STM #cosine,WR 									; init WR pointer
	STM #sine,WI 									; init WI pointer
	STM #K_LOGN-2-1,STAGE_COUNTER 					; init stage counter
	ST #K_FFT_SIZE/8-1,d_grps_cnt 					; init group counter
	STM #K_FLY_COUNT_3-1,BUTTERFLY_COUNTER 			; init butterfly counter
	ST #K_DATA_IDX_3,d_data_idx 					; init index for input data
stage:
	STM #fft_data,PX 								; PX -> PR
	LD d_data_idx, A
	ADD *(PX),A
	STLM A,QX 										; QX -> QR
	MVDK d_grps_cnt,GROUP_COUNTER 					; AR1 contains group counter

;A circular buffer of size R must start on a N-bit boundary (that is, the N LSBs
;of the base address of the circular buffer must be 0), where N is the smallest
;integer that satisfies 2 N > R. The value R must be loaded into BK.

group:
	MVMD BUTTERFLY_COUNTER,BRC 						; # of butterflies in each grp
	RPTBD butterflyend-1
	LD *WR,T 										; T := WR
	MPY *QX+,A 										; A := QR*WR || QX->QI
	MACR *WI+0%,*QX-,A 								; A := QR*WR+QI*WI  || QX->QR
	ADD *PX,16,A,B 									; B := (QR*WR+QI*WI)+PR
	ST B,*PX 										; PR’:=((QR*WR+QI*WI)+PR)/2
	||SUB *PX+,B 									; B := PR-(QR*WR+QI*WI) || PX->PI
	ST B,*QX 										; QR’:= (PR-(QR*WR+QI*WI))/2
	||MPY *QX+,A									; A := QR*WI [T=WI] || QX->QI
	MASR *QX,*WR+0%,A 								; A := QR*WI-QI*WR
	ADD *PX,16,A,B 									; B := (QR*WI-QI*WR)+PI
	ST B,*QX+ 										; QI’:=((QR*WI-QI*WR)+PI)/2  || QX->QR
	||SUB *PX,B 									; B := PI-(QR*WI-QI*WR)
	LD *WR,T 										; T := WR
	ST B,*PX+ 										; PI’:= (PI-(QR*WI-QI*WR))/2  || PX->PR
	||MPY *QX+,A 									; A := QR*WR || QX->QI
butterflyend:
; Update pointers for next group
	PSHM AR0 										; preserve AR0
	MVDK d_data_idx,AR0
	MAR *PX+0 										; increment PX for next group
	MAR *QX+0 										; increment QX for next group
	BANZD group,*GROUP_COUNTER-
	POPM AR0 										; restore AR0
	MAR *QX-
; Update counters and indices for next stage
	LD d_data_idx,A
	SUB #1,A,B 										; B = A-1
	STLM B,BUTTERFLY_COUNTER 						; BUTTERFLY_COUNTER = #flies-1
	STL A,1,d_data_idx 								; double the index of data
	LD d_grps_cnt,A
	STL A,ASM,d_grps_cnt 							; 1/2 the offset to next group
	LD d_twid_idx,A
	STL A,ASM,d_twid_idx 							; 1/2 the index of twiddle table
	BANZD stage,*STAGE_COUNTER-
	MVDK d_twid_idx,AR0 							; AR0 = index of twiddle table
fft_end:
	RET 											; return to Real FFT main module

 
 
 
;=================================================
;Unpack 256-Point Real FFT Output
	.def  unpack
;	.sect "rfft_prg"
unpack:
; Compute intermediate values RP, RM, IP, IM
	.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])
	STM #fft_data+2*K_FFT_SIZE-2,XP_Nminusk 		; AR3 -> R[N-k] (tempRP[N-k])
	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 				; AR6 -> temp RM[k]
	STM #-2+K_FFT_SIZE/2,BRC
	RPTBD phase3end-1
	STM #3,AR0
	ADD *XP_k,*XP_Nminusk,A 						; A := R[k]+R[N-k] =2*RP[k]
	SUB *XP_k,*XP_Nminusk,B 						; B := R[k]-R[N-k] =2*RM[k]
	STH A,ASM,*XP_k+ 								; store RP[k] at AR[k]
	STH A,ASM,*XP_Nminusk+ 							; store RP[N-k]=RP[k] at AR[N-k]
	STH B,ASM,*XM_k- 								; store RM[k] at AI[2N-k]
	NEG B 											; B := R[N-k]-R[k] =2*RM[N-k]
	STH B,ASM,*XM_Nminusk- 							; store RM[N-k] at AI[N+k]
	ADD *XP_k,*XP_Nminusk,A 						; A := I[k]+I[N-k] =2*IP[k]
	SUB *XP_k,*XP_Nminusk,B 						; B := I[k]-I[N-k] =2*IM[k]
	STH A,ASM,*XP_k+ 								; store IP[k] at AI[k]
	STH A,ASM,*XP_Nminusk-0 						; store IP[N-k]=IP[k] at AI[N-k]
	STH B,ASM,*XM_k- 								; store IM[k] at AR[2N-k]
	NEG B 											; B := I[N-k]-I[k] =2*IM[N-k]
	STH B,ASM,*XM_Nminusk+0 						; store IM[N-k] at AR[N+k]
phase3end:
	ST #0,*XM_k- 									; RM[N/2]=0
	ST #0,*XM_k 									; IM[N/2]=0
; Compute 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 								; AR2 -> AR[0] (tempRP[0])
	STM #fft_data+1,IP_0 							; AR4 -> AI[0] (tempIP[0])
	STM #fft_data+2*K_FFT_SIZE+1,AX_N 				; AR5 -> AI[N]
	ADD *AX_k,*IP_0,A 								; A := RP[0]+IP[0]
	SUB *AX_k,*IP_0,B 								; B := RP[0]-IP[0]
	STH A,ASM,*AX_k+ 								; AR[0] = (RP[0]+IP[0])/2
	ST #0,*AX_k 									; AI[0] = 0
	MVDD *AX_k+,*AX_N- 								; AI[N] = 0
	STH B,ASM,*AX_N 								; AR[N] = (RP[0]-IP[0])/2
; Compute final output values AR[k], AI[k]
	.asg AR3,AX_2Nminusk
	.asg AR4,COS
	.asg AR5,SIN                
	STM #fft_data+4*K_FFT_SIZE-1,AX_2Nminusk 		; AR3 -> AI[2N-1](temp RM[1])
	STM #cosine+K_TWID_TBL_SIZE/K_FFT_SIZE,COS 		; AR4 -> cos(k*pi/N)
	STM #sine+K_TWID_TBL_SIZE/K_FFT_SIZE,SIN 		; AR5 -> sin(k*pi/N)
	STM #K_FFT_SIZE-2,BRC
	RPTBD phase4end-1
	STM #K_TWID_TBL_SIZE/K_FFT_SIZE,AR0 			; index of twiddle tables
	LD *AX_k+,16,A 									; A := RP[k] ||AR2->IP[k]
	MACR *COS,*AX_k,A 								; A :=A+cos(k*pi/N)*IP[k]
	MASR *SIN,*AX_2Nminusk-,A 						; A := A-sin(k*pi/N)*RM[k]  || AR3->IM[k]
	LD *AX_2Nminusk+,16,B 							; B := IM[k] ||AR3->RM[k]
	MASR *SIN+0%,*AX_k-,B 							; B := B-sin(k*pi/N)*IP[k]  || AR2->RP[k]
	MASR *COS+0%,*AX_2Nminusk,B 					; B := B-cos(k*pi/N)*RM[k]
	STH A,ASM,*AX_k+ 								; AR[k] = A/2
	STH B,ASM,*AX_k+ 								; AI[k] = B/2
	NEG B 											; B := -B
	STH B,ASM,*AX_2Nminusk- 						; AI[2N-k] = -AI[k]= B/2
	STH A,ASM,*AX_2Nminusk- 						; AR[2N-k] = AR[k] = A/2
phase4end:
	RET 											; returntoRealFFTmain module
	


	

;=====================================================	
;Compute the Power Spectrum of the Complex Output of the 256-Point Real FFT           
	.asg AR2,AX
	.asg AR3,OUTPUT_BUF
	.def  power
;	.sect "pwr_prog" 
power:
	STM #data_output,OUTPUT_BUF 					; AR3 points to output buffer
	STM #K_FFT_SIZE*2-1,BRC
	RPTBD power_end-1
	STM #fft_data,AX 								; AR2 points to AR[0]
	SQUR *AX+,A 									; A := AR^2
	SQURA *AX+,A 									; A := AR^2 + AI^2
	STH A,*OUTPUT_BUF+
power_end:
	RET 											; return to main program
	
	
	.def find
	.asg AR2,POWER
	.asg AR3,STORE
	.asg AR4,INDEX
find:
	STM #data_output,POWER
	STM #data_find,STORE 
	STM #data_index,INDEX
	LD	#0,A
	LD	#0,B
	STL A,*STORE
	STM #K_FFT_SIZE*2-1,BRC	
	RPTB find_end-1
	SUB *POWER,*STORE,A
	BC	next,ALEQ
	MVDD *POWER,*STORE
	STL  B,*INDEX	
next:
	MAR *POWER+
	ADD #1,B
	
find_end:
	RET
	
	
	.end
	
	

⌨️ 快捷键说明

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