📄 1.asm
字号:
;----------------------------------------------------------------
;频域抽取FFT算法(不包含码位倒置,16位乘法器,16位数据,128点)
;jacken.lei
;09.03.31.
;----------------------------------------------------------------
#include <msp430x16x.h>
PUBLIC asmFFT
RSEG CODE
asmFFT; //什么意思?????????????????
extern temp1
extern temp2
extern temp11
;--------------------------------------------------------------
;----------------传递C语言中定义的变量名称标号-----------------------------------
;--------------------------------------------------------------
extern maxOfGrade //总级数
extern totalOfNum //总的计算点数
extern numOfGrade //当前计算的级数
extern shiftOfLowBf //具有相同旋转因子的蝶形单元的跨距
extern stepBetweenW //同一级中,不同旋转因子对应的蝶形单元的跨距
extern maxOfW //该级中,旋转因子的最大值,就是旋转因子的级数
extern counterOfFFTShiftTimes //Q13表示法中,总共移位的次数
extern gradeOverFlowFlag //每级计算完后是否要移位的标志
extern factorOfW //该级中,旋转因子的跨距
extern L1VCOS;
extern L1VSIN;
extern L1RCOS;
extern L1RSIN;
extern tableVOfFFT;数组虚部
extern fft_num
tableROfFFT equ fft_num;数组实部
extern startAdress //第2级循环中,用来设置3级循环的蝶形单元的起始地址和过程中的Bf单元的偏移地址
extern currentW //表示第2级循环中,当前的旋转因子
extern trueStartAdress //第2级循环中,蝶形单元的起始地址
;--------------------------------------------------
;----------- 主程序区 -------------
;--------------------------------------------------
PUSH.W R11
PUSH.W R10
PUSH.W R9
PUSH.W R8
PUSH.W R7
PUSH.W R6
PUSH.W R5
PUSH.W R4
initFFTParameters
CLR.W R11
CLR.W R10
CLR.W R9
CLR.W R8
CLR.W R7
CLR.W R6
CLR.W R5
CLR.W R4
;---------------------------------------------
;------------- 总初始化 -------------------
;---------------------------------------------
clr.w &gradeOverFlowFlag;
clr.w &counterOfFFTShiftTimes ;将上次计算的次数清0
mov.w #1,&numOfGrade
mov.w #1,&factorOfW ;同级中不同旋转因子之间距离,初始化为1,每次开始新的级内运算都需要乘以2
;mov.w &totalOfNum,&gradeOfW ;
mov.w &totalOfNum,&stepBetweenW;
mov.w &totalOfNum,&shiftOfLowBf; 初始化具有相同旋转因子的蝶形单元的跨距为总点数的一半
rra.w &shiftOfLowBf;
mov.w &shiftOfLowBf,&maxOfW; 初始化旋转因子的最大值为总点数的一半
clr.w &startAdress;
clr.w ¤tW;
;-----------------------------------------
;FirstLoop用来控制整个FFT计算一次
;SecondLoop用来控制一级FFT计算
;ThirdLoop用来控制一级中,相同旋转因子的蝶形单元的计算
;-----------------------------------------
FirstLoop
cmp #1,gradeOverFlowFlag;是否需要右移2位
jz ShiftR2
L11 clr.w &gradeOverFlowFlag;
cmp.w &numOfGrade,&maxOfGrade;循环结束条件
jl FinalOUT
SecondLoop
cmp.w &maxOfW,¤tW
jz setupFirstLoop
ThirdLoop
;mov.w &startAdress,r11;
;add.w &shiftOfLowBf,r11;
cmp &totalOfNum,&startAdress;
jge setupSecondLoop;
caculateBf
mov.w &startAdress,r5; 处理实部(r5),虚部(r7),正弦表(r6)的offset量
mov.w ¤tW,r6;
mov.w &shiftOfLowBf,r7;
rla r5;
rla r6;
; rla r6; 8点FFT,使用的是128点FFT的正余弦表
; rla r6;
; rla r6;
; rla r6;
rla r7;
add.w r5,r7;
UP clr.w r8; UP:计算蝶形单元的上半部分
add.w tableROfFFT(r5),r8;
mov.w tableROfFFT(r5),&temp1; 这里设置temp1,2:因为在DOWN部分还要用到的(FFT是原位运算)
add.w tableROfFFT(r7),r8;
mov r8,tableROfFFT(r5);
mov.w r8,r10;
cmp #0,r8;
jge L1
call #jueduizhi
mov.w &temp11,r10;
L1 call #judgeover
clr.w r9;
add.w tableVOfFFT(r5),r9;
add.w tableVOfFFT(r7),r9;
mov.w tableVOfFFT(r5),&temp2;
mov.w r9,tableVOfFFT(r5);
mov.w r9,r10;
cmp #0,r9;
jge L2
call #jueduizhi
mov.w &temp11,r10;
L2 call #judgeover
DOWN clr.w r8; DOWN:计算蝶形单元的下半部分
add.w &temp1,r8;
sub.w tableROfFFT(r7),r8;
mov.w r8,tableROfFFT(r7);
clr.w r9;
add.w &temp2,r9;
sub.w tableVOfFFT(r7),r9;
mov.w r9,tableVOfFFT(r7);
rcos mov.w tableROfFFT(R7),&MPYS
mov.w cos_table(R6),&OP2
RLA &RESLO
RLC &RESHI
RLA &RESLO
RLC &RESHI //结果右移14位,因为正弦表左移了14位
mov.w &RESHI,&L1RCOS
vsin mov.w tableVOfFFT(R7),&MPYS
mov.w sin_table(R6),&OP2
RLA &RESLO
RLC &RESHI
RLA &RESLO
RLC &RESHI
mov.w &RESHI,&L1VSIN
vcos mov.w tableVOfFFT(R7),&MPYS
mov.w cos_table(R6),&OP2
RLA &RESLO
RLC &RESHI
RLA &RESLO
RLC &RESHI
mov.w &RESHI,&L1VCOS
rsin mov.w tableROfFFT(R7),&MPYS
mov.w sin_table(R6),&OP2
RLA &RESLO
RLC &RESHI
RLA &RESLO
RLC &RESHI
mov.w &RESHI,&L1RSIN
add.w &L1VSIN,&L1RCOS;
mov.w &L1RCOS,r10;
cmp #0,&L1RCOS;
jge L3
call #jueduizhi
mov.w &temp11,r10;
L3 call #judgeover
mov.w &L1RCOS,tableROfFFT(r7)
sub.w &L1RSIN,&L1VCOS
mov.w &L1VCOS,r10;
cmp #0,&L1VCOS;
jge L4
call #jueduizhi
mov.w &temp11,r10;
L4 call #judgeover
mov.w &L1VCOS,tableVOfFFT(r7)
setupThirdLoop
add &stepBetweenW,&startAdress;
jmp ThirdLoop;
setupSecondLoop
add.w &factorOfW,¤tW;
inc &trueStartAdress;
mov.w &trueStartAdress,&startAdress;
jmp SecondLoop;
setupFirstLoop
clr.w &trueStartAdress;
clr.w &startAdress;
clr.w ¤tW;
inc.w numOfGrade; 在循环结束时设置
rra.w &shiftOfLowBf;
;rra.w &maxOfW;
rra.w stepBetweenW;
rla.w factorOfW;
jmp FirstLoop;
;--------------------------------------
;---------判断是否溢出的函数-----------
;--------------------------------------
judgeover:
cmp.w #8192,r10; 0x6000=54576
jl L10
mov.w #1,&gradeOverFlowFlag;
L10 ret
;--------------------------------------
;------------绝对值函数----------------
;--------------------------------------
jueduizhi:
sub #1,r10;
inv r10;
mov.w r10,&temp11;
ret
ShiftR2 ;该级的结果右移2位 ???????这里似乎可以只右移1位,因为是频域抽取算法
mov.w &totalOfNum,r11;
rla r11
L12 dec.w r11;
dec.w r11;
rra tableROfFFT(r11)
rra tableROfFFT(r11)
rra tableVOfFFT(r11)
rra tableVOfFFT(r11)
cmp.w #0,r11;
jnz L12
add #1,&counterOfFFTShiftTimes
jmp L11
FinalOUT ;设置最后的输出,
;jmp end1;
POP.W R4
POP.W R5
POP.W R6
POP.W R7
POP.W R8
POP.W R9
POP.W R10
POP.W R11
RET
;-----------------------------------------------------------
;-----------------------------------------------------------
;---------------正余弦函数表--------------------------------
;-----------------------------------------------------------
sin_table
dw 0
dw 804
dw 1606
dw 2404
dw 3196
dw 3981
dw 4756
dw 5520
dw 6270
dw 7005
dw 7723
dw 8423
dw 9102
dw 9760
dw 10394
dw 11003
dw 11585
dw 12140
dw 12665
dw 13160
dw 13623
dw 14053
dw 14449
dw 14811
dw 15137
dw 15426
dw 15679
dw 15893
dw 16069
dw 16207
dw 16305
dw 16364
dw 16384
dw 16364
dw 16305
dw 16207
dw 16069
dw 15893
dw 15679
dw 15426
dw 15137
dw 14811
dw 14449
dw 14053
dw 13623
dw 13160
dw 12665
dw 12140
dw 11585
dw 11003
dw 10394
dw 9760
dw 9102
dw 8423
dw 7723
dw 7005
dw 6270
dw 5520
dw 4756
dw 3981
dw 3196
dw 2404
dw 1606
dw 804
cos_table
dw 16384
dw 16364
dw 16305
dw 16207
dw 16069
dw 15893
dw 15679
dw 15426
dw 15137
dw 14811
dw 14449
dw 14053
dw 13623
dw 13160
dw 12665
dw 12140
dw 11585
dw 11003
dw 10394
dw 9760
dw 9102
dw 8423
dw 7723
dw 7005
dw 6270
dw 5520
dw 4756
dw 3981
dw 3196
dw 2404
dw 1606
dw 804
dw 0
dw -803
dw -1605
dw -2403
dw -3195
dw -3980
dw -4755
dw -5519
dw -6269
dw -7004
dw -7722
dw -8422
dw -9101
dw -9759
dw -10393
dw -11002
dw -11584
dw -12139
dw -12664
dw -13159
dw -13622
dw -14052
dw -14448
dw -14810
dw -15136
dw -15425
dw -15678
dw -15892
dw -16068
dw -16206
dw -16304
dw -16363
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -