C++实现BPSK信号的调制解调过程课题设计报告文档格式.docx
- 文档编号:20654144
- 上传时间:2023-01-24
- 格式:DOCX
- 页数:43
- 大小:520.39KB
C++实现BPSK信号的调制解调过程课题设计报告文档格式.docx
《C++实现BPSK信号的调制解调过程课题设计报告文档格式.docx》由会员分享,可在线阅读,更多相关《C++实现BPSK信号的调制解调过程课题设计报告文档格式.docx(43页珍藏版)》请在冰豆网上搜索。
图2-5BPSK解调原理框图
如图2-5给出了一种BPSK信号相干解调原理框图,图中经过带通滤波的信号在相乘器与本地载波相乘,在相干解调中,如何得到与接收的BPSK信号同频同相的相干载波是关键,然后用低通滤波器去除高频分量,再进行积分采样判决,判决器是按极性进行判决,得到最终的二进制信息。
假设相干载波的基准相位于BPSK信号的调制载波的基准相位一致。
但是,由于在BPSK信号的载波恢复过程中存在
º
的相位迷糊(phaseambiguity),即恢复的本地载波与所需的相干载波可能同相,也可能反相,这种相位关系的不确定性将会造成解调出数字基带信号与发送的数字基带信号正好相反,即‘1’变为‘0’,‘0’变为‘1’,判决器输出数字信号全部出错。
这种现象称为BPSK方式的‘倒
’现象。
载波同步器从BPSK信号中提取的相干载波可能与接收信号的载波同相,也可能反相,称此为相干载波的相位模糊现象。
如果收到的信号与载波信号同相,则相乘为正值,积分采样后必为一大于0的值,即可判决为“1”。
如果收到的信号与参考信号相反,则相乘之后必为负值,积分采样后判决为“0”,因此解调完成。
具体波形如图2-6所示。
图2-6BPSK解调信号示意图
基本架构设计
BPSK调制解调系统的模型如图3-1所示,调制部分包括信息源、星座映射、发送滤波器和调制器,接收部分包括解调器、接收滤波器和抽样判决器,信道干扰为加性高斯噪声。
图3-1BPSK信号调制解调系统框图
整个发送与接收过程仿真了实际中的通信过程,单极性二进制信源经过星座映射变换为一串双极性二进制字符,再经过发送滤波器进行脉冲成形,生成原始的数字基带信号,为了发送信息,通过BPSK调制器变成数字带通信号发射,发射信号进入模拟的加性高斯白噪声信道,被接收机所接收,BPSK信号解调采用的是相干解调,用同步恢复出的载波对接收机收到的信号进行相乘,相干解调恢复出信号经过低通滤波器滤除高频分量,然后依次经过接收滤波器和抽样判决器,恢复最原始的二进制序列,自此完成对数字信号的BPSK调制解调全过程。
模块划分
Bpsk调制模块
Bpsk解调模块
输入输出模块
模块功能设计
Bpsk调制模块包括:
基带数据产生模块
单双极性变换模块
FFT模块
功率信号幅值单位转换模块
加载波模块
Bpsk解调模块包括:
产生高斯白噪声模块
去载波模块
低通滤波器模块
判决模块
误码率计算模块
输入输出模块包括:
数据输入模块
数据读取模块
数据输出模块
绘图模块OnPaint()
图形界面模块
二、详细设计
(一)资源项目
程序文件头文件
(二)Bpsk调制模块
★基带数据产生模块
int*CTools:
:
BaseDataPut(longlength)
{
int*nBaseDataBit;
nBaseDataBit=(int*)malloc(length*sizeof(int));
srand((unsigned)time(NULL));
for(longi=0;
i<
length;
i++)
*(nBaseDataBit+i)=rand()%2;
returnnBaseDataBit;
}
★单双极性变换模块
int*pnget=NULL;
//单双变换后数据
pnget=(int*)malloc(m_nNumOfBase*sizeof(int));
for(i=0;
i<
m_nNumOfBase;
pnget[i]=1-m_pBaseData[i]*2;
}//单双极性变换
★FFT模块
float*CTools:
fft(float*y,longn,long*len)
{//傅立叶变换;
//len:
返回补0以后数据长度的一半;
//函数输出:
fft变换后的数据,长度为len;
//若失败,则返回一个空指针(NULL)
longi,j,k,m,i1,i2,i3,i4,n1,n2,n4;
floata,e,cc,ss,xt,t1,t2;
float*x;
longtemp_n;
//////////////////////////////////
//自动补零
temp_n=1;
while(temp_n<
n)temp_n*=2;
x=(float*)malloc(temp_n*sizeof(float));
if(!
x)returnNULL;
for(i=0;
i<
n;
i++)
*(x+i)=*(y+i);
if(temp_n>
n)
{
for(i=n;
temp_n;
i++)*(x+i)=0;
}
////////////////////////////
//开始做fft运算
for(j=1,i=1;
32;
i++)
m=i;
j=2*j;
if(j==temp_n)
break;
n1=temp_n-1;
for(j=0,i=0;
n1;
if(i<
j)
{
xt=x[j];
x[j]=x[i];
x[i]=xt;
}
k=temp_n/2;
while(k<
(j+1))
j=j-k;
k=k/2;
j=j+k;
for(i=0;
i+=2)
xt=x[i];
x[i]=xt+x[i+1];
x[i+1]=xt-x[i+1];
n2=1;
for(k=2;
k<
=m;
k++)
n4=n2;
n2=2*n4;
n1=2*n2;
e=float(6.283185307179596/n1);
for(i=0;
i+=n1)
xt=x[i];
x[i]=xt+x[i+n2];
x[i+n2]=xt-x[i+n2];
x[i+n2+n4]=-x[i+n2+n4];
a=e;
for(j=1;
j<
=(n4-1);
j++)
{
i1=i+j;
i2=i-j+n2;
i3=i+j+n2;
i4=i-j+n1;
cc=float(cos(a));
ss=float(sin(a));
a=a+e;
t1=cc*x[i3]+ss*x[i4];
t2=ss*x[i3]-cc*x[i4];
x[i4]=x[i2]-t2;
x[i3]=-x[i2]-t2;
x[i2]=x[i1]-t1;
x[i1]=x[i1]+t1;
}
*x=float(fabs(*x));
*(x+temp_n/2)=float(fabs(*(x+temp_n/2)));
for(i=1;
temp_n/2;
*(x+i)=float(sqrt((*(x+i))*(*(x+i))+
(*(x+temp_n-i))*(*(x+temp_n-i))));
x=(float*)realloc(x,(temp_n/2)*sizeof(float));
*len=temp_n/2;
if(!
x)
free(x);
returnNULL;
else
returnx;
★功率信号幅值单位转换模块
doubleCTools:
TransformUnit(doubledRecPower)
doubledPower;
dPower=pow(10,(dRecPower-30)/10);
returndPower;
★加载波模块
float*pfModData=NULL;
//调制数据
pfModData=(float*)malloc(m_nNumOfScan*sizeof(float));
m_nNumOfScan;
j=long(i*m_nNumOfBase/m_nNumOfScan);
*(pfModData+i)=*(pnget+j)*dPa*cos(2*PI*m_dSimRf*i/m_dSampleFreq);
//A*cos(wc*t)=A*cos(2*Pi*f*t)
(二)Bpsk解调模块
★产生高斯白噪声模块
voidCTools:
GaussionNoise(float*noise,doublepSig,doublefSNR,longnum_of_scan)
//noise:
产生的噪声数据;
//stddeviation:
噪声的标准差;
//fSNR:
信噪比;
//pSig:
信号功率;
doublepNoise,stddeviation;
inti,j,numofvar;
doublegauvar,uDx,uEx,ranvar[100],sum,tempE,tempD;
doublemean;
//初始化变量;
mean=0;
uEx=1.0/2.0;
uDx=1.0/12.0;
numofvar=20;
tempE=numofvar*uEx;
tempD=sqrt(numofvar*uDx);
pNoise=pSig/pow(10,fSNR/10);
stddeviation=sqrt(pNoise);
//计算噪声标准差
for(j=0;
num_of_scan;
sum=0;
numofvar;
//产生均匀分布的数据;
ranvar[i]=rand()/(1.0*RAND_MAX);
sum=sum+ranvar[i];
//生成高斯分布的数据;
gauvar=(sum-tempE)/tempD;
*(noise+j)=float(gauvar*stddeviation+mean);
★去载波模块
float*pfDemodData=NULL;
//解调数据
pfDemodData=(float*)malloc(m_nNumOfScan*sizeof(float));
for(i=0;
m_nNumOfScan;
*(pfDemodData+i)=*(pfAdd_Put+i)*cos(2*PI*m_dSimRf*i/m_dSampleFreq);
★低通滤波器模块
lowPassFilter(float*inData,doublefln,longlength)
{
longlengthh,n,i;
float*h,*outData;
//解决卷积分块丢失部分数据问题
longlength_reivse=(int)ceil((float)length/20000)*20000;
float*inData_revise=(float*)malloc(length_reivse*sizeof(float));
*(inData_revise+i)=*(inData+i);
for(;
length_reivse;
*(inData_revise+i)=0;
lengthh=12768;
n=32768;
h=firwin(lengthh,1,fln,0,1);
h=(float*)realloc(h,n*sizeof(float));
outData=(float*)malloc(length_reivse*sizeof(float));
for(i=lengthh;
h[i]=0.0;
convold(h,lengthh,inData_revise,length_reivse,outData,n);
free(h);
inData[i]=outData[i];
free(inData_revise);
free(outData);
firwin(intn,intband,doublefln,doublefhn,intwn)
//n滤波器的阶数
//band滤波器类型,1--低通,2--高通,3--带通,4--带阻
//fln,对于低通和高通滤波器:
通带边界频率,对于带通和带阻
//fln:
通带下边界频率,fhn:
通带上边界频率
//wn窗函数类型:
1--海明窗,2--汉宁窗,3--布拉克曼窗
//h一个指针,指向返回的h(n)
inti,n2,mid;
doubles,wc1,wc2,delay;
float*h;
h=(float*)malloc((n+1)*sizeof(float));
h)returnNULL;
if((n%2)==0)
n2=n/2-1;
mid=1;
else
n2=n/2;
mid=0;
delay=n/2.0;
wc1=2.0*PI*fln;
if(band>
=3)
wc2=2.0*PI*fhn;
switch(band)
{
case1:
{
for(i=0;
=n2;
{
s=i-delay;
*(h+i)=float((sin(wc1*s)/(PI*s))*window(wn,n+1,i));
*(h+n-i)=*(h+i);
if(mid==1)
*(h+n/2)=float(wc1/PI);
case2:
i<
=n2;
*(h+i)=float((sin(PI*s)-sin(wc1*s))/(PI*s));
*(h+i)=*(h+i)*window(wn,n+1,i);
*(h+n/2)=float(1.0-wc1/PI);
case3:
*(h+i)=float((sin(wc2*s)-sin(wc1*s))/(PI*s));
*(h+n/2)=float((wc2-wc1)/PI);
case4:
{s=i-delay;
*(h+i)=float((sin(wc1*s)+sin(PI*s)-sin(wc2*s))/(PI*s));
*(h+i)=*(h+i)*window(wn,n+1,i);
*(h+n-i)=*(h+i);
*(h+n/2)=float((wc1+PI-wc2)/PI);
returnh;
★判决模块
//计算判决门限
floatxmax,xmin,xthreshold;
intmaxn;
xmax=*pfDemodData;
//初始最大最小值
xmin=*pfDemodData;
i=0;
while(i<
m_nNumOfScan)
if(*(pfDemodData+i)>
xmax)
xmax=*(pfDemodData+i);
if(*(pfDemodData+i)<
xmin)
xmin=*(pfDemodData+i);
i++;
xthreshold=(xmax+xmin)/2;
//判决门限
//抽样判决
float*pfDeput=NULL;
//判决数据
pfDeput=(float*)malloc(m_nNumOfBase*sizeof(float));
m_pDemodData=(int*)malloc(m_nNumOfBase*sizeof(int));
maxn=(m_nNumOfScan/m_nNumOfBase/2-1);
//最大判决点
m_nNumOfBase;
*(pfDeput+i)=*(pfDemodData+m_nNumOfScan/m_nNumOfBase*i+maxn);
if((*(pfDeput+i))>
=xthreshold)
*(pfDeput+i)=0;
else
*(pfDeput+i)=1;
★误码率计算模块
CodeErrorRate(int*base_data,int*demod_data,longnum_of_base)
//两个文件的误比特率
longi,num_of_err=0;
if(num_of_base>
2380)
2380;
i++)//误码率计算
if(*(base_data+i)!
=*(demod_data+i))
num_of_err++;
}
num_of_base;
returnnum_of_err/(1.0*num_of_base);
(三)输入输出模块
◆数据输入模块
voidCCommSys0713Dlg:
OnBnClickedStart()
//TODO:
在此添加控件通知处理程序代码
//调制解调
CBPSKbpsk;
inti;
CStrings1,s2,s3,s4;
UpdateData(true);
s1=m_value11.GetString();
s2=m_value12.GetString();
s3=m_value13.GetString();
s4=m_value14.GetString();
inta1=_tstoi(s1);
inta2=_tstoi(s2);
inta3=_tstoi(s3);
inta4=_tstoi(s4);
i=bpsk.BPSK_ModDemod(a1,a2,a3,a4);
MessageBox("
仿真完成"
"
温馨提示"
MB_ICONASTERISK);
//OnOK();
◆数据读取模块
float*CTools:
getDataf(CStringsFilena
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 实现 BPSK 信号 调制 解调 过程 课题 设计 报告