日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

VC++实现QPSK调制

發布時間:2025/4/14 c/c++ 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC++实现QPSK调制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正交相移鍵控(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调制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。