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

📄 2007720111224.c

📁 c8051f020的频域的2FFT算法,
💻 C
字号:
//频域基2fft快速算法
#include <C8051F020.H>
#include<math.h>
#include<intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
sfr16 DP  =0x82;
sfr16 TMR3RL= 0x92;
sfr16 TMR3  = 0x94;
sfr16 ADC0  = 0xbe;
sfr16 ADC0GT= 0xc4;
sfr16 ADCOLT= 0xc6;
sfr16 RCAP2 = 0xca;
sfr16 T2    = 0xcc;
sfr16 RCAP4 = 0xe4;
sfr16 T4    = 0xf4;
sfr16 DAC0  = 0xd2;
sfr16 DAC1  = 0xd5;
#define SYSCLK 12000000
#define SAMPLERATE0 8000
#define SAMPLE_RATE_DAC 1000
#define NUM_SAMPLES 256
#define TRUE 1
#define FALSE 0
//unsigned char data Dac0_val;
//unsigned char data Dac1_val;
sbit LED=P1^6;
sbit SW1=P3^7;
unsigned long frequency=1000;
struct compx 
{ 
	float real;
	float imag;
} compx ;
void SYSCLK_Init(void);
void PORT_Init(void);
void UART0_Init(void);
void ADC0_Init(void);
void Timer3_Init(int counts);
void Timer4_Init(int counts);
void Timer4_ISR(void);
void ADC0_ISR(void);
void PORT_Init(void);
bit ADC0_DONE;
struct compx EE(struct compx b1,struct compx b2);//复数乘法
void FFT(struct compx *xin,int N,int m);
void sleep_ms(uchar count);
xdata struct compx xin[256];
idata unsigned char ss[127];
void main(void)
{
	int data i;
	data float *s=xin;
	data uchar *pss;
	DAC0H=0;
	DAC0L=0;
	DAC1H=0;
	DAC1L=0;
	WDTCN=0xde;//关看门狗kk
	WDTCN=0xad;
	PORT_Init();//端口初始化
    DAC0CN = 0x97;                   // enable DAC0 in left-justified mode
                                    // using Timer4 as update scheduler	
    DAC1CN = 0x97;                   // enable DAC0 in left-justified mode
                                    // using Timer4 as update scheduler	
	SYSCLK_Init();//时钟初始化
	Timer3_Init(SYSCLK/SAMPLERATE0);//定时器初始化
    Timer4_Init(SYSCLK/SAMPLE_RATE_DAC); // initialize T4 to generate DAC0
                                    // schedule

	ADC0_Init();//ADC0初始化
	EA=1;//开中断	
	for(i=0;i<256;i++)//初始化虚部
	{
		xin[i].real=i;
		xin[i].imag=0;
	}
	while(1)//取样
	{
		if(ADC0_DONE)
		{
			LED=1;
			FFT(xin,256,8);//进行FFT运算
			s=xin;
			for(i=1;i<128;i++)//计算FFT模值
			{
				*s=sqrt(xin[i].real*xin[i].real+xin[i].imag*xin[i].imag);
				s++;
			}
			s=xin;
			pss=ss;
			for(i=1;i<128;i++)//对幅值取整
			{
				*(pss-1)=ceil(*s/667);//matlab仿真数值调整
				s++;
				pss++;
			}
		}
		EIE2|=0X02;
		while(ADC0_DONE==FALSE);
		LED=0;
	}
}

struct compx EE(struct compx b1,struct compx b2)//复数乘法
{
	struct compx b3;
	b3.real=b1.real*b2.real-b1.imag*b2.imag;
	b3.imag=b1.real*b2.imag+b1.imag*b2.real;
	return b3;
}
void FFT(struct compx *xin,int N,int m)
{
	//N序列长度,2^m=N
	data int f,LH,nm,i,k,j,L;
	data float p , ps ;
	data int le,B,ip;
	data float pi;
	data struct compx w,t;
	LH=N/2;  
	f=N;
	for(L=m;L>=1;L--)    /*这里和时域的也有差别,第L级碟形运算,L递减,时域L递增*/
	{  
		le=pow(2,L);//每一级碟形运算的点数
		B=le/2; /*每一级碟形运算间隔的点数*/
		pi=3.14159;
		for(j=0;j<=B-1;j++)
		{
		//计算WN
			p=pow(2,m-L)*j;
			ps=2*pi/N*p;
			w.real=cos(ps);
			w.imag=-sin(ps);
			for(i=j;i<=N-1;i=i+le)//碟形运算
			{ 
				ip=i+B;   
				t=xin[i];
				xin[i].real=xin[i].real+xin[ip].real;
				xin[i].imag=xin[i].imag+xin[ip].imag;   
				xin[ip].real=t.real-xin[ip].real;
				xin[ip].imag=t.imag-xin[ip].imag;     
				xin[ip]=EE(xin[ip],w);
			}
		}
	}
		/*变址运算*/
		nm=N-2;    
		j=N/2;
		for(i=1;i<=nm;i++)
		{
			if(i<j)
			{
				t=xin[j];
				xin[j]=xin[i];
				xin[i]=t;
			}
			k=LH;
			while(j>=k)
			{
				j=j-k;k=k/2;
			}
			j=j+k;
		}
}
void sleep_ms(uchar count)
{
	data uchar ii,jj;
	for(ii=0;ii<count;ii++)
	{
		for(jj=0;jj<250;jj++)
		_nop_();
	}
}
void SYSCLK_Init(void)
{
	int i;
	OSCXCN=0X67;
	for(i=0;i<256;i++);
	while(!(OSCXCN&0X80));
	OSCICN=0X88;
}
void PORT_Init(void)
{
	XBR0=0X04;
	XBR1=0X00;
	XBR2=0X40;
	P0MDOUT|=0X01;
	P1MDOUT|=0X40;
}
void ADC0_Init(void)
{
	ADC0CN=0X05;
	REF0CN=0X07;
	AMX0SL=0X00;
	ADC0CF=(SYSCLK/250000)<<3;
	ADC0CF&=~0X07;
	EIE2&=~0X02;
	AD0EN=1;
}
void Timer3_Init(int counts)
{
	TMR3CN=0X02;
	TMR3RL=-counts;
	TMR3=0XFFFF;
	EIE2&=~0X01;
	TMR3CN|=0X04;
}
void ADC0_ISR(void) interrupt 15 using 3
{
	static unsigned num_samples=0;
	AD0INT=0;
	xin[num_samples].real=ADC0;
	num_samples++;
	if(num_samples==NUM_SAMPLES)
	{
		num_samples=0;
		EIE2&=~0X02;
		ADC0_DONE=1;
	}
}
void Timer4_Init (int counts)
{
   T4CON = 0;                       // STOP timer; set to auto-reload mode
   CKCON |= 0x40;                   // T4M = '1'; Timer4 counts SYSCLKs
   RCAP4 = -counts;                 // set reload value
   T4 = RCAP4;
   EIE2 |= 0x04;                    // enable Timer4 interrupts
   T4CON |= 0x04;                   // start Timer4
}
void Timer4_ISR (void) interrupt 16
{
	static unsigned count=1;
	DAC0H=count;
	DAC1H=ss[count];
	count++;
	if(count==128)
	{
		count=1;
	}
}

⌨️ 快捷键说明

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