⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fft.c

📁 基于LPC2132的FFT处理程序。。 。。 。。
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************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)
{   
    int32 b,j1,i,j2;
    j1=j;
    b=0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -