基于jupyter notebook的python编程-----通过python编程实现信号传输MSK的调制与解调


移动通信原理学习过程中,有太多的调制原理了,BPSK、QPSK、MSK等等,前面林君学长分别进行了对应的BPKS和QPSK调制与解调的博客讲解,本次博客,林君学长主要讲解MSK的调制解调原理,并通过调制解调原理,进行对应的调制解调python代码的设计,一起学习吧

一、MSK调制解调原理

1、什么是MSK?

1)、最小频移键控MSK (Minimum Shift Keying)是一种改变波载频率来传输信息的调制技术,即特殊的连续相位的频移键控 (CPFSK)。其最大频移为比特速率的1/4,即MSK是调制系数为0.5的连续相位的FSK。
2)、在数字调制中,最小频移键控(Minimum-Shift Keying,缩写:MSK)是一种连续相位的频移键控方式,在1950年代末和1960年代产生。与偏移四相相移键控(OQPSK)类似,MSK同样将正交路基带信号相对于同相路基带信号延时符号间隔的一半,从而消除了已调信号中180°相位突变的现象。与OQPSK不同的是, MSK采用正弦型脉冲代替了OQPSK基带信号的矩形波形,因此得到恒定包络的调制信号,这有助于减少非线性失真带来的解调问题

MSK又称快速移频键控(FFSK)。这里“最小”指的是能以最小的调制指数(即0.5)获得正交信号;而“快速”指的是对于给定的频带,它能比PSK传送更高的比特速率。
MSK是一种在无线移动通信中很有吸引力的数字调制方式,它具有以下两种主要的特点:
1.信号能量的99.5%被限制在数据传输速率的1.5倍的带宽内。谱密度随频率(远离信号带宽中心)倒数的四次幂而下降,而通常的离散相位FSK信号的谱密度却随频率倒数的平方下降。因此,MSK信号在带外产生的干扰非常小。这正是限带工作情况下所希望有的宝贵特点。
2.信号包络是恒定的,系统可以使用廉价高效的非线性器件。

更多有关MSK的介绍,小伙伴可以参考以下链接进行相关了解,链接如下:https://baike.baidu.com/item/MSK/5475817?fr=aladdin

2、MSK调制原理

1)、MSK调制原理
(1)、MSK信号是一种相位连续、包络恒定并且占用带宽最小的二进制正交FSK信号。它的第k个码元可以表示为:
在这里插入图片描述
式中, w s = 2 π f s w_s=2\pi f_s 为视在角载频; a k a_k =±1;T为第k个码元确定的初始相位。
(2)、由上式可以看出,当 a k a_k =+1时,码元频率 f 1 f_1 等于 f s + 1 / 4 T f_s+1/4T ;当 a k a_k =-1时,码元频率 f 0 f_0 等于 f s 1 / 4 T f_s-1/4T 。故 f 1 f_1 f 0 f_0 的距离等于 1 / 2 T 1/2T 。这是2FSK信号最小频率间隔。
(3)、式(2-1)可以用频率为的两个正交分量表示。将式(2-1)进行三角公式变换,得到:
在这里插入图片描述
式(3-1)表示,此MSK信号可以分解为同相分量(I)和正交分量(Q)两部分。
2)、MSK调制原理框图
由式(3-1)可知,MSK信号可以用两个正交的分量表示。根据该式构成 的MSK信号的产生MSK原理框图如下所示:
在这里插入图片描述

3、MSK解调原理

1)、MSK解调原理
由于MSK信号是最小二进制FSK信号,所以它可以采用解调FSK信号的相干法和非相干法解调。
2)、MSK解调原理框图
通过解调原理,可得到MSK信号的解调原理框图,如下所示:
在这里插入图片描述

二、MSK调制解调的python代码设计

1、信号发射器设计

def information(N):#输入比特流的个数N,输出我们的信号,要么是1,要么是0
    signal=np.array([])
    for i in range(N):
        x=random.random()
        if x>=0.5:
            x=1
        else:
            x=0
        signal=np.insert(signal,len(signal),x)
    return signal

传递我们需要参数信号的个数N ,然后该函数产生0、1的比特流

2、高斯白噪声设计

def awgn(x, snr):
    snr = 10**(snr/10.0)
    xpower = np.sum(x**2)/len(x)
    npower = xpower/snr
    return np.random.randn(len(x)) * np.sqrt(npower)+x

模拟信号在信道传输的过程中掺杂的噪声,x为我们调制后的信号,snr为信噪比,然后输出掺杂高斯白噪声后的调制信号

3、低通滤波器设计

def butter_lowpass(cutoff, fs, order=5):
    nyq = 0.5 * fs
    normal_cutoff = cutoff / nyq
    b, a = butter(order, normal_cutoff, btype='low', analog=False)
    return b, a
def myfilter(data, cutoff, fs, order=5):
    b, a = butter_lowpass(cutoff, fs,order=order)
    y = lfilter(b, a, data)
    return y

调制信号需要经过低通滤波器,所以以上函数只是为了模拟低通滤波器的作用,其中:

  • cutoff:截止频率
  • fs:信号采样频率
  • order:滤波器的阶数
  • data:滤波之前的调制信号

4、MSK调制原理框图设计

1)、导入需要的python库

import numpy as np
import random
import matplotlib.pyplot as plt
  • numpy: 进行数学与数组的计算
  • random: 产生随机信号
  • matplotlib.pyplot: 绘制各种信号的图像

2)、MSK调制原理框图python设计

N=20
T=1
fc=10
Fs=100
bitstream=information(N)
bitstream1=2*bitstream-1
b0=1
encode_output=np.array([])
for i in range(1,N+1):
    encode_output=np.insert(encode_output,len(encode_output),b0*bitstream1[i-1])
    b0=encode_output[i-1]
I=np.array([])
Q=np.array([])
for i in range(1,N+1):
    if np.mod(i,2)!=0:
        I=np.insert(I,len(I),encode_output[i-1])
    else:
        Q=np.insert(Q,len(Q),encode_output[i-1])
bit_data=np.array([])
for i in range(1,N+1):
     bit_data=np.insert(bit_data,len(bit_data),encode_output[i-1]*np.ones(T*Fs))
I_data=np.array([])
Q_data=np.array([])
base_wave=np.array([])
for i in np.arange(-T,T,1/Fs):
    base_wave=np.insert(base_wave,len(base_wave),i)
for i in range(1,int(N/2)+1):
    I_data=np.insert(I_data,len(I_data),I[i-1]*np.cos(np.pi*base_wave/(2*T)))
    Q_data=np.insert(Q_data,len(Q_data),Q[i-1]*np.cos(np.pi*base_wave/(2*T)))
number_delay=int(len(base_wave)/2)
a=np.zeros(number_delay)
b=Q_data[0:len(Q_data)-number_delay]
Q_data1=np.hstack((a,b))
t=np.array([])
for i in np.arange(0,N*T,1/Fs):
    t=np.insert(t,len(t),i)
plt.subplot(3,1,1)
plt.plot(t,bit_data)
plt.legend(["Bitstream"],loc='upper right')
plt.subplot(3,1,2)
plt.plot(t,I_data)
plt.legend(["I_Bitstream"],loc='upper right')
plt.subplot(3,1,3)
plt.plot(t,Q_data1)
plt.legend(["Q_Bitstream"],loc='upper right')
plt.show()

以上python代码功能为MSK的调制过程,将信号进行串/并变换,分为I路和Q路,然后进行对应的信号调制
3)、调制信号波形图如下所示:
在这里插入图片描述

5、MSK解调原理框图设计

1)、MSK解调原理框图python设计

bit_t=np.array([])
for i in np.arange(0,N*T,1/Fs):
    bit_t=np.insert(bit_t,len(bit_t),i)
I_carrier=np.cos(2*np.pi*fc*bit_t)
Q_carrier=np.cos(2*np.pi*fc*bit_t+np.pi/2)
MSK_signal=I_data*I_carrier+Q_data1*Q_carrier
snr=1
MSK_receive=awgn(MSK_signal,snr)
I_output=MSK_receive*I_carrier
I_filter_output=myfilter(I_output, fc, Fs, order=5)
Q_output=MSK_receive*Q_carrier
Q_filter_output=myfilter(Q_output, fc, Fs, order=5)
I_recover=np.array([])
Q_recover=np.array([])
for i in range(1,int(N/2)+1):
    if I_filter_output[(2*i-2)*number_delay]>0:
        I_recover=np.insert(I_recover,len(I_recover),1)
    else:
        I_recover=np.insert(I_recover,len(I_recover),-1)
    if Q_filter_output[(2*i-1)*number_delay]>0:
        Q_recover=np.insert(Q_recover,len(Q_recover),1)
    else:
        Q_recover=np.insert(Q_recover,len(Q_recover),-1)
bit_recover=np.array([])
for i in range(1,N+1):
    if np.mod(i,2)!=0:
        bit_recover=np.insert(bit_recover,len(bit_recover),I_recover[int((i-1)/2)])
    else:
        bit_recover=np.insert(bit_recover,len(bit_recover),Q_recover[int(i/2)-1])
bit_recover1=np.array([])
for i in range(1,N+1):
    if i==1:
        bit_recover1=np.insert(bit_recover1,len(bit_recover1),bit_recover[i-1])
    else:
        bit_recover1=np.insert(bit_recover1,len(bit_recover1),bit_recover[i-1]*bit_recover[i-2])
recover_data=np.array([])
for i in range(1,N+1):
    recover_data=np.insert(recover_data,len(recover_data),bit_recover1[i-1]*np.ones(T*Fs))
bit_stream=np.array([])
for i in range(1,N+1):
    bit_stream=np.insert(bit_stream,len(bit_stream),bitstream1[i-1]*np.ones(T*Fs))
plt.subplot(2,1,2)
plt.plot(t,bit_stream)
plt.legend(["original Bitstream"],loc='upper right')
plt.subplot(2,1,1)
plt.plot(t,recover_data)
plt.legend(["recover Bitstream"],loc='upper right')
plt.show()

以上python代码功能为MSK解调过程模拟,对调制信号进行解调,然后得到解调信号的波形图!
2)、MSK解调信号波形图如下所示:
在这里插入图片描述

三、MSK调制解调结论

1、MSK调制结论

1)、MSK调制信号波形如下所示:
在这里插入图片描述
2)、上图调制仿真的结果为原始信号的波形,和串/并变换后I路和Q路的解调信号的波形
3)、从上图可以看出,I路的调制信号和Q路的调制信号的波形不同的原因主要是因为载波相位不同导致的,当然,这也是MSK调制独特的特点

2、MSK解调结论

1)、MSK解调信号波形如下所示:
在这里插入图片描述
2)、上图解调的波形为解调信号与原始信号的波形图
3)、可以看出,解调后的信号波形图与原始信号是非常吻合的,这个结果对于这个实验来说是很重要的结果,这暗示这我们的MSK的python代码是模拟的非常好的!同时决定的MSK的调制、解调性能的优异

四、MSK调制解调整体代码

1、MPSK调制解调完整python代码如下所示

import numpy as np
import random
import matplotlib.pyplot as plt
from scipy.signal import butter, lfilter
def awgn(x, snr):
    snr = 10**(snr/10.0)
    xpower = np.sum(x**2)/len(x)
    npower = xpower/snr
    return np.random.randn(len(x)) * np.sqrt(npower)+x
def information(N):#输入比特流的个数N,输出我们的信号,要么是1,要么是0
    signal=np.array([])
    for i in range(N):
        x=random.random()
        if x>=0.5:
            x=1
        else:
            x=0
        signal=np.insert(signal,len(signal),x)
    return signal
def butter_lowpass(cutoff, fs, order=5):
    nyq = 0.5 * fs
    normal_cutoff = cutoff / nyq
    b, a = butter(order, normal_cutoff, btype='low', analog=False)
    return b, a

def myfilter(data, cutoff, fs, order=5):
    b, a = butter_lowpass(cutoff, fs,order=order)
    y = lfilter(b, a, data)
    return y
N=20
T=1
fc=10
Fs=100
bitstream=information(N)
bitstream1=2*bitstream-1
b0=1
encode_output=np.array([])
for i in range(1,N+1):
    encode_output=np.insert(encode_output,len(encode_output),b0*bitstream1[i-1])
    b0=encode_output[i-1]
I=np.array([])
Q=np.array([])
for i in range(1,N+1):
    if np.mod(i,2)!=0:
        I=np.insert(I,len(I),encode_output[i-1])
    else:
        Q=np.insert(Q,len(Q),encode_output[i-1])
bit_data=np.array([])
for i in range(1,N+1):
     bit_data=np.insert(bit_data,len(bit_data),encode_output[i-1]*np.ones(T*Fs))
I_data=np.array([])
Q_data=np.array([])
base_wave=np.array([])
for i in np.arange(-T,T,1/Fs):
    base_wave=np.insert(base_wave,len(base_wave),i)
for i in range(1,int(N/2)+1):
    I_data=np.insert(I_data,len(I_data),I[i-1]*np.cos(np.pi*base_wave/(2*T)))
    Q_data=np.insert(Q_data,len(Q_data),Q[i-1]*np.cos(np.pi*base_wave/(2*T)))
number_delay=int(len(base_wave)/2)
a=np.zeros(number_delay)
b=Q_data[0:len(Q_data)-number_delay]
Q_data1=np.hstack((a,b))
t=np.array([])
for i in np.arange(0,N*T,1/Fs):
    t=np.insert(t,len(t),i)
plt.subplot(3,1,1)
plt.plot(t,bit_data)
plt.legend(["Bitstream"],loc='upper right')
plt.subplot(3,1,2)
plt.plot(t,I_data)
plt.legend(["I_Bitstream"],loc='upper right')
plt.subplot(3,1,3)
plt.plot(t,Q_data1)
plt.legend(["Q_Bitstream"],loc='upper right')
plt.show()
bit_t=np.array([])
for i in np.arange(0,N*T,1/Fs):
    bit_t=np.insert(bit_t,len(bit_t),i)
I_carrier=np.cos(2*np.pi*fc*bit_t)
Q_carrier=np.cos(2*np.pi*fc*bit_t+np.pi/2)
MSK_signal=I_data*I_carrier+Q_data1*Q_carrier
snr=1
MSK_receive=awgn(MSK_signal,snr)
I_output=MSK_receive*I_carrier
I_filter_output=myfilter(I_output, fc, Fs, order=5)
Q_output=MSK_receive*Q_carrier
Q_filter_output=myfilter(Q_output, fc, Fs, order=5)
I_recover=np.array([])
Q_recover=np.array([])
for i in range(1,int(N/2)+1):
    if I_filter_output[(2*i-2)*number_delay]>0:
        I_recover=np.insert(I_recover,len(I_recover),1)
    else:
        I_recover=np.insert(I_recover,len(I_recover),-1)
    if Q_filter_output[(2*i-1)*number_delay]>0:
        Q_recover=np.insert(Q_recover,len(Q_recover),1)
    else:
        Q_recover=np.insert(Q_recover,len(Q_recover),-1)
bit_recover=np.array([])
for i in range(1,N+1):
    if np.mod(i,2)!=0:
        bit_recover=np.insert(bit_recover,len(bit_recover),I_recover[int((i-1)/2)])
    else:
        bit_recover=np.insert(bit_recover,len(bit_recover),Q_recover[int(i/2)-1])
bit_recover1=np.array([])
for i in range(1,N+1):
    if i==1:
        bit_recover1=np.insert(bit_recover1,len(bit_recover1),bit_recover[i-1])
    else:
        bit_recover1=np.insert(bit_recover1,len(bit_recover1),bit_recover[i-1]*bit_recover[i-2])
recover_data=np.array([])
for i in range(1,N+1):
    recover_data=np.insert(recover_data,len(recover_data),bit_recover1[i-1]*np.ones(T*Fs))
bit_stream=np.array([])
for i in range(1,N+1):
    bit_stream=np.insert(bit_stream,len(bit_stream),bitstream1[i-1]*np.ones(T*Fs))
plt.subplot(2,1,2)
plt.plot(t,bit_stream)
plt.legend(["original Bitstream"],loc='upper right')
plt.subplot(2,1,1)
plt.plot(t,recover_data)
plt.legend(["recover Bitstream"],loc='upper right')
plt.show()

以上就是本次博客的全部内容啦,通过本次博客,大家可以更好的了解到MSK的的调制与解调原理,也能够对MSK应用于生活中的调制解调问题有一定的了解,同时,林君学长也希望大家能够深入的了解代码的具体意思,理解原理;代码有错误的地方记得给林君学长留言改正。
同时、遇到问题的小伙伴也记得评论区留言,林君学长看到会给大家回复解答的,这个学长不太冷!

陈一月的又一天编程岁月^ _ ^

猜你喜欢

转载自blog.csdn.net/qq_42451251/article/details/106538148
今日推荐