方形16QAM的C语言仿真

本文首先给出16QAM的原理,再给出对应方形星座的C语言设计过程,并附代码。

一、16QAM调制方式原理

为改善进制数较大情况下噪声容限减小的问题,发展出了QAM技术。QAM表示正交幅度调制,其对振幅和相位两个参量同时调制,其具有很高的频谱利用率和抗干扰能力,但对器件参数要求较高。
研究QAM技术主要从其最明显的特征——星座图入手。一般的,我们可以将QPSK视为4QAM,其为最简单的QAM,扩展至16QAM,对比其信号矢量图如下:

可以将16QAM视为两个交错的4ASK。对于每一个点的编码,可以分为对两个4ASK进行级联编码,按格雷码编码如下图所示:
使用格雷码按照上图顺序进行编码可以保证横,纵只有一比特位改变,在保证误码率不变的情况下将减小误比特率。

方形16QAM星座的噪声容限相较于星型16QAM的噪声容限要大,但在衰落信道中,由于星型16QAM的相位,幅度值少,故性能要更好。但是在调制解调的复杂度上,方形更好。

二、16QAM仿真程序

只需要将信号按照两路4ASK在调制判决即可。对于高斯噪声的添加原理,请参考以下博客的第二节:
BPSK,QPSK的C语言仿真
这里信噪比中的Eb计算如下:
方形16QAM的信号平均功率为:
P=A2M∑n=1M(cn2+dn2)=10A2P = \frac{{{A^2}}}{M}\sum\limits_{n = 1}^M {\left( {{c_n}^2 + {d_n}^2} \right)} = 10{A^2}P=MA2​n=1∑M​(cn​2+dn​2)=10A2
程序内设置A=1A=1A=1,则单位信号能量为10,则单位比特能量为2.5。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#define pi 3.14159265
#define data_len 1000000            //比特长
#define M 4                         //进制数
#define k 16                        //符号比特
#define N 2                         //正交路 I Q
#define symbol_len data_len / M
#define EbN0_dB_MAX 15int data_bfcoding[data_len];
int symbol_bfcoding[M][symbol_len];
double symbol_coding[N][symbol_len];
int symbol_decoding[M][symbol_len];
int data_decoding[data_len];
double Eb = 2.5;void Data_produce();
void Symbol_produce();
void Modulation();
double Gauss();
void Gaussnoise(double EbN0_dB);
void Demodulation();
double Erdproduce();
double Mrdproduce();int main()
{double EbN0_dB = 0;srand(unsigned int(time(NULL)));double Erd, Mrd;for (int i = 0; i <= EbN0_dB_MAX; i++){EbN0_dB = i;Data_produce();Symbol_produce();Modulation();Gaussnoise(EbN0_dB);Demodulation();Erd = Erdproduce();Mrd = Mrdproduce();printf("Eb/N0 %d dB\t Symbol_Error: %f \t Bit_Error:%f \n", i, Mrd, Erd);}return 0;
}void Data_produce()
{for (int i = 0; i < data_len; i++){data_bfcoding[i] = rand() % 2;}
}void Symbol_produce()
{int temp = 0;for (int i = 0; i < symbol_len; i++){for (int j = 0; j < M; j++){symbol_bfcoding[j][i] = data_bfcoding[temp];temp++;}}
}void Modulation()
{for (int i = 0; i < symbol_len; i++){if (symbol_bfcoding[0][i] == 0 && symbol_bfcoding[1][i] == 0){symbol_coding[0][i] = -3.0;}if (symbol_bfcoding[0][i] == 0 && symbol_bfcoding[1][i] == 1){symbol_coding[0][i] = -1.0;}if (symbol_bfcoding[0][i] == 1 && symbol_bfcoding[1][i] == 1){symbol_coding[0][i] = 1.0;}if (symbol_bfcoding[0][i] == 1 && symbol_bfcoding[1][i] == 0){symbol_coding[0][i] = 3.0;}}for (int i = 0; i < symbol_len; i++){if (symbol_bfcoding[2][i] == 0 && symbol_bfcoding[3][i] == 0){symbol_coding[1][i] = -3.0;}if (symbol_bfcoding[2][i] == 0 && symbol_bfcoding[3][i] == 1){symbol_coding[1][i] = -1.0;}if (symbol_bfcoding[2][i] == 1 && symbol_bfcoding[3][i] == 1){symbol_coding[1][i] = 1.0;}if (symbol_bfcoding[2][i] == 1 && symbol_bfcoding[3][i] == 0){symbol_coding[1][i] = 3.0;}}
}double Gauss()
{double U, V, Z;U = (double)(rand() + 1.0) / (double)(RAND_MAX + 1.0);V = (double)(rand() + 1.0) / (double)(RAND_MAX + 1.0);Z = sqrt(-2 * log(U)) * sin(2 * pi * V);return Z;
}void Gaussnoise(double EbN0_dB)
{double EbN0 = pow(10, EbN0_dB / 10);double N0 = Eb / EbN0;double sigma = sqrt(N0 / 2);for (int i = 0; i < symbol_len; i++){symbol_coding[0][i] = symbol_coding[0][i] + Gauss() * sigma;symbol_coding[1][i] = symbol_coding[1][i] + Gauss() * sigma;}
}void Demodulation()
{for (int i = 0; i < symbol_len; i++){if (symbol_coding[0][i] > 2.0){symbol_decoding[0][i] = 1;symbol_decoding[1][i] = 0;}if (symbol_coding[0][i] <= 2.0 && symbol_coding[0][i] > 0){symbol_decoding[0][i] = 1;symbol_decoding[1][i] = 1;}if (symbol_coding[0][i] <= 0 && symbol_coding[0][i] > -2.0){symbol_decoding[0][i] = 0;symbol_decoding[1][i] = 1;}if (symbol_coding[0][i] <= -2.0){symbol_decoding[0][i] = 0;symbol_decoding[1][i] = 0;}}for (int i = 0; i < symbol_len; i++){if (symbol_coding[1][i] > 2.0){symbol_decoding[2][i] = 1;symbol_decoding[3][i] = 0;}if (symbol_coding[1][i] <= 2.0 && symbol_coding[1][i] > 0){symbol_decoding[2][i] = 1;symbol_decoding[3][i] = 1;}if (symbol_coding[1][i] <= 0 && symbol_coding[1][i] > -2.0){symbol_decoding[2][i] = 0;symbol_decoding[3][i] = 1;}if (symbol_coding[1][i] <= -2.0){symbol_decoding[2][i] = 0;symbol_decoding[3][i] = 0;}}int temp = 0;for (int i = 0; i < symbol_len; i++){for (int j = 0; j < M; j++){data_decoding[temp] = symbol_decoding[j][i];temp++;}}
}double Erdproduce()
{double Erd;int Nrd = 0;for (int i = 0; i < data_len; i++){if (data_decoding[i] != data_bfcoding[i])Nrd++;}Erd = (double)Nrd / (double)data_len;return Erd;
}double Mrdproduce()
{double Mrd;int Srd = 0;int p[M];int pt;for (int i = 0; i < symbol_len; i++){int pt = 0;for (int j = 0; j < M; j++){if (symbol_decoding[j][i] == symbol_bfcoding[j][i])p[j] = 0;elsep[j] = 1;}for (int j = 0; j < M; j++){pt = pt + p[j];}if (pt > 0)Srd++;}Mrd = (double)Srd / (double)(symbol_len);return Mrd;
}

三、仿真结果

下面给出不同比特信噪比下误码率和误比特率结果。

方形16QAM的C语言仿真相关推荐

  1. 简陋版C语言仿真通讯录之动态内存开辟版本

    简陋版C语言仿真通讯录 https://blog.csdn.net/csdn_kou/article/details/80287640 简陋版C语言仿真通讯录之动态内存开辟版本 给Contact结构体 ...

  2. BPSK,QPSK的C语言仿真

    BPSK,QPSK的C语言仿真 本文首先给出BPSK的原理,再给出对应的C语言设计过程,并附代码. 当给出BPSK的过程后,QPSK即为分路问题,将直接给出代码. 一.什么是BPSK BPSK可以被称 ...

  3. 开源RISC-V处理器(蜂鸟E203)学习(五)A100T-FPGA 移植蜂鸟Hbirdv2,实现Centos下调试器USB识别以及程序编译烧写,并进行C语言仿真

    1.简述 最近购买了一块适合做原型验证FPGA板卡,板卡接口和外设比较丰富,十分适合跑一些小型的SOC工程,比如蜂鸟E203:板卡自带FPGA烧写器和软核CPU的JATG调试器,还有USB接口的UAR ...

  4. DSP定点运算之数字信号处理算法的定点化及其C语言仿真(转)

    DSP广义上指数字信号处理理论(Digital Signal Processing),狭义上指数字 信号处理器(Digital Signal Processor).数字信号处理理论广泛应用于语音.图象 ...

  5. 单片机C语言仿真图,单片机C语言程序设计代码和仿真图.doc

    word完美格式 精心整理 学习帮手 <单片机C语言程序设计实训100例-基于8051+Proteus仿真>案例 第 01 篇 基础程序设计 01闪烁的LED /* 名称:闪烁的LED 说 ...

  6. proteus8单片机c语言仿真教程,入门学习Proteus 8仿真软件以及C51单片机的LED点亮(C语言)——实例...

    入门学习Proteus 8仿真软件以及C51单片机LED的点亮(C语言)--实例 一.点亮LED的程序编译 1.打开Keil uVision 4新建一个工程 2.在Atmel下寻找AT89C52芯片并 ...

  7. 4QAM、16QAM 调制与解调仿真电路,观察并分析QAM星座图和误码率曲线【matlab代码】

    源码: https://download.csdn.net/download/qq_44394952/86236776 要求 完成两种调制方式的调制解调:4QAM.16QAM (1)画出系统框图,搞清 ...

  8. m基于simulink的16QAM和2DPSK通信链路仿真,并通过matlab调用simulink模型得到误码率曲线

    目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 2DPSK又称为相对相移键控,它不是利用载波相位的绝对数值传送数字信息,而是用前后码元的相对 ...

  9. 光栅原理及其c语言仿真,光栅原理及MATLAB仿真

    <光栅原理及MATLAB仿真>由会员分享,可在线阅读,更多相关<光栅原理及MATLAB仿真(8页珍藏版)>请在人人文库网上搜索. 1.取样光纤光栅的原理及基于MATLAB的反射 ...

  10. 光栅原理及其c语言仿真,取样光栅原理及MATLAB仿真.doc

    取样光纤光栅的原理及基于MATLAB的反射谱仿真 张睿 摘要 文章主要运用了基于耦合模理论的传输矩阵法来分析取样光栅的原理,并利用MATLAB模拟和分析了取样光栅长度.调制折射率强度.取样光栅节点的长 ...

最新文章

  1. 关于C#中编译器保证变量必须初始化规则猜想
  2. 跳出数据计算拯救人工智能之打败机器学习方法
  3. 解决不同操作系统下git换行符一致性问题
  4. 为什么 StackOverflow 上的代码片段会摧毁你的项目?
  5. c语言烟花百度云,C语言实现放烟花的程序
  6. ABP从入门到精通(4):使用基于JWT标准的Token访问WebApi
  7. 汇编语言中常用指令对标志位寄存器的影响
  8. 2016多校联合训练1 B题Chess (博弈论 SG函数)
  9. 【轻量级网络】MobileNet-v1详解
  10. 国内maven镜像,快的飞起
  11. 神操作!使用命令更改MAC截图默认保存格式的方法
  12. R工程化—Rest API 之plumber包
  13. Linux设置Oracle环境变量
  14. Win11如何获得最佳电源效率?
  15. JAVA静态变量 静态方法 两者间的区别 继承的特点 继承中的成员变量关系和成员方法 构造方法
  16. 服务器编程之路:进无止境(上)
  17. 这是你知道的建模教程吗
  18. 京东关于区块链的发展历程
  19. OLAP和OLTP比较
  20. Ubuntu20.04+ROS Noetic的安装与配置(win10系统下)

热门文章

  1. 模型训练中batch_size的选择
  2. 使用 Android 签名 APK
  3. linuX开发板eop下载器,EOP乐谱架软件|EOP乐谱架(Everyone Piano插件)下载 V1.3.12.2 最新版 - 比克尔下载...
  4. 数字图像处理 冈萨雷斯(第四版)图像配准
  5. Github上最热门的11个Java开源项目你会了吗
  6. weico.android批量转发,weico android|Weico新浪微博3.3.5 客户端_手机软件
  7. 最小二乘残差 C语言6,传感器原理和应用习题_第1章.doc
  8. 30岁,我从前端转型管理成功了
  9. 石头科技财报背后:不甘再当小米打工仔?
  10. 封装Selenium2Library