|
#include
// C 语言标准输入输出函数库
#include
// C 数学函数库
#include
"mathlib.h"
// DSP 数学函数库
#include
"dsplib.h"
// DSP 函数库
// 软件断点
#define
SW_BREAKPOINT
asm(" SWBP 0 ");
// 快速傅里叶变换
// π 及 浮点数极小值
#define
PI
3.141592654
#define
F_TOL
(1e-06)
// 快速傅里叶变换测试
// 测试快速傅里叶变换点数
// 注意:TI DSP库 最大支持一次性计算 256K 个实数点的 FFT
#define N 1024
// 采样频率
#define Fs 1000.0
// 信号
#pragma DATA_ALIGN(Input, 8);
float Input[2 * N];
// 信号 副本
float InputOrig[2 * N];
// FFT 输出
#pragma DATA_ALIGN(FFT_Out, 8);
float FFT_Out[2 * N];
// IFFT 输出
#pragma DATA_ALIGN(IFFT_Out, 8);
float IFFT_Out[2 * N];
// 旋转因子
#pragma DATA_ALIGN(W, 8);
float W[2 * N];
// 二进制位翻转
#pragma DATA_ALIGN (brev, 8);
unsigned char brev[64] =
{
0x00, 0x20,
0x10, 0x30, 0x08, 0x28, 0x18, 0x38,
0x04, 0x24,
0x14, 0x34, 0x0c, 0x2c, 0x1c, 0x3c,
0x02, 0x22,
0x12, 0x32, 0x0a, 0x2a, 0x1a, 0x3a,
0x06, 0x26,
0x16, 0x36, 0x0e, 0x2e, 0x1e, 0x3e,
0x01, 0x21,
0x11, 0x31, 0x09, 0x29, 0x19, 0x39,
0x05, 0x25,
0x15, 0x35, 0x0d, 0x2d, 0x1d, 0x3d,
0x03, 0x23,
0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b,
0x07, 0x27,
0x17, 0x37, 0x0f, 0x2f, 0x1f, 0x3f
};
// 产生旋转因子
void tw_gen(float *w, int n)
{
int i, j,
k;
for(i =
1, k = 0; i < n >> 2; i++)
{
w[k ] = sin(2
* PI * i / n);
w[k + 1] = cos(2 * PI * i / n);
k += 2;
}
for(j =
1; j <= n >> 3; j = j << 2)
{
for(i = 0; i < n >> 3; i += j)
{
w[k]
= (float)sin( 4 * PI * i / n);
w[k + 1] = (float)cos( 4 * PI * i / n);
w[k + 2] = (float)sin( 8 * PI * i / n);
w[k + 3] = (float)cos( 8 * PI * i / n);
w[k + 4] = (float)sin(12 * PI * i / n);
w[k + 5] = (float)cos(12 * PI * i / n);
k += 6;
}
}
}
void tw_geni(float *w, int n)
{
int i, j,
k;
for(i =
1, k = 0; i < n >> 2; i++)
{
w[k ]
= sin (2 * PI * i / n);
w[k + 1] = -cos (2 * PI * i / n);
k += 2;
}
for(j =
1; j <= n >> 3; j = j << 2)
{
for(i = 0; i < n >> 3; i += j)
{
w[k]
= (float) -sin ( 4 * PI * i / n);
w[k + 1] = (float) cos ( 4 * PI * i / n);
w[k + 2] = (float) -sin ( 8 * PI * i / n);
w[k + 3] = (float) cos ( 8 * PI * i / n);
w[k + 4] = (float) -sin (12 * PI * i / n);
w[k + 5] = (float) cos (12 * PI * i / n);
k += 6;
}
}
}
int main(void)
{
//
产生待测试信号
unsigned int
i;
for (i = 0;
i < N; i++)
{
Input[i] = 5 * sin(2 * PI * 150 * (i / Fs)) + 15 * sin(2 * PI * 350
* (i / Fs));
}
//
基
unsigned
char rad;
if(N == 64
|| N == 256 || N == 1024 || N == 4096 || N == 16384 || N ==
65536)
{
rad = 4;
}
else if(N ==
32 || N == 128 || N == 512 || N == 2048 || N == 8192 || N ==
32768)
{
rad = 2;
}
else
{
printf ("不支持计算 %d 点快速傅里叶变换!\n", N);
while(1);
}
//
保留一份输入信号副本
memcpy(InputOrig, Input, 2 * N * sizeof(float));
//
产生旋转因子
tw_gen(W,
N);
// FFT
计算
DSPF_sp_fftSPxSP_r2c(N, Input, W, FFT_Out, brev, rad, 0, N);
//
计算振幅
float mo[2 *
N];
for(i = 0; i
< N; i++)
{
if(i == 0)
{
mo[i] = mo[i] / N;
}
else
{
mo[i] = sqrtsp(powsp(FFT_Out[2 * i], 2) + powsp(FFT_Out[ 2 * i +
1], 2));
mo[i] = mo[i] * 2 / N;
}
}
//
产生旋转因子
tw_geni(W,
N);
// IFFT
计算
DSPF_sp_ifftSPxSP_c2r(N, FFT_Out, W, IFFT_Out, brev, rad, 0,
N);
for(i =
0; i < N; i++)
{
if(abs(IFFT_Out[i] - InputOrig[i]) > F_TOL)
{
printf("失败 M 原始数据 .5f 逆变换 .5f\r\n", i, InputOrig[i],
IFFT_Out[i]);
}
}
//
断点
SW_BREAKPOINT;
}
|