手把手用Python仿真CDMA信号处理:沃尔什码生成与解扩全流程实现

张开发
2026/4/8 16:40:42 15 分钟阅读

分享文章

手把手用Python仿真CDMA信号处理:沃尔什码生成与解扩全流程实现
Python实现CDMA信号处理从沃尔什码生成到多用户解调的完整指南1. CDMA技术基础与Python实现优势在无线通信领域码分多址(CDMA)技术因其独特的抗干扰能力和高效的频谱利用率而备受青睐。与传统的频分复用(FDMA)和时分复用(TDMA)不同CDMA允许所有用户同时使用相同的频带进行通信通过独特的编码序列来区分不同用户。Python作为科学计算和信号处理的有力工具具有以下优势丰富的库支持NumPy、SciPy等库提供高效的矩阵运算和信号处理功能交互式开发环境Jupyter Notebook非常适合算法验证和教学演示可视化能力Matplotlib可以直观展示信号处理各阶段的波形变化跨平台性代码可以在不同操作系统上无缝运行import numpy as np import matplotlib.pyplot as plt from scipy.signal import correlate # 设置全局绘图参数 plt.rcParams[figure.figsize] [10, 6] plt.rcParams[font.size] 122. 沃尔什码生成与正交性验证2.1 沃尔什码的数学原理沃尔什码是一组正交的二进制序列具有以下数学特性任意两个不同沃尔什码的内积为0同一沃尔什码的自内积等于码长度码长度必须是2的整数幂(2,4,8,16,...)沃尔什码可以通过哈达玛矩阵递归生成H₁ [0] H₂ [0 0 0 1] Hₙ [Hₙ/2 Hₙ/2 Hₙ/2 ¬Hₙ/2]2.2 Python实现沃尔什码生成def generate_walsh_code(n): 生成n阶沃尔什码矩阵 参数: n: 沃尔什码阶数必须是2的幂 返回: walsh_matrix: n×n的沃尔什码矩阵0表示11表示-1 if n 1: return np.array([[0]]) h generate_walsh_code(n//2) return np.block([[h, h], [h, 1 - h]]) # 生成8阶沃尔什码并转换为±1表示 walsh8 generate_walsh_code(8) walsh8 1 - 2 * walsh8 # 将0/1转换为1/-1 print(8阶沃尔什码矩阵:\n, walsh8)2.3 正交性验证实验def verify_orthogonality(walsh_matrix): 验证沃尔什码的正交性 n walsh_matrix.shape[0] for i in range(n): for j in range(i, n): dot_product np.dot(walsh_matrix[i], walsh_matrix[j]) if i j: assert dot_product n, f自相关验证失败: {dot_product} ! {n} else: assert dot_product 0, f互相关验证失败: {dot_product} ! 0 print(所有沃尔什码对都满足正交性条件) verify_orthogonality(walsh8)3. CDMA信号扩频与解扩实现3.1 扩频过程数学建模扩频过程可以表示为扩频信号 原始数据 ⊗ 沃尔什码其中⊗表示克罗内克积(每个数据比特与整个沃尔什码相乘)3.2 Python实现扩频与解扩def spread_signal(data, walsh_code): 使用沃尔什码对数据进行扩频 参数: data: 原始数据序列0/1数组 walsh_code: 分配的沃尔什码 返回: spread_seq: 扩频后的序列 # 将0/1数据转换为1/-1 data 1 - 2 * np.array(data) # 克罗内克积扩频 return np.kron(data, walsh_code) def despread_signal(spread_seq, walsh_code): 从扩频信号中解扩原始数据 参数: spread_seq: 接收到的扩频序列 walsh_code: 用于解扩的沃尔什码 返回: data: 解调出的原始数据 code_len len(walsh_code) num_bits len(spread_seq) // code_len data [] for i in range(num_bits): segment spread_seq[i*code_len : (i1)*code_len] correlation np.dot(segment, walsh_code) # 判决正相关为0负相关为1 data.append(0 if correlation 0 else 1) return data # 测试扩频解扩过程 user_data [1, 0, 1, 1, 0] # 用户原始数据 user_code walsh8[3] # 为用户分配第3个沃尔什码 spread_data spread_signal(user_data, user_code) recovered_data despread_signal(spread_data, user_code) print(原始数据:, user_data) print(恢复数据:, recovered_data)3.3 多用户CDMA系统仿真def simulate_multiuser_cdma(user_data_list, walsh_matrix): 模拟多用户CDMA系统 参数: user_data_list: 各用户数据列表每个元素是一个0/1数组 walsh_matrix: 沃尔什码矩阵 返回: combined_signal: 多用户叠加信号 num_users len(user_data_list) assert num_users len(walsh_matrix), 用户数超过沃尔什码数量 # 为每个用户分配不同的沃尔什码 user_codes walsh_matrix[:num_users] # 生成各用户扩频信号 spread_signals [] for data, code in zip(user_data_list, user_codes): spread_signals.append(spread_signal(data, code)) # 确保所有扩频信号长度相同 max_len max(len(s) for s in spread_signals) for i in range(num_users): if len(spread_signals[i]) max_len: spread_signals[i] np.pad(spread_signals[i], (0, max_len - len(spread_signals[i]))) # 叠加所有用户信号 combined_signal np.sum(spread_signals, axis0) return combined_signal, user_codes # 模拟3个用户同时通信 user1_data [1, 0, 1, 1] user2_data [0, 1, 1, 0] user3_data [1, 1, 0, 1] combined_signal, user_codes simulate_multiuser_cdma( [user1_data, user2_data, user3_data], walsh8) # 各用户解调自己的信号 def decode_all_users(combined_signal, user_codes): decoded_data [] for code in user_codes: decoded despread_signal(combined_signal, code) decoded_data.append(decoded) return decoded_data decoded_data decode_all_users(combined_signal, user_codes) print(用户1发送数据:, user1_data) print(用户1接收数据:, decoded_data[0]) print(用户2发送数据:, user2_data) print(用户2接收数据:, decoded_data[1]) print(用户3发送数据:, user3_data) print(用户3接收数据:, decoded_data[2])4. 噪声环境下的性能分析与优化4.1 添加高斯白噪声def add_awgn(signal, snr_db): 添加加性高斯白噪声 参数: signal: 输入信号 snr_db: 信噪比(dB) 返回: noisy_signal: 加噪后的信号 signal_power np.mean(signal**2) noise_power signal_power / (10 ** (snr_db / 10)) noise np.random.normal(0, np.sqrt(noise_power), len(signal)) return signal noise # 测试不同信噪比下的性能 snr_levels [20, 10, 5, 2, 1, 0, -5] ber_results [] for snr in snr_levels: noisy_signal add_awgn(combined_signal, snr) decoded decode_all_users(noisy_signal, user_codes) # 计算误码率(BER) errors 0 total_bits 0 for orig, recv in zip([user1_data, user2_data, user3_data], decoded): errors sum(o ! r for o, r in zip(orig, recv)) total_bits len(orig) ber errors / total_bits ber_results.append(ber) print(fSNR{snr}dB, BER{ber:.4f}) # 绘制BER-SNR曲线 plt.figure() plt.semilogy(snr_levels, ber_results, o-) plt.xlabel(SNR (dB)) plt.ylabel(Bit Error Rate) plt.title(CDMA系统在不同信噪比下的误码率) plt.grid(True, whichboth, ls--) plt.show()4.2 性能优化技术功率控制算法def power_control(user_signals, target_snr): 简单的功率控制算法 参数: user_signals: 各用户信号列表 target_snr: 目标信噪比(dB) 返回: adjusted_signals: 调整功率后的信号列表 adjusted [] for signal in user_signals: # 计算当前信号功率 power np.mean(signal**2) # 计算需要的增益 gain np.sqrt(10 ** (target_snr / 10) / power) adjusted.append(signal * gain) return adjusted # 生成各用户原始扩频信号 user_signals [spread_signal(user1_data, walsh8[0]), spread_signal(user2_data, walsh8[1]), spread_signal(user3_data, walsh8[2])] # 应用功率控制 controlled_signals power_control(user_signals, 10) # 叠加信号并添加噪声 combined_controlled np.sum(controlled_signals, axis0) noisy_controlled add_awgn(combined_controlled, 5) # 解调并比较性能 decoded_controlled decode_all_users(noisy_controlled, walsh8[:3]) print(无功率控制时的误码率:, ber_results[snr_levels.index(5)]) errors sum(sum(o ! r for o, r in zip(orig, recv)) for orig, recv in zip([user1_data, user2_data, user3_data], decoded_controlled)) print(有功率控制时的误码率:, errors / (len(user1_data)*3))多径信道仿真与均衡def simulate_multipath(signal, delays, attenuations): 模拟多径信道效应 参数: signal: 原始信号 delays: 各径延迟(采样点数) attenuations: 各径衰减系数 返回: multipath_signal: 多径效应后的信号 result np.zeros(len(signal) max(delays)) for delay, att in zip(delays, attenuations): result[delay:delaylen(signal)] signal * att return result[:len(signal)] # 创建RAKE接收机 def rake_receiver(received_signal, walsh_code, delays, attenuations): 简单的RAKE接收机实现 参数: received_signal: 接收信号 walsh_code: 用户沃尔什码 delays: 已知的多径延迟 attenuations: 已知的多径衰减 返回: combined_output: RAKE接收机输出 fingers [] code_len len(walsh_code) for delay, att in zip(delays, attenuations): # 对齐各径信号 aligned np.roll(received_signal, -delay) # 解扩 despread [] for i in range(len(aligned) // code_len): segment aligned[i*code_len:(i1)*code_len] if len(segment) code_len: despread.append(np.dot(segment, walsh_code)) fingers.append(np.array(despread) * att) # 合并各径信号 max_len max(len(f) for f in fingers) combined np.zeros(max_len) for f in fingers: combined[:len(f)] f[:max_len] return combined # 测试RAKE接收机性能 multipath_signal simulate_multipath(combined_signal, [0, 3, 7], [1, 0.5, 0.3]) noisy_multipath add_awgn(multipath_signal, 10) # 传统接收机 normal_decoded despread_signal(noisy_multipath, walsh8[0]) # RAKE接收机 rake_output rake_receiver(noisy_multipath, walsh8[0], [0, 3, 7], [1, 0.5, 0.3]) rake_decoded [0 if x 0 else 1 for x in rake_output] print(原始数据:, user1_data) print(传统接收机:, normal_decoded[:len(user1_data)]) print(RAKE接收机:, rake_decoded[:len(user1_data)])

更多文章