fft例子_FFT原理通俗易懂

fft例子_FFT原理通俗易懂FFT原理与实现#define N 128 #define POWER 6//该值代表了输入数据首先被放大的倍数,放大倍数为2^POWER #define P_COEF 8//该值代表了旋转因子被放大的倍数,放大倍数为2^POWER #

FFT原理与实现   #define N 128 #define POWER 6//该值代表了输入数据首先被放大的倍数,放大倍数为2^POWER #define P_COEF 8//该值代表了旋转因子被放大的倍数,放大倍数为2^POWER #if (N == 4) #define L 2//L的定义满足L = log2(N) #elif (N == 8) #define L 3//L的定义满足L = log2(N) #elif (N == 16) #define L 4//L的定义满足L = log2(N) #elif (N == 32) #define L 5//L的定义满足L = log2(N) #elif (N == 64) #define L 6//L的定义满足L = log2(N) #elif (N == 128) #define L 7//L的定义满足L = log2(N) #endif //AD采样位数为12位,本可以采用s16 x[N]定义数据空间,但是为了节省存储空间,fft结果也将存储在该变量空间。由于受 //fft影响变量需要重新定义,定义的方式及具体原因如下: //fft过程会乘以较大旋转因子,因此需要32位定义 //fft过程会产生负数,因此需要有符号定义 //fft过程会出现复数,因此需要定义二维数组,[][0]存放实部,[][1]存放虚部 s32 x[N][2] = {}; //定义*p[N]是为了在第一次指针初始化以后,该数组指针按照位倒序指向数据变量x //p[i][0]代表了指向数据的实部,p[i][1]代表了指向数据的虚部 s32 *p[N]; //定义旋转因子矩阵 //旋转因子矩阵存储了wn^0,wn^1,wn^2…wn^(N/2-1)这N/2个复数旋转因子 s16 w[N>>1][2] = {256,0,256,-13,255,-25,253,-38,251,-50,248,-62,245,-74,241,-86,237,-98,231,-109,226,                     -121,220,-132,213,-142,206,-152,198,-162,190,-172,181,-181,172,-190,162,-198,152,                     -206,142,-213,132,-220,121,-226,109,-231,98,-237,86,-241,74,-245,62,-248,50,-251,38,                     -253,25,-255,13,-256,0,-256,-13,-256,-25,-255,-38,-253,-50,-251,-62,-248,-74,-245,-86,                     -241,-98,-237,-109,-231,-121,-226,-132,-220,-142,-213,-152,-206,-162,-198,-172,-190,-181,                     -181,-190,-172,-198,-162,-206,-152,-213,-142,-220,-132,-226,-121,-231,-109,-237,-98,-241,                     -86,-245,-74,-248,-62,-251,-50,-253,-38,-255,-25,-256,-13}; void init_pointer(void) { unsigned char i = 0; unsigned char j = 0; unsigned char k = 0; for(i = 0; i < N; i++) { j = 0; for(k = 0; k < L; k++) { j |= (((i >> k)&0x01)<<(L-k-1)); } p[i] = &x[j][0]; } } /* *description:基2fft主函数,该函数将借助指针数组p对全局变量数组x进行fft计算 * 并将结果存储在数组x中 *global var:rw->x; r->p,w。(r表示读,w表示写,rw表示读写) */ void fft2(void) { u8 i;//i用于表示蝶形图级联的阶数 u8 j;//表示蝶形分组起始点序列,蝶形分组跨度为2^i u8 k;//k表示蝶形组内偶数分支序列点号 u8 gp_distance = 1;//蝶形分组跨度 u8 temp;//temp用于记录当前组间距离的一半,同时也表示了同一碟形两分支间的距离 u8 gp_hf = 0;//记录当前组的中间点序号 u8 delta = N;//旋转因子下标增量,本来下标初始值应该为N/2,但是。。 s16 *pw = &(w[0][0]); int tp_result[2]; //用于临时存放旋转因子和奇数分组的乘积 //输入信号序列放大 for(i = 0; i < N; i++) { x[i][0] <<= POWER; x[i][1] <<= POWER; } for(i = 0; i < L; i++) { temp = gp_distance; gp_distance <<= 1; for(j = 0; j < N; j+=gp_distance) { gp_hf = temp + j; pw = &(w[0][0]); for(k = j; k < gp_hf; k++)//完成一组内的所有蝶形运算 { //蝶形运算中的一组复数乘法过程 tp_result[0] = pw[0] * (p[k+temp][0]) – pw[1] * (p[k+temp][1]); tp_result[1] = pw[0] * (p[k+temp][1]) + pw[1] * (p[k+temp][0]); tp_result[0] >>= P_COEF; tp_result[1] >>= P_COEF; //蝶形运算中的2组复数加法过程 p[k+temp][0] = p[k][0] – tp_result[0]; p[k+temp][1] = p[k][1] – tp_result[1]; p[k][0] += tp_result[0]; p[k][1] += tp_result[1]; pw += delta; } } delta >>= 1; } }

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/65713.html

(0)
上一篇 2024年 8月 9日 下午5:20
下一篇 2024年 8月 9日

相关推荐

关注微信