QAM16调制解调
简单说明QAM16调制就是QPSK和4ASK一起使用,相对单独的QPSK和4ASK来说,能够提升频谱利用效率。
暂时没有波形输出,后继版本会添加相关的波形输出代码,以及滤波器相关的设计
类中的x代表输入码的个数,类中的y代表每个周期的采样点数,其他算法相关数据依据这两点产生,其中频率默认是2000Hz,可以直接更变为更高。频率是fre参数,只能设置为整数。
抽样判决需要等低通滤波器设计完后才能实现,后继该文章会更新。
#include "pch.h"
#include <iostream>
#define _MATH_DEFINES_DEFINED
#include <math.h>
#include <stdlib.h>
static const float PI = atan(1) * 4;
static const float PI2 = atan(1);
class filter;
class QAM16
{
private:
int sl; //信号数目
float *sig; //信号数组
float *sam_Time; //采样点时间
float *demod_sig1; //解调后波形
float *demod_sig2; //解调后波形
int *num; //输入数据
int fre; //载波频率
int sam; //每个周期采样点数
float fre_Flo;
int sam_Fre; //采样频率
int car_Sam; //每个载波采样个数
int car_Num; //多少个周期传输一个信息码
int code_Num; //多少个采样点传递一个信息码
int all_Sam; //一共多少个采样点
public:
QAM16(int x = 10, int y = 10); //初始化信号数组
void set_QAM16_num();
void set_QAM16_sig();
void demod_QAM16_sig();
friend class FIR_lowpassfilter;
};
QAM16::QAM16(int x, int y)
{
if (x < 1)
{
std::cout << "码个数不能少于1";
return;
}
if (y<2)
{
std::cout << "每个周期采样点数不能小于2";
return;
}
sl = x;
sam = y;
fre = 2000;
fre_Flo = fre * PI;
sam_Fre = fre * y;
car_Num = 10;
car_Sam = y;
code_Num = car_Num * car_Sam;
all_Sam = code_Num * x;
num = new int [sl];
sig = new float [all_Sam];
sam_Time = new float[all_Sam];
demod_sig1 = new float[all_Sam];
demod_sig2 = new float[all_Sam];
for (int i = 0; i < all_Sam; i++)
sam_Time[i] = i / sam_Fre * fre_Flo;
return;
}
void QAM16::set_QAM16_num()
{
for (int i = 0; i < sl; i++)
num[i] = rand() % 16;
}
void QAM16::set_QAM16_sig() //调制
{
int a, b;
for (int i = 0; i < sl; i++)
{
a = num[i] / 4 + 1;
b = num[i] % 4;
for (int j = 0; j < code_Num; j++)
sig[j] = a * cos(sam_Time[i*code_Num + j] + PI2 * b);
}
}
void QAM16::demod_QAM16_sig()
{
for (int j = 0; j < code_Num*sl; j++)
{
demod_sig1[j] = cos(sam_Time[j])*sig[j];
demod_sig2[j] = cos(sam_Time[j] + PI2)*sig[j];
}
}
int main()
{
QAM16 Signal;
Signal.set_QAM16_sig();
Signal.set_QAM16_num();
Signal.demod_QAM16_sig();
}