#include<stc12c5a60s2.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
uint xdata sample[32]={0};
float xdata real[32]={0};
float xdata imag[32]={0};
float xdata cosp[]={1,0.981,0.924,0.831,0.707,0.556,0.383,0.195,
0,-0.195,-0.383,-0.556,-0.707,-0.831,-0.924,-0.981};
float xdata sinp[]={0,0.195,0.383,0.556,0.707,0.831,0.924,0.981,
1,0.981,0.924,0.831,0.707,0.556,0.383,0.195};
uint ref[]={0,140,280,420,560,700,840,980,1120};
uchar cod[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};
uchar quan[16]={0};
uchar s;
void reverse(uchar n)//倒序
{
uchar i,j,k,l;
float temp;
for(i=0;i<n;i++)
{
real[i]=sample[i];
imag[i]=0;
}
l=n/2;
j=l;//倒序起始序号
for(i=1;i<l;i++)
{
if(i<j)
{
temp=real[i];
real[i]=real[j];
real[j]=temp;
}
k=l;
while((j>k)||(j==k))
{
j=j-k;
k=k/2;
}
j=j+k;//下一个倒序序号
}
}
void fft(uchar m,uchar n)
{
uchar l,b,j,p,k;
float realtemp,imagtemp,temp;
for(l=1;l<=m;l++)
{
b=1<<(l-1);
for(j=0;j<b;j++)
{
p=j*(1<<(m-l));//系数
for(k=j;k<n;k=k+2*b)
{
realtemp=real[k];
imagtemp=imag[k];
temp=real[k+b];
real[k]=real[k]+real[k+b]*cosp[p]+imag[k+b]*sinp[p];
imag[k]=imag[k]+imag[k+b]*cosp[p]-real[k+b]*sinp[p];
real[k+b]=realtemp-real[k+b]*cosp[p]-imag[k+b]*sinp[p];
imag[k+b]=imagtemp-imag[k+b]*cosp[p]+temp*sinp[p];
}
}
}
}
void fftabs(uchar n)//取模
{
uchar i;
for(i=1;i<n;i++)
real[i]=sqrt(real[i]*real[i]+imag[i]*imag[i]);
}
void quantization(uchar n)//量化
{
uchar i,j;
for(i=1;i<n;i++)
{
for(j=0;j<9;j++)
{
if((real[i]-ref[j])>0)
quan[i]=j;
}
}
}
void delay()
{
uchar x,y;
for(x=20;x>0;x--)
for(y=255;y>0;y--);
}
void display()
{
uchar i;
for(i=1;i<8;i++)
{
P1=~(1<<i);
P0=cod[quan[i]];
delay();
}
P1=0XFF;//关闭左面点阵
for(i=0;i<8;i++)
{
P3=~(1<<i);
P2=cod[quan[i+8]];
delay();
}
P3=0XFF;//关闭右面点阵
}
void main()
{
P1ASF=0x01;
ADC_CONTR=0xe0;
TMOD=0X02;
TH0=0XBD;
TL0=0XBD;
EA=1;
ET0=1;
TR0=1;
EADC=1;
while(1)
{
display();
if(TR0==0)//AD采集完32个数
{
reverse(32);
fft(5,32);
fftabs(16);
quantization(16);
TR0=1;
}
}
}
void timer0() interrupt 1
{
ADC_CONTR=0xe8;
}
void adc() interrupt 5
{
ADC_CONTR=0xe0;//清AD中断标志位
sample[s++]=(ADC_RES<<2)|ADC_RESL;
if(s==32)
{
s=0;
TR0=0;
}
}
评论2