正交相移键控(Quadrature Phase Shift Keyin,QPSK)是一种数字调制方式。

相移键控(PSK),是一种用载波相位表示输入信号信息的调制技术。是一种相位调制。

调制方式基本的有三种:幅度调制,频率调制,相位调制。

VC6新建一个单文档工程;

// qpskView.cpp : implementation of the CQpskView class
//#include "stdafx.h"
#include "qpsk.h"#include "qpskDoc.h"
#include "qpskView.h"
#include <math.h>#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif//#define source_length 1000000
#define source_length 128
#define symbol_length source_length/2
#define SNR_start 1
#define SNR_end 10
#define SNR_step 1
#define PI 3.1415926
#define Coderate 1typedef struct {double Rpart;double Ipart;
}complex;int source[source_length];//message(),modulate(),error()
int change[source_length];//modulate()
int resource[source_length];    //demodulate(),error()
complex modulatesym[symbol_length];   //demodulate(),channel(),moudulate()
int snr;//channel(),error()
int errorbit, errorsym;//error()
double BER,SER;//error()void message();
void modulate(int source[source_length]);
void channel(complex modulatesym[symbol_length],int snr);
void demodulate();
void error();/
// CQpskViewIMPLEMENT_DYNCREATE(CQpskView, CView)BEGIN_MESSAGE_MAP(CQpskView, CView)//{{AFX_MSG_MAP(CQpskView)// NOTE - the ClassWizard will add and remove mapping macros here.//    DO NOT EDIT what you see in these blocks of generated code!//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()/
// CQpskView construction/destructionCQpskView::CQpskView()
{// TODO: add construction code here}CQpskView::~CQpskView()
{
}BOOL CQpskView::PreCreateWindow(CREATESTRUCT& cs)
{// TODO: Modify the Window class or styles here by modifying//  the CREATESTRUCT csreturn CView::PreCreateWindow(cs);
}/
// CQpskView drawingvoid CQpskView::OnDraw(CDC* pDC)
{CQpskDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereint row=0, col=0;CString str1;for(snr=SNR_start;snr<=SNR_end;snr+=SNR_step){message();modulate(source);for(int k=0;k<source_length;k++){ str1.Format("%d",source[k]);pDC->TextOut(20+10*((k+1)%32), 20+row*32, str1);if( (k+1)%32==0){row=row+1;}}channel(modulatesym,snr);demodulate();error();}
}/
// CQpskView printingBOOL CQpskView::OnPreparePrinting(CPrintInfo* pInfo)
{// default preparationreturn DoPreparePrinting(pInfo);
}void CQpskView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{// TODO: add extra initialization before printing
}void CQpskView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{// TODO: add cleanup after printing
}/
// CQpskView diagnostics#ifdef _DEBUG
void CQpskView::AssertValid() const
{CView::AssertValid();
}void CQpskView::Dump(CDumpContext& dc) const
{CView::Dump(dc);
}CQpskDoc* CQpskView::GetDocument() // non-debug version is inline
{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CQpskDoc)));return (CQpskDoc*)m_pDocument;
}
#endif //_DEBUG/
// CQpskView message handlers//随机信号产生
void message()
{int i;//以当前时间作为时间种子srand((unsigned)time(NULL));//产生0,1随机信号for(i=0;i<source_length;i++){ source[i]=rand()%2;//cout<<source[i];}//cout<<endl;
}//调制
void modulate(int source[source_length])
{int i,j;//0->-1,1->1for(i=0;i<source_length;i++){   change[i]=1-2*source[i];}     for(j=0;j<symbol_length;j++){   modulatesym[j].Rpart=change[2*j];//cout<<change[2*j];modulatesym[j].Ipart=change[2*j+1];//cout<<change[2*j+1];}// cout<<endl;
}//调制信号通过信道
void channel(complex modulatesym[],int snr)
{long int j;double r1,r2;double amp,phase;double sn,SNR,noise[2];SNR=snr+10*log10((double)Coderate);sn=pow(10.0,SNR/10.0);for(j=0;j<symbol_length;j++){r1=(double)rand()/RAND_MAX;r2=(double)rand()/RAND_MAX;if(r1<=1.0e-8)  r1=1.0e-8; //防止出现log0的操作phase=2.0*PI*r2;amp=sqrt(-log(r1)/sn);noise[0]=amp*cos(phase);noise[1]=amp*sin(phase);modulatesym[j].Rpart=modulatesym[j].Rpart+noise[0];//cout<<modulatesym[j].Rpart;modulatesym[j].Ipart=modulatesym[j].Ipart+noise[1];//cout<<modulatesym[j].Ipart;}//cout<<endl;
}//解调
void demodulate()
{    for(int j=0;j<symbol_length;j++){if (modulatesym[j].Rpart>0)resource[2*j]=0;else //if(modulatesym[j].Rpart<=0)resource[2*j]=1;}for(int i=0;i<symbol_length;i++){if (modulatesym[i].Ipart>0)resource[2*i+1]=0;else //if(modulatesym[j].Ipart<=0)resource[2*i+1]=1;}
}void error()
{long int i,j;errorbit=0;errorsym=0;for(i=0;i<source_length;i++){ if(resource[i]!=source[i])errorbit++;}for(j=0;j<=symbol_length;j++){if(resource[2*j]!=source[2*j]||resource[2*j+1]!=source[2*j+1])errorsym++;}BER=(double)errorbit/source_length;SER=(double)errorsym/symbol_length;//cout<<"snr="<<snr<<endl;//cout<<"source_length="<<source_length<<endl;//cout<<"symbol_length="<<symbol_length<<endl;//cout<<"errorbit="<<errorbit<<endl;//cout<<"errorsym="<<errorsym<<endl;//cout<<"BER="<<BER<<endl;//cout<<"SER="<<SER<<endl;
}

原来定义的源信号长度,#define source_length 1000000 ,演示改为128;

大体看一下函数功能;

源信号是用message()来生成的随机信号;这是要传输的用户信息;

modulate()实现调制;把用户信息转变到载波的相位变化上;得到的调制信号modulatesym是复数形式,需要定义一个复数结构体;

有几个变量是模拟噪声的;

channel()模拟调制信号通过信道;大致是把噪声叠加到调制信号上;

demodulate()实现解调,结果放入resource[];

error()函数大体是输出一些噪声和噪声引起的错误相关的信息;

先输出一下源信号和解调后的信号;调制信号是复数形式,有时间再输出;

分2次输出,写到一次里会出问题;

另一次的OnDraw()函数如下;

void CQpskView::OnDraw(CDC* pDC)
{CQpskDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereint row=0, col=0;CString str1;for(snr=SNR_start;snr<=SNR_end;snr+=SNR_step){message();modulate(source);channel(modulatesym,snr);demodulate();for(int i=0;i<source_length;i++){ str1.Format("%d",resource[i]);pDC->TextOut(800+10*((i+1)%32), 20+row*32, str1);if( (i+1)%32==0){row=row+1;}}error();}
}

输出的结果如下;

原程序参阅 QPSK调制的C实现_bcbobo21cn的专栏-CSDN博客_qpsk调制

VC++实现QPSK调制相关推荐

  1. 【定时同步系列4】QPSK调制+OM定时(FFT实现及频域补偿)+信号分段处理+误码率曲线之MATLAB仿真(复信号模型)

    关注公号[逆向通信猿]更精彩!!! 仿真结果 对于QPSK调制,仿真结果如下: **分析:**可以看出,补偿前的定时相位约为-0.1,补偿后的相位在0附近波动,但由于没有进行环路滤波(可采用卡尔曼滤波 ...

  2. bpsk调制及解调实验_无线通信中的IQ调制,BPSK调制,QPSK调制,16QAM调制的理解...

    欢迎FPGA工程师加入官方微信技术群 点击蓝字关注我们FPGA之家-中国最好最大的FPGA纯工程师社群 先从IQ调制说起: IQ调制:IQ解调原理:Linux下使用GNU Octave运行下面的代码: ...

  3. 单载波频域均衡matlab仿真,包括卷积编码维特比译码,矩阵交织,QPSK调制解调,导频插入,MMSE-FDE频域均衡

    目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 频域均衡是从校正系统的频率特性出发,利用一个可调滤波器的频率的频率特性去补偿信道或系统的频率特性,使 ...

  4. m基于QPSK调制解调的无线图像传输matlab仿真,包括扩频解扩均衡等模块

    目录 1.算法描述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法描述 软件无线电在无线通信领域被称为是自模拟通信过渡到数字通信之后的又一次革命,在军用和民用方面都 ...

  5. qpsk的映射过程_(完整版)QPSK调制原理及matlab程序实现

    QPSK 已调信号生成 一. QPSK 介绍 QPSK 是英文 Quadrature Phase Shift Keying 的缩写,意为正交相移键 控,是一种数字调制方式.其有抗干扰性强.误码性能好. ...

  6. QPSK调制解调仿真matlab

    QPSK是MPSK的一种,对于理解MPSK有着很大的帮助. 在理解MPSK中,有以下几个难点: 什么是串并转换 如何把QPSK转换成两路2PSK信号 解调时如何判决 下面给出我结合全网与自己的理解的Q ...

  7. QPSK调制解调过程,包括串并转换,电平转换,载波调制,相干解调,抽样判决等

    目录 一.理论基础 二.核心程序 三.仿真结论 一.理论基础 QPSK是英文Quadrature Phase Shift Keying的缩略语简称,意为正交相移键控,是一种数字调制方式.在19世纪80 ...

  8. QPSK调制解调FPGA实现成果展示:

    目录 QPSK调制解调使用参数: 调制: 解调: FPGA工程架构: 仿真参数: 仿真展示: 调制: 解调: MATLAB星座图展示: QPSK调制解调使用参数: 采样率为4M,符号速率为1M,载波速 ...

  9. 基于MATLAB的BPSK和QPSK调制的性能比较

    摘要:本文基于研究了MATLAB设计了一个数字通信系统,该系统研究比较了同一数据在不同信噪比下通过高斯信道时BPSK和QPSK的误码率,以及通过同一个瑞利信道时,不同信噪比下两种调制方式的误码率,同时 ...

最新文章

  1. 兰州大学C语言程序设计课程作业,【兰州大学|兰州大学C语言程序设计课程作业( 五 )】语言程序设计|课程|作业-傻大方...
  2. 给博客增加了一个主题Nautica02Liquid
  3. centos上用yum安装rar/unrar
  4. python处理excel-python处理Excel的简单示例
  5. 谁是最可爱的人--环卫工人
  6. [python]练习之递归和循环实现斐波拉契数列
  7. 用神经网络计算甲醛CH2O和亚硝酸HNO2的化学键的键能
  8. 第一章 计算机网络 5 分层结构/协议/接口/服务的概念 [计算机网络笔记]
  9. html5 视频路径加密,HTML5视频路径混淆
  10. 高能同步辐射光源科学数据管理策略研究与应用
  11. elipse安装php
  12. 开启服务器时启动线程
  13. MySQL中的常用函数和聚合函数
  14. 计算机财务管理复利现值的公式,财务管理公式
  15. 常用前端Js框架简介
  16. 大型网络整体安装与配置解决方案
  17. 在线计算机系统考试测试题,最新计算机考试题库及答案.docx
  18. 批量查排名的工具有哪些?网站关键词可以优化?
  19. 数学建模:线性规划—奶制品的生产销售计划模型 (Python 求解)
  20. 初窥 Python 的 import 机制

热门文章

  1. Leetcode 138. 复制带随机指针的链表 解题思路及C++实现
  2. 高数第七版_习题解答_3-1行列式习题
  3. c3p0 参数 模糊查询_mybatis之动态sql,模糊查询,结果集处理,mybatis分页及特殊字符处理...
  4. Create an Apex class that returns contacts based on incoming parameters
  5. mysql实现查询最近7天的数据
  6. npm修改淘宝镜像飞速下载,npm install过程速度优化,npm删除镜像恢复默认
  7. oracle 数据库问题:“ORA-01922: 必须指定 CASCADE 以删除...“,原因及解决办法
  8. c# 学习笔记 (1) 类型转换
  9. 最短路径·三:SPFA算法 HihoCoder - 1093 (spfa无向图)
  10. 图像多尺度对比增强算法