概述
文章目录
- 前言
- 一、介绍
- [1]. 平均功率
- [2]. I输入和Q输入
- [3]. 映射
- [4]. I和Q输出
- [5]. 进制转换
- 二、代码
前言
QAM
正交振幅调制是Quadrature Amplitude Modulation
的缩写,
QAM
星座图有好几种,4QAM(也称QPSK)、16QAM和64QAM
。
此篇文章主要是针对16QAM
进行编码实现,4QAM
和64QAM
的实现方法与16QAM
类似。
介绍中有些内容的原理不大记得了,如果有错误的话可评论指出。
一、介绍
[1]. 平均功率
由于博主在实现时没有使用的星座图来计算对应的QAM平均功率,所以需要在代码中设置一个平均功率进行计算的。
平均功率的求法如下:
- 先在
QAM
中确定一个坐标系,默认两个黑点的间距为2
- 计算原点到指定点的距离
确定一个
QAM
对应的平均功率只需要求下方几个例图的红线长度。
对于QPSK
来说,黑点00
的坐标为(1,1)
,所以由勾股定理可以得出红线的长度为根号2
则QPSK
的平均功率就是根号2
对于
16QAM
,黑点0001
的坐标为(1,3)
,所以线段长度为根号10
在
64QAM
中,点坐标(1,7)
到原点的距离为根号50
[2]. I输入和Q输入
下方是
16QAM
的一个例题,我们需要输入一个二进制串,
然后将这个二进制串分成8
个分组,对于每个分组的前2位
需要分配给I
,后两位分配给Q
I
相当于星座图的横轴,Q
相当于星座图的纵轴。
分组的组数不能随便分,简单来说对于
16QAM
中16 = 2 * 8
,组数就是除以2
后的数字8
(如果没记错的话)
4QAM(QPSK)|16QAM|64QAM
–|–|–|–
2组|8组|32组
[3]. 映射
经过步骤二的分组后,二进制序列
0000 1111 0101 1010 0000 1111 0101 1010
I
输入为:00 11 01 10 00 11 01 10
Q
输入为:00 11 01 10 00 11 01 10
将二进制数据提取出来后,不能直接传入
I和Q
进行计算
而是需要通过题目给出的映射关系表,将二进制转换为十进制数据。
原二进制 | 目标十进制 |
---|---|
00 | -3 |
01 | -1 |
11 | 1 |
10 | 3 |
[4]. I和Q输出
经过步骤三的映射转换后,对应的数据如下
I
输入为:-3 1 -1 3 -3 1 -1 3
Q
输入为:-3 1 -1 3 -3 1 -1 3
获取了数据之后,就需要进行计算了
计算输出的规则为:输出的数据 =原输入的十进制
/QAM的平均功率
[5]. 进制转换
经过步骤四的计算后,数据的类型为小数。
在数字通信中是以二进制的方式进行传输,所以计算后需要转换成对应的二进制输出。
小数
在进行二进制转换
的时候采用的是乘2取整
的方式,
对于又是负数又是小数
的情况,需要求解正数
情况下的二进制
数据,然后对结果中除了符号位外
的二进制进行逐位取反
操作。
二、代码
# coding=utf-8
# 作者:小狐狸
# 题目:模拟实现16QAM调制
def float_to_bin(number):
'''转二进制串输出'''
bin_number = ""
#添加两个符号位
if number<0:
bin_number += "11"
else:
bin_number += "00"
num = abs(number)
for i in range(6):
## print(num,bin_number)
num *= 2 #乘2
bin_number += str(int(num)) #取整
num -= int(num) #保留小数位
num = round(num,4) #保留4位小数,消除精度影响
if bin_number[:2:]=="11": #负数
string = "11" #临时字符串
for i in range(2,len(bin_number)): #除符号位,逐位取反
if bin_number[i]=='1':
string += '0'
else:
string += '1'
return string
else:
return bin_number
##print(float_to_bin(0.3162))
avg = pow(10,0.5) #16QAM平均功率
data = list(input("请输入:").split())
input_i = [] #I输入
input_q = [] #Q输入
output_i = [] #I输出
output_q = [] #Q输出
for i in data:
input_i.append(i[0:2:]) #前两个二进制数据
input_q.append(i[-3:-1:]) #后两个二进制数据
#求解I输出
for i in input_i:
if i=="00": #00对应-3
output_i.append(round(-3/avg,4)) #保留4位小数
elif i=="01": #01对应-1
output_i.append(round(-1/avg,4)) #保留4位小数
elif i=="11": #11对应1
output_i.append(round(1/avg,4)) #保留4位小数
elif i=="10": #10对应3
output_i.append(round(3/avg,4)) #保留4位小数
#求解Q输出
for i in input_q:
if i=="00": #00对应-3
output_q.append(round(-3/avg,4)) #保留4位小数
elif i=="01": #01对应-1
output_q.append(round(-1/avg,4)) #保留4位小数
elif i=="11": #11对应1
output_q.append(round(1/avg,4)) #保留4位小数
elif i=="10": #10对应3
output_q.append(round(3/avg,4)) #保留4位小数
#十进制转二进制
for i in range(len(output_i)):
output_i[i] = float_to_bin(output_i[i]) #I输出
output_q[i] = float_to_bin(output_q[i]) #Q输出
#输出
print("I输出:",' '.join(str(i) for i in output_i))
print("Q输出:",' '.join(str(i) for i in output_q))
##测试数据
##0000 1111 0101 1010 0000 1111 0101 1010
#0.3162小数转bin
##0.3162*2 = 0.6324
##0.6324*2 = 1.2648
##0.2648*2 = 0.5296
##0.5296*2 = 1.0592
##0.0592*2 = 0.1184
##0.1184*2 = 0.2368
最后
以上就是诚心往事为你收集整理的Python笔记-16QAM的编程实现前言一、介绍二、代码的全部内容,希望文章能够帮你解决Python笔记-16QAM的编程实现前言一、介绍二、代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复