/****************************************Copyright (c)**************************************************
**
** UnionTek Lab 2005
**
**--------------文件信息--------------------------------------------------------------------------------
** 文 件 名: fft.c
** 创 建 人: GD
** 最后日期: 2005年09月01日
** 描 述: 快速傅立叶变换
**
** 保密级别: 机密
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创 建 人: GD
** 版 本: v1.0
** 日 期: 2005年09月01日
** 描 述: 原始版本
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修 改 人:
** 版 本:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include "config.h"
/***********************************************************************
* 参数制订
***********************************************************************/
typedef struct
{
float FFT_Xreal[FFTSIZE]; //实部
float FFT_Ximag[FFTSIZE]; //虚部
uint32 sample_count; //采样计数器
uint32 finsh_flage; //采样完成标志
}FFT_Struct;
FFT_Struct FFT__sbuff;
uint32 fft_worng;
fp32 ADC_Buf[FFTSIZE];
fp32 FFT_WNSin[FFTSIZE/2];
fp32 FFT_WNCos[FFTSIZE/2];
/***********************************************************************
*
* FFT驱动部分
*
***********************************************************************/
/***********************************************************************
* 名 称: void FFT_Init(void)
* 功 能:FFT分析初始化
* 入口参数:
* 出口参数: 无
* 说 明: 无
***********************************************************************/
void FFT_Init(void)
{
uint32 i;
fp32 j;
i = 0;
j = 0;
FFT__sbuff.sample_count=0;
FFT__sbuff.finsh_flage=1;
/***********************************************************************
* 确定Wn
***********************************************************************/
for(i=0;i<(FFTSIZE/2);i++)
{
j = (6.28315*i)/FFTSIZE;
FFT_WNSin[i] = sin(j);
FFT_WNCos[i] = cos(j);
j = (720*i)/FFTSIZE;
FFT_WNSin[i] = SinTable_360(j);
FFT_WNCos[i] = CosTable_360(j);
}
/***********************************************************************
* 测试程序
***********************************************************************/
ADC_Buf[0] = -3000;
ADC_Buf[1] = 1000;
ADC_Buf[2] = 2000;
ADC_Buf[3] = -500;
ADC_Buf[4] = -3000;
ADC_Buf[5] = -1000;
ADC_Buf[6] = 2000;
ADC_Buf[7] = 0;
FFT_Count();
i = FFT_FindMAX(&j);
DelayNS(i);
Timer1_Init();
ADC_Init((1<<3),3000000); //选择P0.30 ADC0.3
}
/***********************************************************************
* 名 称: void FFT_Init(void)
* 功 能:FFT分析初始化
* 入口参数:
* 出口参数: 无
* 说 明: 无
***********************************************************************/
void __irq IRQ_FFT(void)
{
//ADC_Buf[FFT__sbuff.sample_count] = 1;
ADC_Buf[FFT__sbuff.sample_count] = ((fp32)ADC_Read()/1000-1.5);
AD0CR |= 1<<24;
FFT__sbuff.sample_count++;
if(FFT__sbuff.sample_count>=FFTSIZE)
{
FFT__sbuff.finsh_flage=1;
FFT__sbuff.sample_count=0;
FFT_Count();
}
T1IR = 0x01;
VICVectAddr = 0x00;
}
/***********************************************************************
*
* FFT应用部分
*
***********************************************************************/
/***********************************************************************
* 名 称: uint32 FFT_FindMAX(fp32 *max_value)
* 功 能:寻找频率幅度最高点,且从输入缓冲中写入该电的值
* 入口参数:获取最大值的数据(功率)缓冲
* 出口参数: 无
* 说 明: 无
***********************************************************************/
uint32 FFT_FindMAX(fp32 *max_value)
{
uint32 i,max_point=0;
fp32 m;
*max_value = 0;
for(i=0;i<(FFTSIZE/2);i++)
{
m = FFT__sbuff.FFT_Xreal[i]*FFT__sbuff.FFT_Xreal[i]+FFT__sbuff.FFT_Ximag[i]*FFT__sbuff.FFT_Ximag[i];
if(m>*max_value)
{
max_point = i;
*max_value = m;
}
}
max_point = max_point*(SAMPLE_FREQUENCY/FFTSIZE);
return(max_point);
}
/***********************************************************************
*
* FFT运算部分
*
***********************************************************************/
/***********************************************************************
* 名 称: void FFT_ChnageAddr(uint32 addr)
* 功 能:FFT变址计算
* 入口参数:需要查询的序号
* 出口参数: 无
* 说 明: 无
***********************************************************************/
uint32 FFT_ChnageAddr(uint32 addr)
{
uint32 i,j=0;
for(i=0;i<FFTNUM;i++)
{
j = j<<1;
j |= addr&0x01;
addr = addr>>1;
}
return(j);
}
/***********************************************************************
* 名 称: void FFT_Count(fp32 *ADC0_Buf,fp32 *FFT_Xreal,fp32 *FFT_Ximag)
* 功 能:FFT计算
* 入口参数:AD输入数据缓冲,FFT输出数据缓冲
* 出口参数: 无
* 说 明: 无
***********************************************************************/
uint32 FFT_Count(void)
{
uint32 i,j,k,l,m,degree;
fp32 c,s;
fp32 treal,timag,mtr,mti;
if(FFT__sbuff.finsh_flage==0) return(0); //采样还没有完成
//for(i=0;i<FFTSIZE;i++)
//{
// ADC_Buf2[i] = ADC_Buf[i];
//}
FFT__sbuff.finsh_flage=0;
/***********************************************/
// 变址
/***********************************************/
for(i=0;i<FFTSIZE;i++)
{
j = FFT_ChnageAddr(i);
//c =ADC_Buf[i];
//c = (c/1000)-1.5;
FFT__sbuff.FFT_Xreal[j] = ADC_Buf[i];
FFT__sbuff.FFT_Ximag[j] = 0;
}
/***********************************************/
// FFT运算
/**********************************************/
for(i=0;i<FFTNUM;i++) //层循环
{
l = 1;
if(i==0) //第1层需要特殊处理
{
for(l=0;l<FFTSIZE;l=l+2)
{
mtr = FFT__sbuff.FFT_Xreal[l];
mti = FFT__sbuff.FFT_Ximag[l];
FFT__sbuff.FFT_Xreal[l] += FFT__sbuff.FFT_Xreal[l+1];
FFT__sbuff.FFT_Ximag[l] += FFT__sbuff.FFT_Ximag[l+1];
FFT__sbuff.FFT_Xreal[l+1] = mtr-FFT__sbuff.FFT_Xreal[l+1];
FFT__sbuff.FFT_Ximag[l+1] = mti-FFT__sbuff.FFT_Ximag[l+1];
k++;
}
}
else
{
m = 2<<(i-1);
for(l=0;l<FFTSIZE;l=l+(2<<i)) //内部列循环
{
for(j=0;j<(2<<(i-1));j++)
{
/*
degree = (FFTNUM-i)*j;
degree = (6.28315*degree)/FFTSIZE;
c=cos(degree);
s=sin(degree);*/
/*
degree = (FFTNUM-i)*j;
degree = (720*degree)/FFTSIZE;
c=CosTable_360(degree);
s=SinTable_360(degree);
*/
degree = (FFTNUM-i)*j;
c=FFT_WNCos[degree];
s=FFT_WNSin[degree];
treal = FFT__sbuff.FFT_Xreal[m+l+j]*c + FFT__sbuff.FFT_Ximag[m+l+j]*s;
timag = FFT__sbuff.FFT_Ximag[m+l+j]*c - FFT__sbuff.FFT_Xreal[m+l+j]*s;
mtr = FFT__sbuff.FFT_Xreal[l+j];
mti = FFT__sbuff.FFT_Ximag[l+j];
FFT__sbuff.FFT_Xreal[l+j] += treal;
FFT__sbuff.FFT_Ximag[l+j] += timag;
FFT__sbuff.FFT_Xreal[l+m+j] = mtr-treal;
FFT__sbuff.FFT_Ximag[l+m+j] = mti-timag;
}
}
}
}
return(1);
}
/***********************************************************************
* 名 称: uint32 Ibitr(uint32 j, uint32 nu)
* 功 能:变址计算
* 入口参数:需要变址处理的序号,表示序号的位数
* 出口参数: 无
* 说 明: 无
***********************************************************************/
uint32 Ibitr(uint32 j, uint32 nu)
{
FFT.rar_FFT C程序_fft
版权申诉
116 浏览量
2022-09-21
04:56:51
上传
评论
收藏 5KB RAR 举报
我虽横行却不霸道
- 粉丝: 75
- 资源: 1万+
最新资源
- 华为云会议安装包适配华为擎云L410 -1060 ARM架构
- 清空redis缓存脚本指令
- STM8S微控制器-寄存器操作指南
- apk一键安装,获取apk签名信息
- opencv4.8.0+contrib+cuda文件
- 【全网最新最全】大气公司年度月度总结汇报PPT
- C语言实现低功耗STM32F411开发板(原理图+PCB源文件+官方例程+驱动等).zip
- C语言实现基于STM32 的联合调试侦听设备解决方案(原理图、PCB源文件、调试工具、视频).zip
- 【全网最全最酷】部门年度年终工作总结汇报PPT模板
- C语言实现基于STM32F103RC的电子相册(原理图、PCB源文件、程序源码及制作).zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论0