,都可通過下式得到單邊帶的已調信號:至此,我們完成了對DSB-AM和SSB-AM基本原理的介紹。下面,將按照上文基本原理展示矩形波的單邊帶幅度調製與解調。矩形波SSB-AM與解調令周期為4,佔空比(高電平信號的振幅持續時間與信號總時間之比)為0.5,振幅為1的矩形波作為基帶信號。一個周期內的矩形波波形圖如圖1所示。圖 1 一個周期內的矩形波令載波是一頻率為100 Hz,振幅為1,初相為0的餘弦波。按公式(5),可得到已調信號,因為已調信號的頻率幾乎與載波相同,為清晰顯示,此處僅展示0.1秒內的已調信號,如圖2。圖 2 0.1秒內的已調信號經調製後,信號的頻譜會發生變化。圖3是基帶信號與已調信號的歸一化頻譜的對比,從中可以看出,調製將信號的頻譜由低頻處搬運到高頻。圖 3 基帶信號與已調信號的歸一化頻譜對已調信號乘以載波,並作低通濾波,低通濾波器的邊界頻率是100 Hz。經過上述步驟,就可從已調信號中提取出基帶信號。最後,獲得基帶信號與解調信號的對比圖,如圖4所示。從圖4可以看出,解調信號與基帶信號幾乎是完全一致的,只有在邊界處有一些畸變。圖 4 基帶信號與解調信號的對比代碼SSBModulate.py:矩形波單邊帶調製與解調的主程序代碼,直接運行可生成上述4幅圖。""" 矩形波單邊帶調製與解調的主程序代碼 """ import numpy as np import scipy.fftpack as fftp import matplotlib as mpl import matplotlib.pyplot as plt import Filter mpl.rcParams['font.sans-serif'] = ['KaiTi'] # 保證正常顯示中文 mpl.rcParams['font.serif'] = ['KaiTi'] # 保證正常顯示中文 mpl.rcParams['axes.unicode_minus'] = False # 保證負號正常顯示 dt = 0.001 # 時間域採樣間隔 Fs = 1/dt # 採樣率 T = 4 # 矩形波的周期 nT = 10 # 總的周期數 nPT = int(T/dt+0.5) # 每個周期的樣點數 n = nT*nPT # 總樣點數 alpha = 0.5 # 矩形波的佔空比 t = np.arange(dt, n*dt+dt, dt) f = np.zeros((n, 1), dtype=np.float64) A = 1 for i in range(0, nT, 1): f[(i+1)*nPT-int(alpha*nPT):(i+1)*nPT] = A # 得到矩形波 fc = 100 # 載波的頻率 g1 = np.cos(2*np.pi*fc*t).reshape(n, 1) g2 = np.sin(2*np.pi*fc*t).reshape(n, 1) hf = fftp.hilbert(f.reshape(n, )) # 矩形波的希爾伯特變換 s = 0.5*f*g1-0.5*hf.reshape(n, 1)*g2 # 已調信號 s_dm = s*g1 # 解調 cutoff = 60 # 截至頻率 order = 6 # 濾波器的階數 s_dm = 4*Filter.butter_lowpass_filtfilt(s_dm, cutoff, Fs, order) # 作低通濾波 f_spec = np.fft.fft(f, n, 0) # 作傅立葉變換 freq = np.fft.fftfreq(n, dt).reshape(n, 1) # 得到每點的頻率 f_spec_amp = abs(f_spec)/(n/2) # 對頻譜的振幅作歸一化 f_spec_amp[0] = f_spec_amp[0]/2 f_spec_amp[int(n/2)+1] = f_spec_amp[int(n/2)+1]/2 s_spec = np.fft.fft(s, n, 0) s_spec_amp = abs(s_spec)/(n/2) s_spec_amp[0] = s_spec_amp[0]/2 s_spec_amp[int(n/2)+1] = s_spec_amp[int(n/2)+1]/2 # 繪製一個周期內的矩形波 plt.figure(num=1) plt.plot(t[0:nPT], f[0:nPT], 'b-') plt.xlim(0, T) plt.ylim(-0.5, 1.5) plt.xlabel('時間/(s)') plt.ylabel('振幅') plt.title('一個周期內的矩形波信號') plt.savefig('圖1.jpg', dpi=600) plt.show() # 繪製已調信號 plt.figure(num=2) plt.plot(t[0:int(10/fc/dt+0.5)], s[0:int(10/fc/dt+0.5)], 'b-') plt.xlim(0, 10/fc) plt.ylim(-1.5, 1.5) plt.xlabel('時間/(s)') plt.ylabel('振幅') plt.title('已調信號') plt.savefig('圖2.jpg', dpi=600) plt.show() # 繪製基帶信號與已調信號的頻譜 plt.figure(num=3) plt.plot(freq, f_spec_amp, 'b-', freq, s_spec_amp, 'r-') plt.xlim(min(freq), max(freq)) plt.legend(('基帶信號的頻譜', '已調信號的頻譜'), loc='upper right') plt.xlabel('頻率/(Hz)') plt.ylabel('振幅') plt.title('基帶信號和已調信號的歸一化頻譜') plt.savefig('圖3.jpg', dpi=600) plt.show() # 繪製基帶信號與解調信號 plt.figure(num=4) plt.plot(t[0:nPT], f[0:nPT], 'b-', t[0:nPT], s_dm[0:nPT], 'r-') plt.legend(('基帶信號', '解調信號'), loc='upper right') plt.xlim(0, T) plt.ylim(-0.5, 1.5) plt.xlabel('時間/(s)') plt.ylabel('振幅') plt.title('基帶信號和解調信號') plt.savefig('圖4.jpg', dpi=600) plt.show()""" 濾波模塊 """ import numpy as np import scipy.signal as signalP def butter_lowpass(cutoff, fs, order=5): """ 根據低通濾波通帶截至頻率和採樣頻率計算濾波器分子係數b和分母係數a :param cutoff: 截至頻率 :param fs: 採樣頻率 :param order: 濾波器的階數 :return: b, a分別為濾波器的分子和分母 """ nyq = 0.5*fs normal_cutoff = cutoff/nyq b, a = signalP.butter(order, normal_cutoff, btype='low') return b, a def butter_lowpass_filtfilt(data, cutoff, fs, order=5): """ 對信號作低通濾波 :param data: 輸入信號 :param cutoff: 通帶截至頻率 :param fs: 採樣頻率 :param order: 濾波器的階數 :return: 返回值為y,經低通濾波後的信號 """ b, a = butter_lowpass(cutoff, fs, order=order) shape = data.shape if shape[0] != 1: data = data.T y = signalP.filtfilt(b, a, data) y =y.T return y PS:完整的Python代碼,我已經整理到我的百度企業雲盤中,感興趣的小夥伴可以從以下分享連結(有效期7天)中下載:https://eyun.baidu.com/s/3ggWaYsz