精华内容
下载资源
问答
  • Python模拟调制

    2020-11-15 19:40:56
    分享一下我用Python模拟的AM,PM,FM调制,起因就是刚开始了解调制的时候,有点理解不了,那模拟一下呗,然后就写了一个代码。 代码地址 先放一个AM的演示图 然后看一个程序调用,我不喜欢奇奇怪怪的操作,程序调用...

    分享一下我用Python模拟的AM,PM,FM调制,起因就是刚开始了解调制的时候,有点理解不了,那模拟一下呗,然后就写了一个代码。
    代码地址

    先放一个AM的演示图
    在这里插入图片描述

    然后看一个程序调用,我不喜欢奇奇怪怪的操作,程序调用要符合操作逻辑:创建信息波和载波,然后生成调制信号波,最后画图。

    fig = plt.figure() # 创建画布
    
    # 初始化波的参数:频率和幅度
    A = 2 # carrier wave amplitude 
    m = 1  #  m is the amplitude sensitivity
    mes_fre = 1 # message wave frequence 
    car_fre = 10  # carrier  wave frequence 
    
    # 创建信息波
    signal = Signal()
    mes_wave = SinWave(fre=mes_fre, Amp=A*m, Phi=0)
    information_signal = signal + mes_wave
    # 创建载波
    carrier_signal = CosWave(fre=car_fre, Amp=A, Phi=0)
    # 创建时间轴
    time = np.arange(0, 2*np.pi, 0.01)
    # 生成调制信号
    am_sig = AM(information_signal, carrier_signal, A=A)
    
    # 画出动图
    ud = UpdateDist(fig, time, information_signal, carrier_signal, am_sig)
    ani = animation.FuncAnimation(fig=fig,
                                    func=ud,
                                    frames=20,
                                    interval=100,
                                    blit=True)
    plt.show()
    

    我比较喜欢模块化应用,我在网上也调研了一部分的模拟代码,发现大多是一次性的工作,基本没有移植性。所以我就按照我的思想写了一个脚本,虽然代码会显得有点臃肿,但是移植性还是蛮不错的。接下来就分享一下我的思路,我不会讲调制的原理,就讲代码的实现方式。

    创建大体的框架

    1. 构建基本类变量

    模拟的是调制,调制也就是两个信号的相互作用。信号也就是波的叠加,简化一下,载波(carrier wave)用单一频率的波表示,信号波(message wave)用波实现简单运算得到。这个时候还有点复杂,波的种类繁多,所以我就只考虑Sin和Cos波。对应到代码构造,我比较喜欢用类编程,于是就有了下面的结构

    class Wavedef __init__(self, fre, Amp, Phi):
            # 定义波的公共属性:幅度、频率、相位
            pass 
        def __str__(self):
         # 打印波的信息,方便后期调试
         pass 
    
     class SinWave(Wave):
         # 继承 Wave 类,子类实现 波与波的乘法运算
         def __init__(self, fre, Amp, Phi, modu_wave=None):
             super().__init__(fre, Amp, Phi, modu_wave, info='Sin')
    
         def __call__(self, t):
             # 定义调用接口,实现将t带入运算
             pass
         def __mul__(self, scalar):
             # 定义 波与波 之间的乘法运算法则
             pass
            
         def __rmul__(self, scalar):
             # 也是 实现 波与波的运算 
             pass
    
     class CosWave(Wave):
         # 构造与 SinWave 类似,不同的只是乘法运算法则不同
    
     class Signal:
         def __init__(self, sig=None):
             # 初始化 "Signal", 可以是 Wave 也可以是 实数,内部用 list 保存
             pass
    
         def max_fre(self):
             # 获取 Signal 的最大频率
             pass
    
         def max_Amp(self):
             # 获取 Signal 的最大幅值
             pass
    
         def __iter__(self):
             # 使得 Signal 变为可迭代对象,满足 Signal*Wave的运算
             pass
    
         def __add__(self, sig):
             # Signal 满足加法运算
             pass
    
         def __radd__(self, sig):
             # Signal 满足加法运算
             pass
    
         def __call__(self, t):
             # Signal 满足可调用
             pass
    
         def __str__(self):
             # 打印 Signal 的信息,方便以后调试。
             pass
    

    2. 完善调制函数

    信号Signal和波Wave初始化完成后,需要考虑调制的函数。这里用3个函数表示三种调制就行了

    def AM(information_signal, carrier_signal, A):
        # AM 幅度调制,A 是调幅的参数,参考AM调制的原理
        pass
    
    def PM(information_signal, carrier_signal):
        # PM 相位调制 
        pass
    
    def FM(information_signal, carrier_signal, h=1):
        # FM 频率调制,h是调频参数 参考FM调制的原理
        pass
    

    3. 构建作图函数

    创建画图类 UpdateDist

    class UpdateDist:
        # 画动图时候推荐采用类编程,比函数好管理
        def __init__(self, fig, x, *func_y):
            # 初始化刚开始的图像显示,我这里初始化了三个波
            pass
        
        def __call__(self, i):
            # 调用函数,这里的 i 也就是 t=i 时刻函数的图像,这样达到了动态显示的效果
            pass
    

    代码的完善

    对代码的完善就是对上面框架的缝缝补补,有时候可能会修改框架,上面的框架是我推翻了一次原框架后的结果。不过上面的框架还是适用于 AM 调制,因为 AM 调制本质就是几个波的乘法运算,而 PM 和 FM 是修改了波的相位,于是我就加了一个 modu_wave 变量

    class CosWave(Wave):
        def __init__(self, fre, Amp, Phi, modu_wave=None):
            # modu_wave 默认为 None ,如果 PM 和 FM 时需要传入
            super().__init__(fre, Amp, Phi, modu_wave, info='Cos')
            self.modu_wave = modu_wave
            
        
    class SinWave(Wave):
        def __init__(self, fre, Amp, Phi, modu_wave=None):
            super().__init__(fre, Amp, Phi, modu_wave, info='Sin')
            self.modu_wave = modu_wave
    

    代码的具体实现,点击获取原文可以查看。

    关于代码中的一些函数的解释

    我在代码中用了几个 __mul____add__等以__开头结尾的函数,这是python的魔法函数,它是python的一种协议。比如如果实现了函数 __add__,就可以使用 + 运算。

    1. __add____radd__

      # 比如这里有两个波
      test1_wave = CosWave(fre= 2, Amp=0.5, Phi=0)
      test2_wave = CosWave(fre= 3, Amp=0.5, Phi=0)
      # 实现了 __add__ 函数后 载波信号可以这么写
      signal = Signal()
      information_signal = signal  + test1_wave + test2_wave
      # 实现了 __radd__ 函数后,前后式子可以调换位置
      information_signal = test1_wave + signal + test2_wave
      
      # tip: 我这里只在 Signal 中实现了 + 法运算,所以 下面的写法会报错
      # test_wave = test1_wave + test2_wave # 报错
      # 原因嘛,我觉得 Signal 实现 + 就够使用了
      

      可以看看波的样子
      在这里插入图片描述

    2. __mul____rmul__

      # __mul__ 表示乘法运算
      # 还是上面的两个波,我可以直接这么写
      information_signal = signal  + test1_wave * test2_wave
      # 同理 实现了 __rmul__ 后可以换位置
      information_signal = signal  + test2_wave * test1_wave
      

      看看波的样子
      在这里插入图片描述

    3. __call__

      # 实现 # call 函数后,类变量可以和函数一样调用
      # 上面的波举例,我要是想知道 t=1 时函数的幅值我就可以这么写
      A1 = test1_wave(1) # 0.5
      A2 = test2_wave(1) # 0.5
      
    4. __str__

      # 实现函数后 可以使用 str(func) 打印函数
      # 接着上面的例子, 程序结果放在 '#' 后面
      print(test1_wave) # CosWave(Frequency is 2,Amplitude is 0.5,Initial phase is 0),modulate wave is None
      print(test2_wave) # CosWave(Frequency is 2,Amplitude is 0.5,Initial phase is 0),modulate wave is None
      

    总结

    以上就是我分享的这次代码的细节部分,点击阅读全文获取代码。最后放几个 PM 和 FM 调制的图,我曾经对着这个图呆了一早上。
    代码地址

    FM
    PM

    展开全文
  • python实现BPSK调制信号解调

    千次阅读 2018-10-15 09:50:29
    众所周知,matlab中信号处理的工具箱十分强大,但因为一些深度学习实时性的需求,博主不得不转至python,下面是用python编写的一个完整的测试;实现了BPSK的相干解调,门限使用积分判决。 源码: # -*- coding:...

    众所周知,matlab中信号处理的工具箱十分强大,但因为一些深度学习实时性的需求,博主不得不转至python,下面是用python编写的一个完整的测试;实现了BPSK的相干解调,门限使用积分判决。

    源码:

    # -*- coding:utf-8 -*-
    
    import numpy as np
    
    from math import pi
    
    import matplotlib.pyplot as plt
    
    import matplotlib
    
    import scipy.signal as signal
    
    import math
    
    
    
    #码元数
    
    size = 10
    
    sampling_t = 0.01
    
    t = np.arange(0, size, sampling_t)
    
    
    
    # 随机生成信号序列
    
    a = np.random.randint(0, 2, size)
    
    m = np.zeros(len(t), dtype=np.float32)
    
    for i in range(len(t)):
    
        m[i] = a[math.floor(t[i])]
    
    fig = plt.figure()
    
    ax1 = fig.add_subplot(3, 1, 1)
    
    
    
    # 解决set_title中文乱码
    
    zhfont1 = matplotlib.font_manager.FontProperties(fname = 'C:\Windows\Fonts\simsun.ttc')
    
    ax1.set_title('产生随机n位二进制信号', fontproperties = zhfont1, fontsize = 20)
    
    plt.axis([0, size, -0.5, 1.5])
    
    plt.plot(t, m, 'b')
    
    
    
    fc = 4000
    
    fs = 20 * fc # 采样频率
    
    ts = np.arange(0, (100 * size) / fs, 1 / fs)
    
    coherent_carrier = np.cos(np.dot(2 * pi * fc, ts))
    
    
    
    bpsk = np.cos(np.dot(2 * pi * fc, ts) + pi * (m - 1) + pi / 4)
    
    
    
    # BPSK调制信号波形
    
    ax2 = fig.add_subplot(3, 1, 2)
    
    ax2.set_title('BPSK调制信号', fontproperties=zhfont1, fontsize=20)
    
    plt.axis([0,size,-1.5, 1.5])
    
    plt.plot(t, bpsk, 'r')
    
    
    
    
    
    # 定义加性高斯白噪声
    
    def awgn(y, snr):
    
        snr = 10 ** (snr / 10.0)
    
        xpower = np.sum(y ** 2) / len(y)
    
        npower = xpower / snr
    
        return np.random.randn(len(y)) * np.sqrt(npower) + y
    
    
    
    # 加AWGN噪声
    
    noise_bpsk = awgn(bpsk, 5)
    
    
    
    # BPSK调制信号叠加噪声波形
    
    ax3 = fig.add_subplot(3, 1, 3)
    
    ax3.set_title('BPSK调制信号叠加噪声波形', fontproperties = zhfont1, fontsize = 20)
    
    plt.axis([0, size, -1.5, 1.5])
    
    plt.plot(t, noise_bpsk, 'r')
    
    
    
    
    
    # 带通椭圆滤波器设计,通带为[2000,6000]
    
    [b11,a11] = signal.ellip(5, 0.5, 60, [2000 * 2 / 80000, 6000 * 2 / 80000], btype = 'bandpass', analog = False, output = 'ba')
    
    
    
    # 低通滤波器设计,通带截止频率为2000Hz
    
    [b12,a12] = signal.ellip(5, 0.5, 60, (2000 * 2 / 80000), btype = 'lowpass', analog = False, output = 'ba')
    
    
    
    # 通过带通滤波器滤除带外噪声
    
    bandpass_out = signal.filtfilt(b11, a11, noise_bpsk)
    
    
    
    # 相干解调,乘以同频同相的相干载波
    
    coherent_demod = bandpass_out * (coherent_carrier * 2)
    
    
    
    # 通过低通滤波器
    
    lowpass_out = signal.filtfilt(b12, a12, coherent_demod)
    
    fig2 = plt.figure()
    
    bx1 = fig2.add_subplot(3, 1, 1)
    
    bx1.set_title('本地载波下变频,经低通滤波器后', fontproperties = zhfont1, fontsize=20)
    
    plt.axis([0, size, -1.5, 1.5])
    
    plt.plot(t, lowpass_out, 'r')
    
    
    
    #抽样判决
    
    detection_bpsk = np.zeros(len(t), dtype=np.float32)
    
    flag = np.zeros(size, dtype=np.float32)
    
    
    
    for i in range(10):
    
        tempF = 0
    
        for j in range(100):
    
            tempF = tempF + lowpass_out[i * 100 + j]
    
        if tempF > 0:
    
            flag[i] = 1
    
        else:
    
            flag[i] = 0
    
    for i in range(size):
    
        if flag[i] == 0:
    
            for j in range(100):
    
                detection_bpsk[i * 100 + j] = 0
    
        else:
    
            for j in range(100):
    
                detection_bpsk[i * 100 + j] = 1
    
    
    
    bx2 = fig2.add_subplot(3, 1, 2)
    
    bx2.set_title('BPSK信号抽样判决后的信号', fontproperties = zhfont1, fontsize=20)
    
    plt.axis([0, size, -0.5, 1.5])
    
    plt.plot(t, detection_bpsk, 'r')
    
    plt.show()

     

    显示结果:

    展开全文
  • 1 BPSK调制 # -*- coding:utf-8 -*- import numpy as np from math import pi import matplotlib.pyplot as plt import matplotlib import math #码元数 size = 10 sampling_t = 0.01 t = np.arange(0, ...

    1 BPSK调制

    # -*- coding:utf-8 -*-
     
    import numpy as np
    from math import pi
    import matplotlib.pyplot as plt
    import matplotlib
    import math
     
     
     
    #码元数
     
    size = 10
    sampling_t = 0.01
    t = np.arange(0, size, sampling_t)
     
    
    # 随机生成信号序列
    a = np.random.randint(0, 2, size)
    m = np.zeros(len(t), dtype=np.float32)
    for i in range(len(t)):
        m[i] = a[math.floor(t[i])]
    fig = plt.figure()
    ax1 = fig.add_subplot(2, 1, 1)
     
    ax1.set_title('generate Random Binary signal', fontsize = 20)
    plt.axis([0, size, -0.5, 1.5])
    plt.plot(t, m, 'b')
    
    fc = 4000
    fs = 20 * fc # 采样频率
    ts = np.arange(0, (100 * size) / fs, 1 / fs)
    coherent_carrier = np.cos(np.dot(2 * pi * fc, ts))
     
    bpsk = np.cos(np.dot(2 * pi * fc, ts) + pi * (m - 1) + pi / 4)
    
    # BPSK调制信号波形
    ax2 = fig.add_subplot(2, 1, 2)
    ax2.set_title('BPSK Modulation', fontsize=20)#, fontproperties=zhfont1
    plt.axis([0,size,-1.5, 1.5])
    plt.plot(t, bpsk, 'r')
    plt.show()
    print()
    

    在这里插入图片描述

    2 QPSK

    from scipy import signal, special
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.ticker as mticker 
    from matplotlib.font_manager import FontProperties
    
    
    t = np.arange(0,8.5,0.5)
    # input
    plt.subplot(4,1,1)
    y1 = [0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,0]
    plt.plot(t,y1,drawstyle='steps-post')
    plt.xlim(0,8)
    plt.ylim(-0.5,1.5)
    plt.title('Input Signal')
    
    # I Signal
    plt.subplot(4,1,2)
    a = 1/np.sqrt(2)
    tI = np.arange(0,9,1)
    yI = [-a,a,-a,a,-a,a,-a,a,a]
    plt.plot(tI,yI,drawstyle='steps-post')
    plt.xlim(0,8)
    plt.ylim(-2,2)
    plt.title('I signal')
    
    # Q signal
    plt.subplot(4,1,3)
    yQ = [a,-a,-a,a,a,-a,-a,a,a]
    plt.plot(tI,yQ,drawstyle='steps-post')
    plt.xlim(0,8)
    plt.ylim(-1,1)
    plt.title('Q Signal')
    
    # QPSK signal
    plt.subplot(4,1,4)
    t = np.arange(0,9.,0.01)
    def outputwave(I,Q,t):
        rectwav = []
        for i in range(len(I)):
            t_tmp = t[((i)*100):((i+1)*100)]
            yI_tmp = yI[i]*np.ones(100)
            yQ_tmp = yQ[i]*np.ones(100)
            wav_tmp = yI_tmp*np.cos(2*np.pi*5*t_tmp)-yQ_tmp*np.sin(2*np.pi*5*t_tmp)
            rectwav.append(wav_tmp)
        return rectwav
    rectwav = outputwave(yI,yQ,t)
    plt.plot(t,np.array(rectwav).flatten(),'r')
    plt.xlim(0,8)
    plt.ylim(-2,2)
    plt.title('QPSK Signal')
    
    plt.tight_layout()
    plt.show()
    

    在这里插入图片描述

    3 QAM

    4 参考资料

    1. python实现BPSK调制信号解调
    2. 深入浅出通信原理Python代码版
    3. Python实现M-QAM
    展开全文
  • 有太多的调制原理了,BPSK、QPSK、MSK等等,前面林君学长分别进行了对应的BPKS和QPSK调制与解调的博客讲解,本次博客,林君学长主要讲解MSK的调制解调原理,并通过调制解调原理,进行对应的调制解调python代码的设计...


    移动通信原理学习过程中,有太多的调制原理了,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个码元可以表示为:
    在这里插入图片描述
    式中,ws=2πfsw_s=2\pi f_s为视在角载频;aka_k=±1;T为第k个码元确定的初始相位。
    (2)、由上式可以看出,当aka_k=+1时,码元频率f1f_1等于fs+1/4Tf_s+1/4T;当aka_k=-1时,码元频率f0f_0等于fs1/4Tf_s-1/4T。故f1f_1f0f_0的距离等于1/2T1/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应用于生活中的调制解调问题有一定的了解,同时,林君学长也希望大家能够深入的了解代码的具体意思,理解原理;代码有错误的地方记得给林君学长留言改正。
    同时、遇到问题的小伙伴也记得评论区留言,林君学长看到会给大家回复解答的,这个学长不太冷!

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

    展开全文
  • 基于jupyter notebook的python编程-----通过python编程实现信号传输QPSK的调制与解调目录一、QPSK调制解调原理1、什么是QPSK?2、QPSK调制原理3、QPSK解调原理二、QPSK的python代码设计1、QPSK调制框图设计2、高斯白...
  • 文章目录雷达脉冲串信号脉内信号PRI序列python代码 雷达脉冲串信号 脉内信号 脉冲内的信号有两种: 常规连续波信号 s(t)=cos(2πf0t)s(t)=cos(2\pi f_0 t)s(t)=cos(2πf0​t) 线性调频信号 s(t)=cos(2πf0t+πkt2)s...
  • 文章目录QPSK调制原理及python实现QPSK调制原理python实现调制过程1、导入相关库函数2、调制过程3、作图过程 QPSK调制原理及python实现 QPSK调制原理 QPSK调制过程及原理在前面的博客中以及详细分析过。在本文中将...
  • 如何用MATLAB产生数字调制的基带信号,这是设计调制解调器的第一步。 T=1; % 基带信号宽度,也就是频率 nb=100; % 定义传输的比特数 delta_T=T/200; fs=1/delta_T; ...
  • AWGN信道下QPSK调制信号的平均相位估计 piccolo.用python简单实现的作业 Q1:在Eb/N0(5db~30db,间隔5db)下的加性高斯白噪声,并且假设信道为AWGN信道引入了30度的相位误差,采用QPSK调制信号作为导频信号,试...
  • 本实验目的使用python仿真PRI调制,脉内为LFM信号,参数接口使用configparse调用.ini文件。 整体思路:首先把lfm信号和0矩阵拼接(均为一维矩阵),生成一个完整的周期信号,period_num数量个信号的PRI都不相同...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,114
精华内容 845
关键字:

python信号调制

python 订阅