📄 2007720111224.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 + -