用单片机对模拟信号进行转换,转换后做FFT快速傅里叶变换。
程序如下:
- #include<c8051f020.h>
- #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;
- }
- }
复制代码 |