📄 hello.c
字号:
/***************************************************************************/
/* */
/* H E L L O . C */
/* */
/* FFT/IFFT程序,可以进行任意点数的FFT/IFFT变换 */
/* */
/* */
/***************************************************************************/
/***************************************************************************/
/*
说明:
ppr[n]--输入的实部
ppi[n]--数入的虚部
n,k--满足n=2^k
fr[n]--输出的实部
fi[n]--输出的虚部
l--0 FFT,1 IFFT
il--0 输出按实部/虚部;1 输出按模/幅角
*/
/***************************************************************************/
#include "math.h"
#define pp 3.1415926
#define nn 128 //FFT变换的点数
#define kk 7 //FFT变换的节数
// #define qamn 16
double tr[128],ti[128],or[128],oi[128]; //FFT
int qamin[16],qam2[16],qam1[16],qamfout[16];
double qamzout[512],qamlb1[512],qamlb2[512];
void kkfft(ppr,ppi,n,k,fr,fi,l,il)
int n,k,l,il;
double ppr[],ppi[],fr[],fi[];
{
double pr[nn],pi[nn]; //++++
int it,m,is,i,j,nv,l0;
double p,q,s,vr,vi,poddr,poddi;
for(it=0;it<n;it++)
{
pr[it]=ppr[it];
pi[it]=ppi[it];
}
for (it=0; it<=n-1; it++)
{
m=it; is=0;
for (i=0; i<=k-1; i++)
{
j=m/2; is=2*is+(m-2*j); m=j;
}
fr[it]=pr[is]; fi[it]=pi[is];
}
pr[0]=1.0; pi[0]=0.0;
p=6.283185306/(1.0*n);
pr[1]=cos(p); pi[1]=-sin(p);
if (l!=0) pi[1]=-pi[1];
for (i=2; i<=n-1; i++)
{
p=pr[i-1]*pr[1]; q=pi[i-1]*pi[1];
s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);
pr[i]=p-q; pi[i]=s-p-q;
}
for (it=0; it<=n-2; it=it+2)
{
vr=fr[it]; vi=fi[it];
fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1];
fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1];
}
m=n/2; nv=2;
for (l0=k-2; l0>=0; l0--)
{
m=m/2; nv=2*nv;
for (it=0; it<=(m-1)*nv; it=it+nv)
for (j=0; j<=(nv/2)-1; j++)
{
p=pr[m*j]*fr[it+j+nv/2];
q=pi[m*j]*fi[it+j+nv/2];
s=pr[m*j]+pi[m*j];
s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]);
poddr=p-q; poddi=s-p-q;
fr[it+j+nv/2]=fr[it+j]-poddr;
fi[it+j+nv/2]=fi[it+j]-poddi;
fr[it+j]=fr[it+j]+poddr;
fi[it+j]=fi[it+j]+poddi;
}
} //以上为傅立叶变换。
if (l!=0) //进行傅立叶反变换后进行加权系数处理。
for (i=0; i<=n-1; i++)
{
fr[i]=fr[i]/(1.0*n);
fi[i]=fi[i]/(1.0*n);
}
if (il!=0) //变换成幅度/相角。
{
for (i=0; i<=n-1; i++)
{
pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]);
if (fabs(fr[i])<0.000001*fabs(fi[i]))
{
if ((fi[i]*fr[i])>0) pi[i]=90.0;
else pi[i]=-90.0;
}
else
pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306;
}
for (i=0;i<n;i++)
{
fi[i]=pi[i];
fr[i]=pr[i];
}
}
return;
}
/**************************************************************************/
/*
16QAM/4-QAM调制程序
input[]为输入存储器,使用低4位进行数据存储,每个输入代表一个16进制数
output[]为解调后的输出,输出数据的个数为n×32个。
qamz1[]:2分频输出的一路数据。绘制星座图的一个数组
qamz2[]:2分频输出的另一路数据。绘制星座图的一个数组
n:输入16进制数据的个数,即4bit二进制数据的个数。
输出数据个数为n*32.
*/
/**************************************************************************/
void qamz(input,qamz1,qamz2,n,output)
int input[],qamz1[],qamz2[];
double output[];
{
int i,j;
int temp;
for(j=0;j<n;j++)
{
qamz1[j]=0;
qamz2[j]=0;
}
for(j=0;j<n;j++) //串/并转换
{
/* switch(input[j])
{
case 0:
qamz1[j]=0;
qamz2[j]=0;
break;
case 1:
qamz1[j]=1;
qamz2[j]=0;
break;
case 2:
qamz1[j]=0;
qamz2[j]=1;
break;
case 3:
qamz1[j]=1;
qamz2[j]=1;
break;
case 4:
qamz1[j]=2;
qamz2[j]=0;
break;
case 5:
qamz1[j]=3;
qamz2[j]=0;
break;
case 6:
qamz1[j]=2;
qamz2[j]=1;
break;
case 7:
qamz1[j]=3;
qamz2[j]=1;
break;
case 8:
qamz1[j]=0;
qamz2[j]=2;
break;
case 9:
qamz1[j]=1;
qamz2[j]=2;
break;
case 10:
qamz1[j]=0;
qamz2[j]=3;
break;
case 11:
qamz1[j]=1;
qamz2[j]=3;
break;
case 12:
qamz1[j]=2;
qamz2[j]=2;
break;
case 13:
qamz1[j]=3;
qamz2[j]=2;
break;
case 14:
qamz1[j]=2;
qamz2[j]=3;
break;
case 15:
qamz1[j]=3;
qamz2[j]=3;
break;
default:
break;
}*/
for(i=0;i<4;i++)
{
temp=input[j];
qamz1[j]=(temp&0x01)|qamz1[j];
temp=input[j];
qamz1[j]=((temp&(0x01<<2))>>1)|qamz1[j];
temp=input[j];
qamz2[j]=((temp&(0x01<<1))>>1)|qamz2[j];
temp=input[j];
qamz2[j]=((temp&(0x01<<3))>>2)|qamz2[j];
}
}
for(j=0;j<n;j++) //调制到通道
{
for(i=0;i<32;i++)
{
output[(32*j+i)]=qamz1[j]*sin(pp*i/8)+qamz2[j]*cos(pp*i/8);
}
}
}
/**************************************************************************/
/*
16QAM/4-QAM解调程序
input[]为解调输入信号!为256个数据的数组,并为浮点数据
output[]为解调输出信号!为16个数据的16进制数据.为整型数据
*/
/**************************************************************************/
void qamf(input,n,outputlb1,outputlb2,output)
double input[],outputlb1[],outputlb2[];
int output[],n;
{
int i,j,k,l=-1;
double temp1[128];//temp2[512];//,temp2[512],temp3[512]; //512应对应n,即在n=512时,定义数组为512。
k=n/128;
for(j=0;j<k;j++)
{
for(i=0;i<128;i++) //sin部分解调
{
temp1[i]=input[128*j+i]*sin(pp*i/8);
}
kkfft(temp1,ti,128,7,or,oi,0,0); //fft
for(i=12;i<116;i++) //滤波
{
oi[i]=0;
or[i]=0;
}
kkfft(or,oi,128,7,temp1,ti,1,0); //ifft
for(i=0;i<128;i++)
{
outputlb1[128*j+i]=temp1[i]*2; //sin 解调部分滤波输出
}
for(i=0;i<128;i++) //cos部分解调
{
temp1[i]=input[128*j+i]*cos(pp*i/8);
}
kkfft(temp1,ti,128,7,or,oi,0,0); //fft
for(i=12;i<116;i++) //滤波
{
oi[i]=0;
or[i]=0;
}
kkfft(or,oi,128,7,temp1,ti,1,0); //ifft
for(i=0;i<128;i++)
{
outputlb2[128*j+i]=temp1[i]*2; //cos 解调部分滤波输出
}
}
k=n/32; //32位数据代表一个码型
for(j=0;j<k;j++)
{
for(i=12;i<20;i++)
{
if((outputlb1[32*j+i]<0.25)&&(outputlb2[32*j+i]<0.25))
{
if(l<0)
l=0;
if(l>0)
l=55; //数据出错
}
else if((outputlb1[32*j+i]<0.25)&&(0.75<outputlb2[32*j+i])&&(outputlb2[32*j+i]<1.25))
{
if(l<0)
l=1;
if(l>0&&l!=1)
l=55; //数据出错
}
else if((outputlb1[32*j+i]<0.25)&&(1.75<outputlb2[32*j+i])&&(outputlb2[32*j+i]<2.25))
{
if(l<0)
l=2;
if(l>0&&l!=2)
l=55; //数据出错
}
else if((outputlb1[32*j+i]<0.25)&&(2.75<outputlb2[32*j+i]))
{
if(l<0)
l=3;
if(l>0&&l!=3)
l=55; //数据出错
}
else if((0.75<outputlb1[32*j+i])&&(outputlb1[32*j+i]<1.25)&&(outputlb2[32*j+i]<0.25))
{
if(l<0)
l=4;
if(l>0&&l!=4)
l=55; //数据出错
}
else if((0.75<outputlb1[32*j+i])&&(outputlb1[32*j+i]<1.25)&&(0.75<outputlb2[32*j+i])&&(outputlb2[32*j+i]<1.25))
{
if(l<0)
l=5;
if(l>0&&l!=5)
l=55; //数据出错
}
else if((0.75<outputlb1[32*j+i])&&(outputlb1[32*j+i]<1.25)&&(1.75<outputlb2[32*j+i])&&(outputlb2[32*j+i]<2.25))
{
if(l<0)
l=6;
if(l>0&&l!=6)
l=55; //数据出错
}
else if((0.75<outputlb1[32*j+i])&&(outputlb1[32*j+i]<1.25)&&(2.75<outputlb2[32*j+i]))
{
if(l<0)
l=7;
if(l>0&&l!=7)
l=55; //数据出错
}
else if((1.75<outputlb1[32*j+i])&&(outputlb1[32*j+i]<2.25)&&(outputlb2[32*j+i]<0.25))
{
if(l<0)
l=8;
if(l>0&&l!=8)
l=55; //数据出错
}
else if((1.75<outputlb1[32*j+i])&&(outputlb1[32*j+i]<2.25)&&(0.75<outputlb2[32*j+i])&&(outputlb2[32*j+i]<1.25))
{
if(l<0)
l=9;
if(l>0&&l!=9)
l=55; //数据出错
}
else if((1.75<outputlb1[32*j+i])&&(outputlb1[32*j+i]<2.25)&&(1.75<outputlb2[32*j+i])&&(outputlb2[32*j+i]<2.25))
{
if(l<0)
l=10;
if(l>0&&l!=10)
l=55; //数据出错
}
else if((1.75<outputlb1[32*j+i])&&(outputlb1[32*j+i]<2.25)&&(2.75<outputlb2[32*j+i]))
{
if(l<0)
l=11;
if(l>0&&l!=11)
l=55; //数据出错
}
else if((2.75<outputlb1[32*j+i])&&(outputlb2[32*j+i]<0.25))
{
if(l<0)
l=12;
if(l>0&&l!=12)
l=55; //数据出错
}
else if((2.75<outputlb1[32*j+i])&&(0.75<outputlb2[32*j+i])&&(outputlb2[32*j+i]<1.25))
{
if(l<0)
l=13;
if(l>0&&l!=13)
l=55; //数据出错
}
else if((2.75<outputlb1[32*j+i])&&(1.75<outputlb2[32*j+i])&&(outputlb2[32*j+i]<2.25))
{
if(l<0)
l=14;
if(l>0&&l!=14)
l=55; //数据出错
}
else if((2.75<outputlb1[32*j+i])&&(2.75<outputlb2[32*j+i])&&(outputlb2[32*j+i]<3.25))
{
if(l<0)
l=15;
if(l>0&&l!=15)
l=55; //数据出错
}
else
l=55;
}
if(l==0)
output[j]=0;
else if(l==1)
output[j]=2;
else if(l==2)
output[j]=8;
else if(l==3)
output[j]=10;
else if(l==4)
output[j]=1;
else if(l==5)
output[j]=3;
else if(l==6)
output[j]=9;
else if(l==7)
output[j]=11;
else if(l==8)
output[j]=4;
else if(l==9)
output[j]=6;
else if(l==10)
output[j]=12;
else if(l==11)
output[j]=14;
else if(l==12)
output[j]=5;
else if(l==13)
output[j]=7;
else if(l==14)
output[j]=13;
else if(l==15)
output[j]=15;
else
output[j]=-1;
l=-1;
}
}
/**************************************************************************/
/*
*/
/**************************************************************************/
void main()
{
int i,j;
for(i=0;i<16;i++)
{
qamin[i]=i;
}
//以下为发送程序
qamz(qamin,qam1,qam2,16,qamzout);
for(j=0;j<4;j++)
{
for(i=0;i<128;i++)
{
tr[i]=qamzout[4*j+i];
ti[i]=0;
}
kkfft(tr,ti,128,7,or,oi,0,0);
//将or,oi发送到通道中 --以下为接收程序
kkfft(or,oi,128,7,tr,ti,1,0);
for(i=0;i<128;i++)
{
qamzout[4*j+i]=tr[i];
}
}
qamf(qamzout,512,qamlb1,qamlb2,qamfout);
/* for(i=0;i<128;i++) //产生进行傅立叶变换的信号,128点数据
{
tr[i]=1+cos(pp*i/4);//-cos(pp*i/8);
ti[i]=0;
}
kkfft(tr,ti,128,7,or,oi,0,0); */ //FFT
// kkfft(or,oi,128,7,tr,ti,1,0); //IFFT
// puts("hello world!hahah\n");
while(1)
{
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -