[算法] QPSK调制与解调详解(完整仿真代码)

QPSK调制与解调详解


一、QPSK基本原理

QPSK(Quadrature Phase Shift Keying)是一种高效的数字调制技术,通过载波的四种相位状态传输数据。每个符号携带2比特信息,频谱利用率是BPSK的两倍。

数学表达式

s(t) = I(t)·cos(2πf₀t) - Q(t)·sin(2πf₀t)
其中:
I(t) = 同相分量(In-phase)
Q(t) = 正交分量(Quadrature)
f₀ = 载波频率

星座图映射规则(格雷码编码):

比特对相位I分量Q分量复数表示
0045°+1/√2+1/√2(1+1j)/√2
01135°-1/√2+1/√2(-1+1j)/√2
11225°-1/√2-1/√2(-1-1j)/√2
10315°+1/√2-1/√2(1-1j)/√2

二、调制解调流程

调制过程

  1. 二进制数据分组成2比特符号
  2. 映射为I/Q两路基带信号
  3. 分别与正交载波相乘
  4. 合成射频信号

解调过程

  1. 接收信号与正交载波相乘
  2. 低通滤波提取基带信号
  3. 采样判决I/Q分量
  4. 逆映射恢复二进制数据

具体调制解调流程如下图所示:

解调部分
调制部分
乘以载波 cos
添加噪声
乘以载波 -sin
低通滤波
低通滤波
匹配滤波
匹配滤波
符号定时采样
符号定时采样
判决
判决
并串转换
I路比特
串并转换
Q路比特
极性转换
极性转换
脉冲成形
脉冲成形
乘以载波 cos
乘以载波 -sin
信号合成
二进制数据流
QPSK信号
信道传输
恢复二进制数据
subgraph_mod
subgraph_demod

三、Python完整仿真代码
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, lfilter

# 参数设置
num_symbols = 1000       # 符号数
sps = 16                 # 每符号采样数
sample_rate = 1e6        # 采样率 (Hz)
carrier_freq = 0.1e6     # 载波频率 (Hz)
noise_power = 0.01       # 噪声功率

# 生成随机二进制数据
data = np.random.randint(0, 2, num_symbols * 2)

# ================== QPSK调制 ==================
# 数据分组:每2比特 -> 1个符号
symbols = data.reshape(-1, 2)

# 比特映射(格雷码)
def bits_to_qpsk(bits):
    if bits[0] == 0 and bits[1] == 0: return (1 + 1j) / np.sqrt(2)
    if bits[0] == 0 and bits[1] == 1: return (-1 + 1j) / np.sqrt(2)
    if bits[0] == 1 and bits[1] == 1: return (-1 - 1j) / np.sqrt(2)
    if bits[0] == 1 and bits[1] == 0: return (1 - 1j) / np.sqrt(2)

# 生成符号流
symbol_stream = np.array([bits_to_qpsk(sym) for sym in symbols])

# 上采样(插值)
tx_signal = np.zeros(num_symbols * sps, dtype=complex)
tx_signal[::sps] = symbol_stream

# 设计成型滤波器(根升余弦)
beta = 0.35  # 滚降系数
t = np.arange(-4*sps, 4*sps) / sps
h = np.sinc(t) * np.cos(np.pi*beta*t) / (1 - (2*beta*t)**2)
h = h / np.sqrt(np.sum(h**2))  # 归一化

# 脉冲成形
tx_shaped = np.convolve(tx_signal, h, mode='same')

# 载波调制
t = np.arange(len(tx_shaped)) / sample_rate
tx_real = np.real(tx_shaped) * np.cos(2*np.pi*carrier_freq*t)
tx_imag = np.imag(tx_shaped) * -np.sin(2*np.pi*carrier_freq*t)
tx_wave = tx_real + tx_imag

# ================== 信道模拟 ==================
# 添加高斯白噪声
noise = np.sqrt(noise_power/2) * (np.random.randn(len(tx_wave)) + 1j*np.random.randn(len(tx_wave)))
rx_signal = tx_wave + noise

# ================== QPSK解调 ==================
# 正交下变频
t = np.arange(len(rx_signal)) / sample_rate
rx_i = rx_signal * np.cos(2*np.pi*carrier_freq*t)
rx_q = rx_signal * -np.sin(2*np.pi*carrier_freq*t)

# 低通滤波
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

b, a = butter_lowpass(carrier_freq/2, sample_rate)
rx_i_filt = lfilter(b, a, rx_i)
rx_q_filt = lfilter(b, a, rx_q)
rx_baseband = rx_i_filt + 1j*rx_q_filt

# 匹配滤波
rx_shaped = np.convolve(rx_baseband, h, mode='same')

# 采样判决
rx_samples = rx_shaped[sps//2::sps]  # 符号中心点采样

# 解映射
def qpsk_to_bits(symbol):
    angle = np.angle(symbol)
    if angle >= 0 and angle < np.pi/2: return [0, 0]
    if angle >= np.pi/2 and angle < np.pi: return [0, 1]
    if angle < 0 and angle >= -np.pi/2: return [1, 0]
    return [1, 1]

rx_bits = []
for sym in rx_samples:
    rx_bits.extend(qpsk_to_bits(sym))
rx_bits = np.array(rx_bits[:len(data)])  # 截断至原始长度

# ================== 性能分析 ==================
# 计算误码率
ber = np.sum(data != rx_bits) / len(data)
print(f"误码率 (BER): {ber:.2%}")

# 绘制星座图
plt.figure(figsize=(10, 8))
plt.scatter(np.real(rx_samples), np.imag(rx_samples), alpha=0.6)
plt.axhline(0, color='k', linestyle='--')
plt.axvline(0, color='k', linestyle='--')
plt.grid(True)
plt.title("接收信号星座图")
plt.xlabel("I分量")
plt.ylabel("Q分量")
plt.axis('equal')
plt.show()

四、关键代码解析
  1. 格雷码映射:最小化相邻符号的比特差异,降低误码率
  2. 脉冲成形:使用根升余弦滤波器消除码间干扰
  3. 相干解调:需要精确的载波同步
  4. 匹配滤波:最大化信噪比的最佳接收方案
五、仿真结果分析
  • 星座图:展示接收信号在I-Q平面的分布
    在这里插入图片描述

  • 误码率:量化系统性能,典型值10⁻²~10⁻⁵

误码率 (BER): 0.05%
  • 噪声影响:噪声功率增大时,星座点会扩散
六、实际应用场景
  1. 卫星通信(DVB-S2标准)
  2. 4G/5G移动通信(LTE控制信道)
  3. WiFi(802.11a/g/n)

通过调整噪声功率(noise_power参数),可观察不同信噪比下的系统性能变化。在理想信道中,BER趋近于0;当噪声功率超过0.5时,误码率显著上升。


研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值