|
这两天有空看了一下STM32的DSP库,并且在MDK中进行软件仿真,发现其计算的结果与理论值有一定的差异,软件模拟了幅值为10000的正弦波,频率为50Hz,采样频率3200,采样点为64点,调用64点的FFT,得到的值为7070,与理论值7071有一点点差异,这个可以理解,但是将幅值改为100时,计算出的值为705,假如把7070作为标准值,那么幅值为1000时的理论值应该为707,而FFT计算出的值为705,差了2,线性度不是很好,可能程序里舍入误差有点大,我以前的程序用的是DFT,其计算的结果准确度和线性度完全由于DSP库的FFT程序,我的程序主要用来做交流采样的,看来只有自己用汇编重新编FFT的程序了。
测试代码如下:
typedef unsigned char uint8; // 无符号8位整型变量
typedef signed char sint8; // 有符号8位整型变量
typedef unsigned short uint16; // 无符号16位整型变量
typedef signed short sint16; // 有符号16位整型变量
typedef unsigned int uint32; // 无符号32位整型变量
typedef signed int sint32; // 有符号32位整型变量
typedef float fp32; // 单精度浮点数(32位长度)
typedef double fp64; // 双精度浮点数(64位长度)
#include <math.h>
void cr4_fft_64_stm32(void *pssOUT, void *pssIN, uint16 Nbin);
void cr4_fft_256_stm32(void *pssOUT, void *pssIN, uint16 Nbin);
void cr4_fft_1024_stm32(void *pssOUT, void *pssIN, uint16 Nbin);
sint32 data_in[1000];
sint32 data_out[1000];
sint16 dft_out[100];
sint32 samp_cnt;
fp64 sum1,sum2,sum3,sum4,sum5,sum6;
fp64 sum_fft;
fp64 fk;
#define PI_2 6.283185307179586476925286766559
#define SAMP_CLK 3200.
int main(void)
{
sint16 i,deti;
fp64 sign_frq;
sint16 base_num,fk_num;
base_num = 1;
fk_num= 9;
sign_frq = 50;
samp_cnt = (sint16)(SAMP_CLK / sign_frq + 0.5);
for(i = 0;i < 1000;i ++)
{
fk = (i * sign_frq) / SAMP_CLK;
data_in = (sint32)((1000 * sqrt(2) * sin(base_num * fk * PI_2) + 0 * sqrt(2) * sin(fk_num * fk * PI_2))) * 65536;
}
sum1 = 0;
sum2 = 0;
deti = 20;
// data_out中保存根据算法计算的各次DFT结果,可以与sum1、sum2、sum3、sum4的值进行对比
cr4_fft_64_stm32(&data_out[0], &data_in[deti], 64);
for(i = 0;i < 32;i ++)
{
dft_out[2 * i] = data_out & 0xFFFF;
dft_out[2 * i + 1] = data_out >> 16;
}
for(i = 0;i < samp_cnt;i ++)
{
// sum1、sum2:基波的实部、虚部的理论值
sum1 += (double)(data_in[i + deti] / 65536) * (sint32)(32767 * cos(base_num * i * PI_2 / samp_cnt)) / 64 / 32767;
sum2 += (double)(data_in[i + deti] / 65536) * (sint32)(32767 * sin(base_num * i * PI_2 / samp_cnt)) / 64 / 32767;
// sum3、sum4:谐波的实部、虚部的理论值
sum3 += (double)data_in * (sint32)(32767 * cos(fk_num * i * PI_2 / samp_cnt)) / 64 / 32767;
sum4 += (double)data_in * (sint32)(32767 * sin(fk_num * i * PI_2 / samp_cnt)) / 64 / 32767;
}
sum5 = sqrt(sum1 * sum1 + sum2 * sum2);
sum6 = sqrt(sum3 * sum3 + sum4 * sum4);
sum_fft = sqrt((sint32)dft_out[2] * dft_out[2] + (sint32)dft_out[3] * dft_out[3]);
while(1);
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|