📄 fft.asm
字号:
******************************************************************
*** N(8-1024) points FFT Program ***
******************************************************************
.title "fft.asm"
.mmregs
.copy "coeff.inc"
; .copy "fftin.dat"
* .copy "fftin64.dat"
.def _c_int00
sine: .usect "sine",512
cosine: .usect "cosine",512
d_input: .usect "d_input",2048
fft_data: .usect "fft_data",2048
fft_out: .usect "fft_out",1024
STACK .usect "STACK",10
K_DATA_IDX_1 .set 2
K_DATA_IDX_2 .set 4
K_DATA_IDX_3 .set 8
K_TWID_TBL_SIZE .set 512
K_TWID_IDX_3 .set 128
K_FLY_COUNT_3 .set 4
K_FFT_SIZE .set 256 ;N=256
K_LOGN .set 8 ;LOG(N)=LOG(8)=8
PA0 .set 0
PA1 .set 1
.bss d_twid_idx,1
.bss d_data_idx,1
.bss d_grps_cnt,1
.sect "fft_prg"
*** Bit Reversal Routine ***
.asg AR2,REORDERED
.asg AR3,ORIGINAL_INPUT
.asg AR7,DATA_PROC_BUF
.text
_c_int00:
SSBX FRCT
STM #STACK+10,SP
STM #d_input,AR1 ;input the 2N data
* STM #fft_data,AR1 ;input the 2N data
* RPT #2*K_FFT_SIZE-1 ;from PA1
* MVPD d_input1,*AR1+
* PORTR PA1,*AR1+
STM #sine,AR1 ;move coeft of sin
RPT #511 ;from program to data
MVPD sine1,*AR1+
STM #cosine,AR1 ;move coeff of cos
RPT #511 ;from program to data
MVPD cosine1,*AR1+
STM #d_input,ORIGINAL_INPUT
STM #fft_data,DATA_PROC_BUF
MVMM DATA_PROC_BUF,REORDERED
STM #K_FFT_SIZE-1,BRC
RPTBD bit_rev_end-1
STM #K_FFT_SIZE,AR0
MVDD *ORIGINAL_INPUT+,*REORDERED+
MVDD *ORIGINAL_INPUT-,*REORDERED+
MAR *ORIGINAL_INPUT+0B
bit_rev_end:
* * * * FFT Code * * * * *
.asg AR1,GROUP_COUNTER
.asg AR2,PX
.asg AR3,QX
.asg AR4,WR
.asg AR5,WI
.asg AR6,BUTTERFLY_COUNTER
.asg AR7,STAGE_COUNTER
* * * stage 1 * * *
STM #0, BK
LD #-1,ASM ;设置移位,防止溢出
STM #fft_data,PX
LD *PX,16,A
STM #fft_data+K_DATA_IDX_1,QX
STM #K_FFT_SIZE/2-1,BRC
RPTBD stage1end-1
STM #K_DATA_IDX_1+1,AR0
SUB *QX,16,A,B
ADD *QX,16,A
STH A,ASM,*PX+
ST B,*QX+
||LD *PX,A
SUB *QX,16,A,B
ADD *QX,16,A
STH A,ASM,*PX+0
ST B,*QX+0%
||LD *PX,A
stage1end:
* * * Stage 2 * * *
STM #fft_data,PX
STM #fft_data+K_DATA_IDX_2,QX
STM #K_FFT_SIZE/4-1,BRC
LD *PX,16,A
RPTBD stage2end-1
STM #K_DATA_IDX_2+1,AR0
;1st butterfly
SUB *QX,16,A,B
ADD *QX,16,A
STH A,ASM,*PX+
ST B,*QX+
||LD *PX,A
SUB *QX,16,A,B
ADD *QX,16,A
STH A,ASM,*PX+
STH B,ASM,*QX+
;2nd butterfly
MAR *QX+
ADD *PX,*QX,A
SUB *PX,*QX-,B
STH A,ASM,*PX+
SUB *PX,*QX,A
ST B,*QX
||LD *QX+,B
ST A,*PX
||ADD *PX+0%,A
ST A,*QX+0%
||LD *PX,A
stage2end:
* * * Stage 3 through Stage logN * * *
STM #K_TWID_TBL_SIZE,BK
ST #K_TWID_IDX_3,d_twid_idx
STM #K_TWID_IDX_3,AR0
STM #cosine,WR
STM #sine,WI
STM #K_LOGN-2-1,STAGE_COUNTER
ST #K_FFT_SIZE/8-1,d_grps_cnt
STM #K_FLY_COUNT_3-1,BUTTERFLY_COUNTER
ST #K_DATA_IDX_3,d_data_idx
stage:
STM #fft_data,PX
LD d_data_idx,A
ADD *(PX),A
STLM A,QX
MVDK d_grps_cnt,GROUP_COUNTER
group:
MVMD BUTTERFLY_COUNTER,BRC
RPTBD butterflyend-1
LD *WR,T
MPY *QX+,A
MACR *WI+0%,*QX-,A
ADD *PX,16,A,B
ST B,*PX
||SUB *PX+,B
ST B,*QX
||MPY *QX+,A
MASR *QX,*WR+0%,A
ADD *PX,16,A,B
ST B,*QX+
||SUB *PX,B
LD *WR,T
ST B,*PX+
||MPY *QX+,A
butterflyend:
; Update pointers for next group
PSHM AR0
MVDK d_data_idx,AR0
MAR *PX+0
MAR *QX+0
BANZD group,*GROUP_COUNTER-
POPM AR0
MAR *QX-
;Update counters and indices for next stage
LD d_data_idx,A
SUB #1,A,B
STLM B,BUTTERFLY_COUNTER
STL A,1,d_data_idx
LD d_grps_cnt,A
STL A,ASM,d_grps_cnt
LD d_twid_idx,A
STL A,ASM,d_twid_idx
BANZD stage,*STAGE_COUNTER-
MVDK d_twid_idx,AR0
fft_end:
* * * Compute the power spectrum * * *
STM #fft_data,AR2
STM #fft_data,AR3
STM #fft_out,AR4
STM #K_FFT_SIZE*2-1,BRC
RPTB power_end-1
SQUR *AR2+,A
SQURA *AR2+,A
STH A,*AR4+
power_end:
;STM #fft_out,AR4
;RPT #K_FFT_SIZE-1
;PORTW *AR4+,PA0
;here: B here
*************************Get the Freq**************************
.bss result,10
.bss TimesOfFS,1
.bss NumOfFreq,1
Fs .set 4000 ;设置采样频率
.bss temp,1
Gate .set 164 ;设置门限
stm #fft_out,ar2
stm #result,ar3
stm #0,ar7
ld #K_FFT_SIZE,A ;计算比较次数
sfta A,-1
sub #2,A
stl A,*(TimesOfFS)
mvdm *(TimesOfFS),ar1
rsbx C
loopInG: ldm ar2,A ;保存点地址
;rsbx TC
stl A,*ar3
ld *ar2+,B ;数据读进
stlm B,ar0
ld *ar2,B
stlm B,ar4
ld #Gate,16,A ;为比较数据是否大于门限作准备
add B,A
nop
nop
cmps A,*(temp)
nop
nop
xc 1,NTC
rsbx c
nop
nop ;给ar4以有效时间
nop
xc 1,NC
cmpr 1,ar4 ;测试前一点是否大于后一点
xc 1,C
cmpr 2,ar4 ;测试前一点是否小于后一点
nop
nop
xc 2,TC
call XX
mvmd ar7,*(NumOfFreq) ;置频率个数
banz loopInG,*ar1-
loop_end:
call GetFreq
end: b end
XX: stm #Gate,ar0
mar *ar2- ;s
nop
nop
ld *ar2+,A
pshm ar4
stlm A,ar4
nop
nop ;e
cmpr 2,ar4
popm ar4
bc XX1,NTC
xc 1,C
rsbx C
xc 1,NC
ssbx C
mar *ar3+
mar *ar7+
XX1: ret
GetFreq: ;计算实际频率
rsbx FRCT
stm #result,ar5
ld *(NumOfFreq),A
sub #1,A
stlm A,ar1
kk:
ld *ar5,A
sub #fft_out,A
stl A,*ar5
mpy *ar5,#Fs,A
sfta A,-8 ;f=(k/N)*Fs
stl A,*ar5+
banz kk,*ar1-
ret
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -