📄 fft.txt
字号:
#include "f2407_c.h"
#include "math.h"
#define N 32 // FFT变换的点数
extern void fft(void);
extern void resave(void);
interrupt void phantom(void);
void sysinit(void);
extern int input[2*N]; // 输入数据的存储数组
int indati[N]={0};
// -----------------------------------------------------------------------------------
// 128 点 FFT所需的数据
// 采样函数: x=1/4+1/4cos(3*2*pi*f*t)+1/4cos(6*2*pi*f*t)+1/4cos(9*2*pi*f*t);
// f=50Hz
// -----------------------------------------------------------------------------------
/* int indatr[N]={16394,15871,14425,12398, 10276 ,8584 , 7767 , 8088 ,9557 , 11913 , 14660 ,17155 , 18724 , 18802 , 17044 , 13411 , 8197 , 1995 , -4389 ,-10071, -14231 , -16255 ,-15844, -13057 ,-8309 , -2296, 4125 , 10079, 14819, 17843 , 18969, 18342 , 16394 ,13739 , 11055 , 8950 , 7848, 7921 , 9070 , 10961, 13110 , 14992 , 16159 , 16334 ,5479 , 13792 , 11675 , 9640 , 8197 , 7741, 8457, 10264 , 12815 , 15554 , 17812 ,18939 , 18429 , 16034 , 11825 , 6203 , -156, -6405, -11662 , -15165 , -16394 , -15165 ,-11662 , -6405 , -156 , 6203 , 11825 , 16034, 18429, 18939 , 17812 , 15554 , 12815 ,10264 , 8457 , 7741 , 8197, 9640 , 11675, 13792, 15479 , 16334 , 16159, 14992 ,13110 , 10961 , 9070 ,7921 , 7848 , 8950 , 11055 , 13739 , 16393 , 18342 , 18969 ,17843 , 14819 , 10079 ,4125 , -2296 , -8309 , -13057 , -15844 , -16255 , -14231 , -10071 ,-4389 , 1995 , 8197 , 13411 , 17044 , 18802 , 18724 , 17155 , 14660 , 11913 , 9557 ,8088 , 7767, 8584 , 10276 , 12398 , 14425 , 15871 ,
};*/
// -----------------------------------------------------------------------------------
// 32点FFT所需的数据
// 采样函数: x=1/4+1/4cos(3*2*pi*f*t)+1/4cos(6*2*pi*f*t)+1/4cos(9*2*pi*f*t);
// f=50Hz ;pi=π;
// -----------------------------------------------------------------------------------
/* int indatr[N]={16384, 10270, 9551 , 18713 , 8192 , -14222 , -8304 , 14810 , 16384 ,7843 , 13102 ,15469, 8192 , 12807 , 18418 , -0156 ,-16384 , -0156 , 18418 , 12807 , 8192 , 15469,13102 , 7843 , 16383 , 14810 , -8304 , -14222 , 8192 , 18713 , 9551 , 10270 ,
};*/
int indatr[N]={0x07ff, 0x07ff, 0x07ff , 0x07ff , 0x07ff , 0x07ff , 0x07ff , 0x07ff , 0x07ff ,0x07ff , 0x07ff ,0x07ff, 0x07ff , 0x07ff , 0x07ff , 0x07ff ,0x0F801 , 0x0F801 , 0x0F801 , 0x0F801 , 0x0F801 , 0x0F801,0x0F801 , 0x0F801, 0x0F801 , 0x0F801 , 0x0F801 , 0x0F801 , 0x0F801 , 0x0F801 , 0x0F801 , 0x0F801 ,
};
// -----------------------------------------------------------------------------------
// 64点 FFT所需的数据
// 采样函数: x=1/4+1/4cos(3*2*pi*f*t)+1/4cos(6*2*pi*f*t)+1/4cos(9*2*pi*f*t);
// f=50Hz
// -----------------------------------------------------------------------------------
/* int indatr[N]={16384 , 14416, 10270, 7762, 9551 , 14651 , 18713, 17034, 8192 , -4387 , -14222,-15834 , -8304 , 4123 , 14810 , 18957 , 16384 , 11049 , 7843 , 9064 , 13102 , 16149 ,15469 , 11668 , 8192 , 8452 , 12807 , 17801 , 18418 , 11818, -0156 , -11655 , -16384 , -11655 , -0156 , 11818 , 18418 , 17801, 12807 , 8452 , 8192, 11668 , 15469 , 16149 ,13102 , 9064 , 7843 , 11049 , 16383 , 18957 , 14810 , 4123 , -8304 , -15834 , -14222 ,-4387 , 8192 , 17034 , 18713 , 14651 , 9551 , 7762 , 10270 , 14416 , };*/
// ---------------------------------------------------------------
// 128 点 FFT的sin 和 cos值存储表
// ---------------------------------------------------------------
/* const int sintab[N]={0x07fff,0x0,0x07fd9,0x0f9b9,0x07f62,0x0f375,0x07e9d,0x0ed38,
0x07d8a,0x0e708,0x07c2a,0x0e0e7,0x07a7d,0x0dad8,0x07885,0x0d4e1,
0x07642,0x0cf05,0x073b6,0x0c946,0x070e3,0x0c3aa,0x06dca,0x0be32,
0x06A6C,0x0B8E4,0x066CE,0x0B3C1,0x062F1,0x0AECD,0x05ED6,0x0AA0C,
0x05A81,0x0A57F,0x055F4,0x0A12A,0x05133,0x09D0F,0x04C3F,0x09932,
0x0471C,0x09594,0x041CD,0x09237,0x03C56,0x08F1F,0x036B9,0x08C4B,
0x030FB,0x089C0,0x02B1E,0x0877D,0x02527,0x08584,0x01F19,0x083D7,
0x018F8,0x08277,0x012C7,0x08164,0x00C8B,0x0809F,0x00647,0x08029,
0x00000,0x08001,0x0F9B9,0x08029,0x0F375,0x0809F,0x0ED39,0x08164,
0x0E708,0x08277,0x0E0E7,0x083D7,0x0DAD9,0x08584,0x0D4E2,0x0877D,
0x0CF05,0x089C0,0x0C947,0x08C4B,0x0C3AA,0x08F1F,0x0BE33,0x09237,
0x0B8E4,0x09594,0x0B3C1,0x09932,0x0AECD,0x09D0F,0x0AA0C,0x0A12A,
0x0A57F,0x0A57F,0x0A12A,0x0AA0C,0x09D0F,0x0AECD,0x09932,0x0B3C1,
0x09594,0x0B8E4,0x09237,0x0BE33,0x08F1F,0x0C3AA,0x08C4B,0x0C947,
0x089C0,0x0CF05,0x0877D,0x0D4E2,0x08584,0x0DAD9,0x083D7,0x0E0E7,
0x08277,0x0E708,0x08164,0x0ED39,0x0809F,0x0F375,0x08029,0x0F9B9
};*/
// ---------------------------------------------------------------
// 64点 FFT的sin 和 cos值存储表
// ---------------------------------------------------------------
/* const int sintab[N]={ 0x7FFF,0x0000,0x7F61 ,0xF375, 0x7D89 , 0xE708 , 0x7A7C , 0xDAD9,0x7640, 0xCF05 ,0x70E1 ,0xC3AA ,0x6A6C , 0xB8E4 , 0x62F1 , 0xAECD ,
0x5A81, 0xA57F, 0x5133, 0x9D0F, 0x471C , 0x9594, 0x3C56, 0x8F1F,
0x30FB, 0x89C0 ,0x2527, 0x8584 ,0x18F8 , 0x8277 , 0x0C8B , 0x809F,
0x0000 ,0x8001, 0xF375, 0x809F, 0xE708 , 0x8277 , 0xDAD9 , 0x8584,
0xCF05 ,0x89C0 ,0xC3AA, 0x8F1F, 0xB8E4 , 0x9594 , 0xAECD , 0x9D0F,
0xA57F, 0xA57F, 0x9D0F, 0xAECD, 0x9594 , 0xB8E4 , 0x8F1F , 0xC3AA,
0x89C0, 0xCF05, 0x8584 ,0xDAD9 ,0x8277 , 0xE708 , 0x809F , 0xF375, };*/
// ---------------------------------------------------------------
// 32 点 FFT的sin 和 cos值存储表
// ---------------------------------------------------------------
const int sintab[N]={
0x7FFF,0x0000,0x7D89,0xE708,0x7640,0xCF05,0x6A6C,0xB8E4,
0x5A81,0xA57F,0x471C,0x9594,0x30FB,0x89C0,0x18F8,0x8277,
0x0000,0x8001,0xE708,0x8277,0xCF05,0x89C0,0xB8E4,0x9594,
0xA57F,0xA57F,0x9594,0xB8E4,0x89C0,0xCF05,0x8277,0xE708,
};
extern int table128[];
extern int nom; // 当nom=1时, FFT 需要归一化处理
main()
{ int i;
double x=0,y;
nom=1; // 需要归一化处理
sysinit();
for(i=0;i<=255;i++) input[i]=0; // 清除输入数据
resave(); // 把原始的输入数据反序排列
*PCDATDIR=(*PCDATDIR&0x0FF00)|0x01;
fft( ); // 进行FFT运算
*PCDATDIR=*PCDATDIR&0x0FF00;
}
void interrupt phantom(void)
{
return;
}
void sysinit(void)
{
*SCSR1=0x81FE;
*WDCR=0x0E8;
*IFR=0x0FF;
*IMR=0x0;
WSGR=0;
*MCRB=0;
*PCDATDIR=0x100;
}
(2)反序排列子程序
.def _resave
// 基2时间抽取的128点FFT算法需要定义的各量
// N .set 128
// 基2时间抽取的64点FFT算法需要定义的各量
// N .set 64
// 基2时间抽取的32点FFT算法需要定义的各量
N .set 32
.global _resave
.global _input
.global _indatr
.global _indati
_resave:
//-------------------------------------------------------------------
// 与C语言兼容的代码部分
// -------------------------------------------------------------------
POPD *+
SAR AR0,*+
SAR AR1,*
LAR AR0,*+,AR3
// ------------------------------------------------------------------
// 反序排列程序部分
//------------------------------------------------------------------
LAR AR2,#_input
LAR AR3,#_indatr
LAR AR0,#N
LAR AR4,#(N-1)
RESAV1
LACC *+,0,AR2
SACL *BR0+,AR4
BANZ RESAV1,*-,AR3
//-------------------------------------------------------------------
// 与C语言兼容的程序代码部分
//-------------------------------------------------------------------
MAR *,AR1
SBRK #2
LAR AR0,*-
PSHD *
RET
(3) FFT应用子程序
// -------------------------------------------------------------------------------------------------
// 函数名: void fft(void)
// 功能:实现32、64或128采样点的快速傅立叶变换
// 入口条件:
// _sintab 存放FFT运算中用到的sin和cosin函数值
// _input 存放FFT运算中用到的数据,包括实部和虚部,按二进制反序排列
// 注意:由于“*BR0+”间接寻址方式对_input的地址有特殊的要求,
// 所以最好将数组_input放置在一个独立的块中,如B1块。
// _nom 当_nom=0时,本函数将不对运算结果进行归一化。反之,将对每
// 一步运算结果进行归一化处理,避免溢出,但是,它会使运算精度降低。
// N 常数,参与FFT运输的点数,用户可根据需要选择,例如,需要进行128点
// FFT时,请在本函数中做出如下选择:
// N .set 128
// M .set 7
// 依此类推。
// 出口条件:
// _input 存放FFT的运算结果
// 本函数可供C调用,请用户在C主程序中作以下声明:
// extern void fft(void);
// const int sintab[N]={...}; N为128、64或32
// extern int _input[2*N];
// extern int nom;
//--------------------------------------------------------------------------------------------------
.def _ fft
// 基2时间抽取的128点FFT算法需要定义的各量
// N .set 128 // 点数
// M .set 7 // N=2**M
// 基2时间抽取的64点FFT算法需要定义的各量
// N .set 64 // 点数
// M .set 6 // N=2**M
// 基2时间抽取的32点FFT算法需要定义的各量
N .set 32 // 点数
M .set 5 // N=2**M
_input .usect ".data0",2*N // 输入数据
// .bss _sintab,N // SIN和COSIN函数的存储表
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -