📄 decode.cpp
字号:
#include<iostream>
#include<cmath>
using namespace std;
//****************************************************************************
// 一个复数类(实现复数的加/减/乘/除/求模/与实数相乘/求共轭/求负共轭/赋值/显示)
//****************************************************************************
class complex
{
public:
complex(float r=1,float i=1):x(r),y(i){}//构造函数,实现初始化
complex operator+(complex &c2);//声明重载运算符的"+"函数
complex operator-(complex &c2);//声明重载运算符的"-"函数
complex operator*(complex &c2);//声明重载运算符的"*"函数(两个复数的乘法)
complex operator/(complex &c2);//声明重载运算符的"/"函数
complex operator*(float e);//声明重载运算符的"*"函数(实数与复数的乘法)
float model();//求模
complex conjugate();//求共轭
complex negative();//求负共轭
void display();//显示
void fz(float ,float);//复数对象的赋值
private:
float x;
float y;
};
complex complex:: operator+(complex &c2)
{ complex c;
c.x=x+c2.x;
c.y=y+c2.y;
return c;
}
complex complex::operator-(complex &c2)
{ complex c;
c.x=x-c2.x;
c.y=y-c2.y;
return c;
}
complex complex::operator*(complex &c2)
{ complex c;
c.x=x*c2.x-y*c2.y;
c.y=x*c2.y+c2.x*y;
return c;
}
complex complex::operator/(complex &c2)
{ complex c;
c.x=(x*c2.x+y*c2.y)/(c2.x*c2.x+c2.y*c2.y);
c.y=(c2.x*y-x*c2.y)/(c2.x*c2.x+c2.y*c2.y);
return c;
}
complex complex::operator*(float e)
{
return complex(e*x,e*y);
}
void complex::fz (float r ,float i)
{
x=r;
y=i;
}
float complex::model()
{ return((float) sqrt(x*x+y*y));
}
complex complex::conjugate()
{
return complex(x,-y);
}
complex complex::negative()
{
return complex(-x,y);
}
void complex::display()
{
cout<<"("<<x<<","<<y<<"i)"<<endl;
}
//两个全局变量
int A[45];//发送端产生数据流
int b[45];//接收端产生数据流
//***********************************************
// 15位M序列发生器函数
//***********************************************
void msequence()
{ int i,j;
int a[5]={1,0,1,0,1};
for(j=0;j<45;j++)
{
int temp=(a[0]+a[3])%2;
if(j%15==0) cout<<endl;
A[j]=a[4];
for(i=4;i>=0;i--)
a[i]=a[i-1];
a[0]=temp;
}
}
//cout<<"********************************************"<<endl;
//cout<<" 发送端 "<<endl;
//cout<<"********************************************"<<endl;
void main()//主程序
{
int a[45];
int i,j,d,g;
float error=0,ber;
float Z=sqrt(2)/2;//8PSK星座图中某些点的坐标值
complex cm[8];
complex t[45];//复数对象数组,便于存放每一时刻调制后发送的信号值
complex c1,c2,c3,c4;
void decode(complex &c1,complex &c2);//解调函数的声明
msequence();//调用m序列函数发生器产生一个15位的m序列
for(i=0;i<42;i++) cout<<A[i];//先将产生的序列输出
cout<<endl;
for(i=0;i<45;i++) a[i]=A[i];
for(j=0;j<7;j++)//本程序中共有45个比特的数据,我们每次需要顺序取出6个比特来发射,故循环七次
{
for(i=0;i<6;i++)//顺序取出6个比特来发射
{cout<<A[i];}//输出这6个比特便于检测
cout<<endl;
d=A[2]*4+A[1]*2+A[0]*1;//取每3个比特来进行8PSK调制,先将二进制转化为十进制,该步是为了便于写后面的选择语句
g=A[5]*4+A[4]*2+A[3]*1;//d为前3个输出的比特表示的十进制数,对应我们的X1;g为后3个输出的比特表示的十进制数,对应我们的X2;
for(i=0;i<42;i++) //每取6个比特后就将数组前移,便于后面取数
A[i]=A[i+6];
cout<<"t时刻第一根天线上发送的是:";
//8PSK中的映射关系,采用GRAY编码,这种编码可以使噪声引起的误差在3个比特的码元中仅出现一个比特的错
switch(d)//X1的8PSK映射;
{
case(0):c1.fz(1,0); c1.display();break;
case(1):c1.fz(Z,Z); c1.display();break;
case(3):c1.fz(0,1); c1.display();break;
case(2):c1.fz(-Z,Z); c1.display();break;
case(6):c1.fz(-1,0); c1.display();break;
case(7):c1.fz(-Z,-Z);c1.display();break;
case(5):c1.fz(0,-1); c1.display();break;
case(4):c1.fz(Z,-Z); c1.display();break;
}
cout<<"t时刻第二根天线上发送的是:";
switch(g)//X2的8PSK映射;
{
case(0):c2.fz(1,0); c2.display();break;
case(1):c2.fz(Z,Z); c2.display();break;
case(3):c2.fz(0,1); c2.display();break;
case(2):c2.fz(-Z,Z); c2.display();break;
case(6):c2.fz(-1,0); c2.display();break;
case(7):c2.fz(-Z,-Z);c2.display();break;
case(5):c2.fz(0,-1); c2.display();break;
case(4):c2.fz(Z,-Z); c2.display();break;
}
t[2*j]=c1;//将调制后的信号送到接收端(注:仅因为调试程序,在最终程序中,调制信息的传送由MIMO来实现)
t[2*j+1]=c2;
cout<<"t+T时刻第一根天线上发送的是:";
c3=c2.negative() ;//-X2*
c3.display();
cout<<"t+T时刻第二根天线上发送的是:";
c4=c1.conjugate() ;//X1*
c4.display();
cout<<endl;
}
//cout<<"********************************************"<<endl;
//cout<<" 接收端 "<<endl;
//cout<<"********************************************"<<endl;
for(j=0;j<7;j++)//分为7组,每组两个调制符号,即x1和x2
{
cout<<endl;
cout<<"调制后数据:"<<endl;
t[2*j].display();
t[2*j+1].display();
decode(t[2*j],t[2*j+1]);//每次解调两个符号,共解调7次
}
cout<<"发送数据:"<<endl;//输出发送的数据
for(i=0;i<42;i++)
cout<<a[i];
cout<<endl;
cout<<"接收数据:"<<endl;//输出接收端经过线性处理和解调后的数据
for(j=0;j<42;j++)
cout<<b[j];
cout<<endl;
for(i=0;i<42;i++)//误码率计算
{if(a[i]!=b[i])
error++;}
cout<<"错误比特数"<<endl;
cout<<error<<endl;
ber=error/42;
cout<<"误码率:"<<endl;
cout<<ber<<endl;
}
//**********************************************************
// 接收端线性处理和解调
//**********************************************************
void decode(complex &c1,complex &c2) //信道加扰 译码函数
{
static int u;
int B[45];
float min1,min2;
float Z=sqrt(2)/2;
complex cm[8];
complex s1,s2,h1(4,1),h2(4,2);//s为判决变量,h为信道衰落系数
complex r1,r2,n1(0,1),n2(0,1);//r为接收信号,n为信道复噪声
r1=h1*c1+h1*c2+n1;//接收信号的表达式(仅为调试时使用,在最终程序中,接收信号从MIMO中提取)
r2=h1*c2.negative()+h1*c1.conjugate()+n2;
int k=0,p=0;
/*****************************************************
s1=r1*h1.conjugate()+r2.conjugate()*h2;线性处理
s2=r1*h2.conjugate()-r2.conjugate()*h1;
*******************************************************/
s1=c1*(h1.model()*h1.model()+h2.model()*h2.model())+h1.conjugate()*n1+h2*n2.conjugate();
s2=c2*(h1.model()*h1.model()+h2.model()*h2.model())+h1*n2.negative()+h2.conjugate()*n1;
cm[0].fz(1,0);//解调(将星座点映射到十进制数据)
cm[1].fz(Z,Z);
cm[3].fz(0,1);
cm[2].fz(-Z,Z);
cm[6].fz(-1,0);
cm[7].fz(-Z,-Z);
cm[5].fz(0,-1);
cm[4].fz(Z,-Z);
min1=(cm[0]-s1).model()*(cm[0]-s1).model();//比较欧式距离的暂定最小量
min2=(cm[0]-s2).model()*(cm[0]-s2).model();
for(int i=0;i<8;i++)//将原来调制的所有变量一起拿来比较,找出最小的平方欧式距离
{
if((cm[i]-s1).model()*(cm[i]-s1).model()<min1)
{min1=(cm[i]-s1).model()*(cm[i]-s1).model();
k=i;//保存判断接收信号判决变量s1欧式距离的最小值时的数组下标
}
if((cm[i]-s2).model()*(cm[i]-s2).model()<min2)
{min2=(cm[i]-s2).model()*(cm[i]-s2).model();
p=i;//保存判断接收信号判决变量s2欧式距离的最小值时的数组下标
}
}
cout<<"解调后数据:"<<endl;
cout<<u<<" 时刻X1的译码输出为: ";
cm[k].display();
switch(k)//将十进制数据映射成二进制数据
{
case(0):B[2]=0;B[1]=0;B[0]=0;break;
case(1):B[2]=0;B[1]=0;B[0]=1;break;
case(3):B[2]=0;B[1]=1;B[0]=1;break;
case(2):B[2]=0;B[1]=1;B[0]=0;break;
case(6):B[2]=1;B[1]=1;B[0]=0;break;
case(7):B[2]=1;B[1]=1;B[0]=1;break;
case(5):B[2]=1;B[1]=0;B[0]=1;break;
case(4):B[2]=1;B[1]=0;B[0]=0;break;
}
cout<<u<<" 时刻X2的译码输出为: ";
cm[p].display();
switch(p)
{
case(0):B[5]=0;B[4]=0;B[3]=0;break;
case(1):B[5]=0;B[4]=0;B[3]=1;break;
case(3):B[5]=0;B[4]=1;B[3]=1;break;
case(2):B[5]=0;B[4]=1;B[3]=0;break;
case(6):B[5]=1;B[4]=1;B[3]=0;break;
case(7):B[5]=1;B[4]=1;B[3]=1;break;
case(5):B[5]=1;B[4]=0;B[3]=1;break;
case(4):B[5]=1;B[4]=0;B[3]=0;break;
}
u++;
cout<<"接收信息为"<<endl;
for(i=0;i<6;i++)
{cout<<B[i];}
cout<<endl;
static int m=0;//将数据依次存入b[45]中
b[m]=B[0];
b[m+1]=B[1];
b[m+2]=B[2];
b[m+3]=B[3];
b[m+4]=B[4];
b[m+5]=B[5];
m=m+6;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -