在ST更新STM32 DSP库之前,需要用到256点和1024点FFT运算的同学,不妨用以下的补丁打上。
1. 现有的DSP库函数中,64点FFT是正确的。
2. 256/1024点需要更改以下几个地方
(1)NPT的定义
IAR assembly file: #define NPT 64 => #define NPT 256/1024
Keil assembly file: NPT EQU 64 => NPT EQU 256/1024
RIDE assembly file: .equ NPT, 64 => .equ NPT, 256/1024
(2)修改一些汇编代码
IAR assembly file:
BUTFLY4ZERO_OPT MACRO pIN,offset, pOUT
LDRSH Ai, [pIN, #2]
LDRSH Ar, [pIN],#NPT
LDRSH Ci, [pIN, #2]
LDRSH Cr, [pIN],#NPT
LDRSH Bi, [pIN, #2]
LDRSH Br, [pIN],#NPT
LDRSH Di, [pIN, #2]
LDRSH Dr, [pIN],#NPT
改成:
BUTFLY4ZERO_OPT MACRO pIN,offset, pOUT
LDRSH Ai, [pIN, #2]
LDRSH Ar, [pIN]
ADD pIN, pIN, #NPT
LDRSH Ci, [pIN, #2]
LDRSH Cr, [pIN]
ADD pIN, pIN, #NPT
LDRSH Bi, [pIN, #2]
LDRSH Br, [pIN]
ADD pIN, pIN, #NPT
LDRSH Di, [pIN, #2]
LDRSH Dr, [pIN]
ADD pIN, pIN, #NPT
Keil assembly file:
MACRO
BUTFLY4ZERO_OPT $pIN,$offset, $pOUT
LDRSH Ai, [$pIN, #2]
LDRSH Ar, [$pIN],#NPT
LDRSH Ci, [$pIN, #2]
LDRSH Cr, [$pIN],#NPT
LDRSH Bi, [$pIN, #2]
LDRSH Br, [$pIN],#NPT
LDRSH Di, [$pIN, #2]
LDRSH Dr, [$pIN],#NPT
改成:
MACRO
BUTFLY4ZERO_OPT $pIN,$offset, $pOUT
LDRSH Ai, [$pIN, #2]
LDRSH Ar, [$pIN]
ADD $pIN, #NPT
LDRSH Ci, [$pIN, #2]
LDRSH Cr, [$pIN]
ADD $pIN, #NPT
LDRSH Bi, [$pIN, #2]
LDRSH Br, [$pIN]
ADD $pIN, #NPT
LDRSH Di, [$pIN, #2]
LDRSH Dr, [$pIN]
ADD $pIN, #NPT
RIDE assembly file:
preloop_v7:
ADD r14, r1, r12, LSR#24 /*256pts*/
LDRSH r5, [r14, #2]
LDRSH r4, [r14],#NPT
LDRSH r9, [r14, #2]
LDRSH r8, [r14],#NPT
LDRSH r7, [r14, #2]
LDRSH r6, [r14],#NPT
LDRSH r11, [r14, #2]
LDRSH r10, [r14],#NPT
改成:
preloop_v7:
ADD r14, r1, r12, LSR#24 /*256pts*/
LDRSH r5, [r14, #2]
LDRSH r4, [r14]
ADD r14, #NPT
LDRSH r9, [r14, #2]
LDRSH r8, [r14]
ADD r14, #NPT
LDRSH r7, [r14, #2]
LDRSH r6, [r14]
ADD r14, #NPT
LDRSH r11, [r14, #2]
LDRSH r10, [r14]
ADD r14, #NPT
楼主确实专业!顶!
就搞不懂 ST公司的 牛人是啥回事!
语法错误:LDRSH r4, [r14],#NPT的 立即数限定
用 ADD 方法! ADD R4,#NPT
看了看手册介绍。扫盲一下都要了。
原文当NPT>=256时超出范围 out range
LDRSH Ar, [pIN],#NPT
参考手册:
LDRSH<c><q> <Rt>, [<Rn>, #+/-<imm>]!
这条指令的功能介绍:
Operation:
if ConditionPassed() then
EncodingSpecificOperations();
offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
address = if index then offset_addr else R[n];
if wback then R[n] = offset_addr;
R[t] = SignExtend(MemU[address,2], 32);
就是:如果#NPT是#+NPT 是加,
(R[n] + imm32)
#-NPT是减
(R[n] - imm32);
R[n] 作为offset_addr 偏移地址来寻址。
参数注释:
<c><q> See Standard assembler syntax fields on page A5-6.
<Rt> Specifies the destination register.
<Rn> Specifies the base register. This register is allowed to be the SP. If this register is the PC, see
LDRSH (literal) on page A5-143.
+/- Is + or omitted to indicate that the immediate offset is added to the base register value
(add == TRUE), or – to indicate that the offset is to be subtracted (add == FALSE).
Different instructions are generated for #0 and #-0.
<imm> Specifies the immediate offset added to or subtracted from the value of <Rn> to form the
address. The range of allowed values is 0-4095 for encoding T1, and 0-255 for encoding T2.
For the offset addressing syntax, <imm> can be omitted, meaning an offset of 0.
不行啊,你看有三个错误
..DSPLibsourceasmRVMDKcr4_fft_256_stm32.s(228): error: A1151E: Bad register name symbol
..DSPLibsourceasmRVMDKcr4_fft_256_stm32.s(228): error: A1151E: Bad register name symbol
ADD pIN, #NPT
8 楼
是这句的问题 ADD pIN, #NPT 应该为 ADD $pIN, #NPT
第一次是对的,后面3次的漏掉了$吧, 不知道我的说法正确吗?
LZ利害
LZ利害,我验证过库函数,64点的算法没有问题,256和1024的算法是错的,但是没有搞明白什么地方出问题了
这个例子有问题吧
#define N 64 /*Number of points*/
u32 x[N],y[N]; /* input and output arrays */
u16 real[N], imag[N]; /* real and imaginary arrays */
/* Fill the input array */
for(i=0; i<N; i++)
x = (((u16)(real)) | ((u32)(imag<<16)));
cr4_fft_64_stm32(y, x, N); /*computes the FFT of the x[N] samples*/
输入输出竟然都定义成了无符号的,这样有问题吧?如果输入是实数,虚部为零,那么把输入定义成无符号的,大不了相当于固定加了个正的常数,也就是加了个直流分量,勉勉强强吧。输出是无论如何也不能定义成无符号数的吧?