手把手复现1G通话:用Python模拟FM调制、FSK信令与FDMA多用户通信
在移动通信的演进史中,1G系统如同数字时代的罗塞塔石碑,用模拟信号承载了人类首次无线对话的自由。今天我们将穿越回1983年摩托罗拉DynaTAC 8000X面世的年代,用Python代码拆解那些藏在"大哥大"厚重机身里的通信奥秘。不同于教科书上的理论框图,这里每个步骤都将转化为可执行的代码块——从语音信号的FM调制、控制信令的FSK生成,到多用户频分复用的频谱舞蹈,最后完成接收端的信号重建。准备好你的Jupyter Notebook,我们即将用NumPy和Matplotlib重现那段电磁波里的模拟浪漫。
1. 环境准备与基础波形生成
1.1 配置Python通信仿真环境
现代Python生态为我们提供了堪比专业通信仿真工具的计算能力。建议创建独立的conda环境:
conda create -n 1g_sim python=3.9 conda activate 1g_sim pip install numpy matplotlib scipy ipython核心库版本要求:
- NumPy ≥1.20(用于向量化信号处理)
- Matplotlib ≥3.4(支持频谱瀑布图等高级可视化)
- SciPy ≥1.7(包含FIR滤波器设计工具)
提示:在Jupyter中运行
%matplotlib widget可获得交互式频谱探索体验
1.2 生成基带语音信号仿真
1G系统处理的语音信号带宽通常限制在300-3400Hz。我们通过叠加正弦波模拟典型语音特征:
import numpy as np import matplotlib.pyplot as plt fs = 44100 # 采样率高于奈奎斯特频率 t = np.linspace(0, 1, fs) # 1秒时长 # 模拟元音共振峰特征 voice_base = (0.5 * np.sin(2*np.pi*800*t) + 0.3 * np.sin(2*np.pi*1200*t) + 0.2 * np.sin(2*np.pi*2500*t)) # 添加幅度波动模拟自然语音 envelope = 0.5*(1 + np.sin(2*np.pi*5*t)) voice_signal = voice_base * envelope2. FM调制实现与频偏控制
2.1 调频原理的数学表达
频率调制的本质是让载波频率随基带信号变化:
瞬时频率 = 载波频率 + Δf * m(t)其中Δf称为最大频偏,m(t)是归一化的调制信号。
关键参数对照表:
| 参数 | 典型值 | 物理意义 |
|---|---|---|
| fc | 900MHz | 载波中心频率 |
| Δf | 12kHz | FCC规定的最大频偏 |
| β | 1.5-5 | 调制指数(Δf/fm) |
2.2 Python实现FM调制
通过相位积分实现真正的频率调制:
def fm_modulate(carrier_freq, mod_signal, fs, delta_f): # 归一化调制信号 mod_signal = mod_signal / np.max(np.abs(mod_signal)) # 相位积分 phase = 2*np.pi*carrier_freq*t + 2*np.pi*delta_f*np.cumsum(mod_signal)/fs return np.cos(phase) # 调制示例 carrier_freq = 100e3 # 为演示降低频率 fm_signal = fm_modulate(carrier_freq, voice_signal, fs, delta_f=12e3)3. 控制信令的FSK调制实现
3.1 1G系统的信令机制
早期系统使用**双音多频(DTMF)**作为控制信令,例如:
- 拨号数字"5":770Hz + 1336Hz组合
- 信道分配信令:通常采用2-FSK调制
3.2 FSK调制核心代码
用频率变化表示二进制数据:
def generate_fsk(data_bits, bit_rate, f0, f1, fs): t_bit = np.arange(0, 1/bit_rate, 1/fs) signal = [] for bit in data_bits: freq = f0 if bit == 0 else f1 signal.extend(np.cos(2*np.pi*freq*t_bit)) return np.array(signal) # 示例:生成号码"911"的FSK信令 dtmf_map = {'9': (852, 1477)} # 简化的DTMF映射 fsk_signal = generate_fsk([1,0,1,1,0,0,0,1], 1200, 1200, 1800, fs)注意:实际系统会添加CRC校验和前导码
4. FDMA多用户系统仿真
4.1 频分复用架构设计
模拟三个用户共享频谱资源:
| 用户 | 中心频率 | 占用带宽 |
|---|---|---|
| A | 890MHz | 30kHz |
| B | 890.03MHz | 30kHz |
| C | 890.06MHz | 30kHz |
4.2 频谱合成与信道效应
使用频移实现多路信号合成:
def apply_frequency_shift(signal, shift, fs): t = np.arange(len(signal))/fs return signal * np.exp(1j*2*np.pi*shift*t) # 合成三个用户信号 user_a = apply_frequency_shift(fm_signal, 890e6, fs) user_b = apply_frequency_shift(fm_signal, 890.03e6, fs) user_c = apply_frequency_shift(fm_signal, 890.06e6, fs) composite_signal = user_a + user_b + user_c5. 接收端解调实战
5.1 超外差接收机仿真
典型的接收链路包含:
- RF带通滤波(模拟LC调谐电路)
- 混频降频(使用10.7MHz中频)
- 限幅放大与鉴频
from scipy import signal # 设计88-108MHz带通滤波器 bpf = signal.firwin(101, [88e6, 108e6], fs=fs, pass_zero=False) # 混频降频 local_osc = np.cos(2*np.pi*(890e6-10.7e6)*t) if_signal = composite_signal * local_osc5.2 FM解调技巧
采用相位差分法实现鉴频:
def fm_demod(signal, fs): analytic_signal = signal.hilbert(signal) phase = np.unwrap(np.angle(analytic_signal)) return np.diff(phase) * fs / (2*np.pi) demodulated = fm_demod(if_signal, fs)在完成这些代码实验后,对比原始语音与解调信号的频谱相似度,你会发现1G系统虽然简单,但已经蕴含了现代通信的诸多核心思想。那些看似笨重的模拟电路,实则是工程师们用硬件实现的实时傅里叶变换器——这或许就是通信技术的永恒魅力:无论技术如何演进,电磁波承载人类情感的本质从未改变。