用单片机对模拟信号进行转换,转换后做FFT快速傅里叶变换。
#include<math.h>
#define SYSCLK 11000000
#define PI 3.1415926536
#define size_x 1024
sfr16 ADC0 = 0xbe;
typedef struct{
float real;
float img;
}complex;
complex W[512];
complex xdata x[1024];
float p=0; //总功率
unsigned int h;
void SYSCLK_Init (void)
{
int i; // delay counter
OSCXCN = 0x67; // start external oscillator with
// 11MHz crystal
for (i=0; i < 256; i++) ; // Wait for osc. to start up
while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle
OSCICN = 0x88; // select external oscillator as SYSCLK
// source and enable missing clock
// detector
// OSCICN = 0x07; //interal 16MHZ
}
void WDT_Init()
{
WDTCN = 0xde;
WDTCN = 0xad;
}
void T3_Init() //定时48.8us
{
TMR3CN=0x02;
TMR3RLL=(65536-540)%256;
TMR3RLH=(65536-540)/256;
TMR3L=(65536-540)%256;
TMR3H=(65536-540)/256;
TMR3CN|=0X04; //启动定时器
}
void ADC_Init()
{
AMX0CF=0X00; //通道0
AMX0SL=0X00;
ADC0CF = (SYSCLK/2500000) << 3; //SAR时钟为2.5mhz
ADC0CN = 0x84; //定时器3方式启动
REF0CN = 0x03;
EA=1;
EIE2|=0X02;
EIE1&= ~0x04;
}
void ADC0_ISR() interrupt 15
{
ADC0CN&=0xdf;
x[h].real=ADC0;
h++;
}
void add(complex a,complex b,complex *c)
{
c->real=a.real+b.real;
c->img=a.img+b.img;
}
void mul(complex a,complex b,complex *c)
{
c->real=a.real*b.real - a.img*b.img;
c->img=a.real*b.img + a.img*b.real;
}
void sub(complex a,complex b,complex *c)
{
c->real=a.real-b.real;
c->img=a.img-b.img;
}
void change() //倒位序
{
unsigned int i=0,j=0,k=0,t;
complex temp;
for(i=0;i<size_x;i++)
{
k=i;j=0;
t=(unsigned) (log(size_x)/log(2));
while(t--)
{
j=j<<1;
j|=(k & 1);
k=k>>1;
}
if(j>i)
{
temp=x[i];
x[i]=x[j];
x[j]=temp;
}
}
} //计算旋转因子
void init_W()
{
int i;
for(i=0;i<(size_x/2);i++)
{
W[i].real=cos(2*PI/size_x*i);
W[i].img=-1*sin(2*PI/size_x*i);
}
}
void FFT()
{
unsigned int i=0,j=0,k=0,l=0;
complex up,down;
change(); //倒位序
init_W(); //计算旋转因子
for(i=0;i<(int)( log(size_x)/log(2) );i++) //一级蝶形运算
{
l=( 1<<i );
for(j=0;j<size_x;j+=(1<<(i+1))) //一组蝶形运算
{
for(k=0;k<l;k++)
{ //一个蝶形运算
mul(x[j+k+l],W[size_x*k/2/l],&up);
add(x[j+k],up,&up);
mul(x[j+k+l],W[size_x*k/2/l],&down);
sub(x[j+k],down,&down);
x[j+k]=up;
x[j+k+l]=down;
}
}
}
}
void PSD() //功率谱
{
unsigned int i;
for(i=0;i<size_x;i++)
{
x[i].real=(1/1024.0)*(x[i].real*x[i].real+x[i].img*x[i].img);
x[i].img=0;
}
}
void ZP() //总功率
{
int i;
for(i=0;i<size_x;i++)
{p+=x[i].real*x[i].real;}
p=(1/1024.0)*p;
} //转电压
void ZDY()
{
unsigned int i;
for(i=0;i<1024;i++)
{
x[i].real=(1/4096.0)*x[i].real*2.4;
}
}
void main()
{
WDT_Init();
SYSCLK_Init();
ADC_Init();
T3_Init();
while(h==1024)
{
TMR3CN&=0xfb;
ZDY();
ZP();
FFT();
PSD();
h=0;
TMR3CN|=0x04;
}
}
|