ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MATLAB跳频通信仿真:从原理到实现的抗干扰通信系统设计

MATLAB跳频通信仿真:从原理到实现的抗干扰通信系统设计 简介本资源是一份面向通信工程、电子信息类本科生的跳频通信课程设计实践材料聚焦跳频图案生成、发射与接收全过程的MATLAB建模仿真解决课程设计中原理理解难、代码实现弱、系统联调缺参考等典型问题。压缩包共3个文件962KB含核心仿真脚本.m、详细原理说明文档.docx及简明使用指引.txt覆盖跳频序列生成、调制映射、信道传输、同步捕获与解调还原等关键环节结构完整、逻辑清晰可直接运行验证跳频通信系统性能。已有129人学习下载项目经导师指导并获评97分高分配套文档包含原理图解、参数设置依据与结果分析要点适合作为期末大作业或课程设计参考大幅降低从理论到仿真实现的学习门槛。1. 项目概述从课程设计到跳频通信的实战演练最近在整理资料时翻出了一个当年做课程设计的老项目——“跳频图案生成及发收的MATLAB仿真”。这个项目对于通信工程、电子信息类专业的学生来说应该不陌生。它不仅仅是完成一份作业更是理解现代抗干扰通信技术核心原理的一把钥匙。跳频技术简单说就是让通信双方按照一个事先约定好的、看似随机的“舞蹈步伐”即跳频图案在多个频率点上快速切换进行通信。敌方如果想干扰或窃听就像试图踩中一个不断变幻位置的舞步难度极大。这个仿真项目就是用MATLAB这个强大的数学工具把教科书上抽象的跳频通信系统从理论公式变成可视化的波形和可分析的性能曲线。如果你正在为类似的课程设计、毕业设计头疼或者是对通信仿真感兴趣的爱好者想亲手搭建一个从信号生成、调制、跳频到解调、分析的完整链路那么这个项目拆解会非常适合你。它不只是一个源码压缩包更是一个理解“通信系统如何对抗干扰”的完整实验框架。接下来我会基于这个项目标题结合我当年踩过的坑和积累的经验带你从头到尾拆解一遍看看如何用MATLAB实现一个可运行、可观测、可评估的跳频通信仿真系统。2. 跳频通信系统核心原理与仿真框架设计2.1 为什么是跳频对抗干扰的通信“游击战”在深入代码之前我们必须先搞清楚跳频通信到底在解决什么问题。传统的通信系统比如早期的电台工作在一个固定的频率上。这就好比两个人始终在一个固定的房间里大声交谈一旦有人在这个房间制造噪音干扰或者躲在门外偷听窃听通信就很容易被破坏或截获。跳频通信的思路则是一种“游击战术”。通信双方手握同一本“密码本”跳频序列按照密码本的指示在很宽的一段频率范围内快速地从一个频率点跳到另一个频率点进行通信。每个频率点上只停留非常短的时间毫秒级。对于干扰方来说他无法预知下一个时刻通信会发生在哪个频率上如果想实施有效干扰就必须用极大的功率覆盖整个频段这通常难以实现。对于窃听方由于不知道跳频图案也无法同步跟上这个快速变化的频率难以截获完整信息。在MATLAB仿真中我们构建的系统模型核心就是模拟这个过程信源 - 调制 - 跳频 - 信道加入噪声和干扰- 解跳 - 解调 - 信宿。仿真的价值在于我们可以在纯净的软件环境中灵活地调整跳频速度跳速、频率集大小、调制方式、干扰类型和强度然后直观地看到系统误码率的变化从而深刻理解各个参数对系统抗干扰性能的影响。2.2 仿真系统顶层架构设计思路一个结构清晰的仿真框架是项目成功的一半。根据我的经验不建议把所有代码堆在一个脚本里。好的课程设计项目应该模块化便于理解和调试。我建议的顶层架构如下主脚本 (main.m或FHSS_Sim.m): 这是仿真的总控制器。它负责设置全局仿真参数如仿真时长、信噪比范围、跳频参数等调用各个子模块函数并最终组织结果绘制图表。跳频图案生成模块 (generate_hopping_pattern.m): 这是跳频系统的“大脑”。负责生成供收发双方同步使用的频率切换序列。常用的方法有基于伪随机序列如m序列、Gold序列生成法或者查表法。这个模块的输出是一个长度固定的序列序列中的每个元素对应一个具体的载波频率索引或频率值。发射机模块 (transmitter.m): 负责完成从信息比特到已调信号的整个过程。包括生成随机信源比特、进行数字调制如BPSK, QPSK、根据跳频图案将基带信号上变频到不同的射频载波上。信道模块 (channel.m): 模拟真实的无线信道环境。主要包括添加加性高斯白噪声AWGN来模拟热噪声还可以选择性加入单频干扰、部分频带干扰等来测试系统的抗干扰能力。接收机模块 (receiver.m): 这是发射机的逆过程。首先它必须使用与发射端完全同步的跳频图案进行“解跳”将接收到的射频信号下变频回基带。然后进行解调将信号还原为比特流。性能评估模块 (ber_analysis.m): 将接收机解调出的比特与原始发送比特进行逐位比较计算误码率BER。通常我们会让仿真在不同的信噪比SNR下运行多次得到一条BER随SNR变化的曲线这是衡量系统性能最关键的指标。可视化模块 (plot_results.m): 将仿真结果以图形呈现。例如绘制跳频图案的时频图频率vs时间、发送与接收信号的时域/频域对比图、系统的误码率曲线等。一图胜千言好的图表能让你的课程设计报告增色不少。注意模块化设计的好处不仅仅是代码清晰。当你需要研究“不同跳频序列对性能的影响”时你只需要替换generate_hopping_pattern.m中的算法想测试“不同调制方式”时也只需修改transmitter.m和receiver.m中的对应部分其他模块完全不用动。这种设计体现了工程思维。3. 核心模块实现细节与MATLAB实操要点3.1 跳频图案生成伪随机序列的妙用跳频图案的核心要求是“伪随机性”和“可重复性”。“伪随机”是指序列看起来是随机的难以预测“可重复”是指收发双方能生成一模一样的序列实现同步。在MATLAB中我们常用线性反馈移位寄存器LFSR来生成m序列它结构简单相关特性好。假设我们有一个包含N个频点的频率集freq_set [f1, f2, ..., fN]。我们需要生成一个长度为L的跳频序列hop_seq序列中的每个值是freq_set的索引。一种典型的实现步骤初始化LFSR寄存器确定寄存器的阶数n例如5阶寄存器可以产生最长31位的m序列。设置一个非全零的初始状态向量比如reg [1 0 0 0 0]。生成m序列根据LFSR的反馈多项式例如本原多项式x^5 x^2 1进行移位和异或操作循环产生一个很长的二进制序列m_seq。映射到频率索引由于m_seq是二进制的而我们需要从N个频点中选择需要将连续的k个二进制位组成一个整数再映射到[1, N]的范围内。k至少需要满足2^k N。例如N8个频点取k3位。每3位二进制数对应一个0-7的十进制数加1后就是1-8的索引。如果生成的十进制数大于N则丢弃或取模取模可能破坏均匀性建议丢弃重取。生成跳频序列重复步骤3直到生成L个有效的频率索引存入hop_seq。% 示例片段基于5阶LFSR生成跳频索引假设N8 function hop_seq generate_hopping_pattern_LFSR(L, N) % L: 跳频序列长度 % N: 频率集大小 n 5; % LFSR阶数 reg [1 zeros(1, n-1)]; % 初始状态 poly [5 2 0]; % 对应 x^5 x^2 1MATLAB通信工具箱用法 % 这里简化演示实际需用循环生成长序列 m_seq lfsr(poly, reg, L*3); % 假设生成足够长的m序列 k ceil(log2(N)); % 每k位映射为一个索引 hop_seq zeros(1, L); idx 1; for i 1:k:length(m_seq)-k1 if idx L, break; end bits m_seq(i:ik-1); decimal_num bi2de(bits, left-msb); % 二进制转十进制 freq_index mod(decimal_num, N) 1; % 映射到1~N % 更严谨的做法是判断decimal_num是否小于N否则跳过保证均匀性 hop_seq(idx) freq_index; idx idx 1; end end实操心得lfsr函数可能需要通信工具箱如果没有可以自己用移位和异或实现一个简单的LFSR。关键点在于跳频序列的“随机性”好坏直接影响抗干扰能力。在课程设计中你可以对比m序列和简单随机数randi生成的序列在存在部分频带干扰时前者的性能通常更优因为其均匀性和相关性更好。3.2 发射机调制与跳频上变频发射机的工作是将数字信息“搭载”到高频载波上并让这个载波按照跳频图案跳舞。我们以最简单的BPSK调制为例。信源生成生成随机的0/1比特流data_bits。BPSK调制将比特0映射为复包络1比特1映射为-1或相反。得到基带信号baseband_signal。跳频上变频这是核心步骤。我们需要为每个符号或每几个符号分配一个载波频率。假设符号周期为Ts跳频周期驻留时间为Th且Th是Ts的整数倍。遍历时间轴以Th为间隔。在每个跳频时段内根据当前时刻对应的hop_seq索引取出频率f_c freq_set(hop_seq(i))。生成该时段内的载波cos(2*pi*f_c*t)。将该时段内的基带信号可能是多个符号与载波相乘实现上变频。信号合成将所有时段的上变频信号拼接起来形成最终的发射信号tx_signal。% 示例片段发射机跳频上变频过程简化版假设一个跳频周期发送一个符号 function tx_signal transmitter(data_bits, hop_seq, freq_set, Ts, Th, Fs) % Fs: 采样频率 num_hops length(hop_seq); symbol_per_hop Th / Ts; % 每个跳频周期发送的符号数 % 1. BPSK调制 modulated_symbols 2*data_bits - 1; % 0- -1, 1- 1 % 扩展符号以匹配跳频时段 total_symbols_needed num_hops * symbol_per_hop; % 这里可能需要处理数据比特长度与需要的符号数不匹配的情况通常补零或截断 % 2. 跳频上变频 tx_signal []; for hop_idx 1:num_hops fc freq_set(hop_seq(hop_idx)); % 当前跳的载频 t_hop (0:1/Fs:Th-1/Fs).; % 当前跳时段的时间向量 carrier exp(1j*2*pi*fc*t_hop); % 复载波便于处理 % 取出当前跳对应的符号 start_idx (hop_idx-1)*symbol_per_hop 1; end_idx hop_idx * symbol_per_hop; symbols_in_hop modulated_symbols(start_idx:end_idx); % 将符号上采样并成型例如矩形脉冲 % 简化处理将每个符号重复成采样点 symbols_upsampled reshape(repmat(symbols_in_hop, Fs*Ts, 1), [], 1); % 确保长度与t_hop匹配可能会有一个采样点误差需处理 sig_len min(length(symbols_upsampled), length(t_hop)); baseband_hop symbols_upsampled(1:sig_len); % 上变频 tx_hop baseband_hop .* carrier(1:sig_len); tx_signal [tx_signal; tx_hop]; end end注意事项这里有一个仿真中极易出错的细节——采样率Fs与载波频率fc的关系。根据奈奎斯特采样定理Fs必须大于2*fc。如果fc是几十MHz甚至更高那么Fs就需要上百MHz这会导致仿真数据量巨大速度极慢。工程仿真中的常用技巧是使用复信号低通等效模型。我们通常将基带信号直接与复载波exp(1j*2*pi*fc*t)相乘其结果是一个复信号其频谱被搬移到了fc附近。在添加噪声和后续处理时我们都用复信号来等效带通信号这样可以大大降低对采样率的要求只需满足信号带宽即可。这是通信仿真中必须掌握的关键概念。3.3 信道模型不只是加噪声在课程设计中很多人只添加AWGN噪声这虽然必要但不够完整。一个更贴近实际、更能体现跳频优势的信道模型应该包括加性高斯白噪声AWGN这是基础模拟无处不在的热噪声。MATLAB中可以用awgn函数方便地添加。rx_signal_noisy awgn(tx_signal, snr_db, measured);参数‘measured’表示先计算输入信号功率再根据指定的信噪比snr_db添加相应功率的噪声。单频干扰Tone Jamming在某个或某几个固定的频率上添加强正弦波干扰。这是检验跳频系统“躲避”能力的最直接方式。t (0:length(tx_signal)-1)./Fs; jamming_signal jamming_amp * exp(1j*2*pi*f_jam*t); % f_jam为干扰频率 rx_signal_jammed tx_signal jamming_signal;部分频带干扰Partial-Band Jamming干扰者将其功率分散在系统总带宽的一部分上。对于跳频系统这意味着有些跳会“中奖”受到强干扰有些跳则相对干净。这种干扰模型下跳频系统的性能优势会更加明显。实操心得在仿真对比时可以设置相同的总干扰功率。对于单频干扰功率集中在一个点对于部分频带干扰功率分散在比如30%的频带上。然后对比两种情况下系统的误码率。你会发现在总干扰功率相同的情况下跳频系统对部分频带干扰的容忍度通常高于单频干扰因为后者只要干扰频率不在跳频集内就完全无效而前者总有部分跳会受到干扰。这个对比实验能非常直观地展示跳频的抗干扰机理。3.4 接收机同步与解调接收机是挑战最大的部分其核心是同步。在理想仿真中我们通常假设“理想同步”即接收机已知跳频图案的起始时间和序列这简化了问题。但在课程设计报告中你必须明确指出这是一个理想假设并讨论非理想同步定时误差、频率误差会带来什么影响。解跳De-hopping接收机使用与发射端相同的hop_seq和freq_set在完全相同的时刻用相反的频率变化进行下变频。具体操作与发射机上变频完全对称将接收到的信号分段每段乘以对应跳频频率的复载波的共轭exp(-1j*2*pi*fc*t)将信号搬回基带。解调对于BPSK解调就是判断基带信号的实部或相位是正还是负。通常先进行匹配滤波如果发射时做了脉冲成型然后在每个符号的最佳采样点进行判决。% 假设已获得解跳后的基带信号 rx_baseband % 匹配滤波如果使用了成型脉冲如根升余弦 % ... % 符号定时同步理想情况下已知采样点位置 sampled_signal rx_baseband(sampling_instants); % BPSK判决 recovered_bits real(sampled_signal) 0; % 假设映射关系为 1-1, 0--1性能评估比较recovered_bits和原始的data_bits计算误码率。num_errors sum(recovered_bits ~ data_bits(1:length(recovered_bits))); ber num_errors / length(recovered_bits);4. 仿真实现中的关键环节与参数设置4.1 时频图的绘制让跳频“看得见”跳频图案的时频图是仿真结果中最直观的展示。它横轴是时间纵轴是频率用一条随时间变化的阶梯线或散点图表示频率的跳变。在MATLAB中我们可以用stairs或plot函数来绘制。function plot_time_frequency_pattern(hop_seq, freq_set, Th, total_time) % hop_seq: 跳频索引序列 % Th: 跳周期 num_hops length(hop_seq); time_edges 0:Th:total_time; if length(time_edges) num_hops 1 time_edges time_edges(1:num_hops1); end frequencies freq_set(hop_seq); % 使用stairs绘制阶梯图 figure; stairs(time_edges(1:end-1), frequencies, LineWidth, 1.5); xlabel(时间 (s)); ylabel(频率 (Hz)); title(跳频图案时频图); grid on; % 或者使用plot绘制更清晰显示跳变点 figure; for i 1:num_hops plot([time_edges(i), time_edges(i1)], [frequencies(i), frequencies(i)], b-, LineWidth, 2); hold on; % 在跳变点画竖线 if i num_hops plot([time_edges(i1), time_edges(i1)], [frequencies(i), frequencies(i1)], r--); end end xlabel(时间 (s)); ylabel(频率 (Hz)); title(跳频图案带跳变瞬间); grid on; hold off; end这张图能清晰地展示出频率随时间伪随机变化的过程。你可以在报告中对比使用不同方法生成的跳频序列的时频图观察其随机性和均匀性。4.2 误码率曲线绘制性能的量化衡量单独一个信噪比下的误码率意义不大。我们需要绘制一条误码率曲线即BER随SNR通常用Eb/N0每比特能量与噪声功率谱密度之比变化的曲线。这需要运行一个蒙特卡洛仿真循环。function run_ber_simulation() % 参数初始化 EbN0_dB_range 0:2:12; % 信噪比范围 num_bits_per_snr 1e5; % 每个信噪比下发送的比特数越多结果越平滑 ber_results zeros(size(EbN0_dB_range)); % 跳频系统参数 hop_seq generate_hopping_pattern(...); freq_set ...; % 主循环 for idx 1:length(EbN0_dB_range) EbN0_dB EbN0_dB_range(idx); num_errors_total 0; num_bits_processed 0; % 可能需要多次平均以减少随机性 while num_bits_processed num_bits_per_snr % 生成数据、调制、跳频、加噪、解跳、解调... % 计算本次仿真的误码数 % ... num_errors_total num_errors_total num_errors; num_bits_processed num_bits_processed length(data_bits); end ber_results(idx) num_errors_total / num_bits_processed; end % 绘图 figure; semilogy(EbN0_dB_range, ber_results, bo-, LineWidth, 1.5, MarkerFaceColor, b); hold on; % 可以同时绘制理论BPSK在AWGN信道下的误码率曲线作为对比 theory_ber 0.5*erfc(sqrt(10.^(EbN0_dB_range/10))); semilogy(EbN0_dB_range, theory_ber, r--, LineWidth, 1.5); xlabel(Eb/N0 (dB)); ylabel(误码率 (BER)); title(跳频通信系统误码率性能); legend(跳频BPSK仿真, 理论BPSK (AWGN)); grid on; end将跳频系统的BER曲线与理论BPSK在AWGN信道下的曲线对比你会发现在理想同步且无干扰的情况下两条曲线应该非常接近。这说明你的跳频仿真链路基本正确。如果存在差距就需要回头检查调制解调、噪声添加或能量计算等环节。4.3 参数设置经验谈仿真参数的设置直接影响结果的合理性和仿真速度。以下是一些经验值和建议参数建议值/设置原则说明与注意事项采样频率Fs至少是信号带宽的4-8倍对于复基带仿真带宽由符号速率和脉冲成型决定。例如符号速率Rs1e6使用滚降系数0.3的根升余弦成型带宽约1.3e6 HzFs可设为5e6或8e6。符号周期Ts1/Rs根据数据速率设定。课程设计中常用1e-6秒1微秒对应1Mbps。跳频周期ThN * Ts(N为整数)通常一个跳频周期包含多个符号。例如Th 10 * Ts表示每跳发送10个符号。跳速越快Th越小抗跟踪干扰能力越强但对同步要求越高。频率集freq_set等间隔分布间隔大于信号带宽例如中心频率1e9 Hz带宽10 MHz频点间隔2 MHz取10个频点。间隔必须足够大避免相邻频道干扰。跳频序列长度L足够长如127, 255使用m序列时长度通常为2^n -1。太短则随机性不足。仿真比特数每个SNR点至少1e5误码率越低需要的比特数越多以保证统计可靠性。例如要仿真到BER1e-4至少需要1e5/1e-4 1e9个比特不现实。通常做法是对于低BER区域如果误码数为0可以记录为 1/N绘图时用向下箭头表示。踩坑记录我曾将Fs设得与符号速率Rs相同导致严重的频谱混叠误码率曲线完全不对。务必牢记仿真中的“时间”是离散的采样点Fs必须满足采样定理。另一个坑是能量计算。awgn函数中的snr_db参数是信噪比SNR但对于数字通信我们更常用Eb/N0。两者关系为SNR Eb/N0 * (比特率/带宽)。如果直接混淆使用会导致曲线横向偏移。在计算理论BER对比时一定要用Eb/N0。5. 常见问题排查与调试技巧实录仿真程序跑不起来或者结果明显不合理是课程设计中最常遇到的情况。下面是我总结的一些排查清单和调试技巧。5.1 频谱分析定位信号异常的第一步当发现误码率奇高无比或者解调出的信号完全不对时第一步不是去死磕代码逻辑而是画图尤其是频谱图。检查发射信号频谱在发射机输出后用fft和plot画出信号的功率谱密度。你应该能看到信号能量集中在以各个跳频频率为中心的频带上。如果频谱形状奇怪比如只有一根线可能是上变频环节出错信号没有被正确调制到载波上。检查信道后频谱在添加噪声和干扰后再次绘制频谱。你应该能看到背景噪声AWGN的平坦谱以及可能存在的干扰尖峰单频干扰。这可以验证你的信道模型是否按预期工作。检查解跳后频谱在接收机解跳之后、解调之前绘制基带信号的频谱。理想情况下无论接收信号在射频端如何跳变解跳后的信号频谱都应该稳定地集中在零频附近。如果解跳后频谱仍然是分散的或偏移的那百分之百是跳频同步出了问题——接收机使用的跳频图案或时序与发射机不匹配。% 简单的频谱绘制函数 function plot_spectrum(signal, Fs, title_str) L length(signal); Y fft(signal); P2 abs(Y/L); P1 P2(1:floor(L/2)1); P1(2:end-1) 2*P1(2:end-1); f Fs*(0:floor(L/2))/L; figure; plot(f/1e6, 10*log10(P1)); % 频率以MHz为单位功率以dB显示 xlabel(频率 (MHz)); ylabel(幅度 (dB)); title(title_str); grid on; end5.2 同步问题排查跳频系统的命门同步失败是跳频仿真失败的最主要原因。请按以下步骤检查序列一致性确保发射机和接收机调用的是同一个generate_hopping_pattern函数并且输入参数种子、长度、频率集大小完全一致。一个简单的调试方法是在两端生成序列后立刻用isequal函数比较一下。时序对齐确保接收机在解跳时时间分段与发射机完全对齐。在理想同步假设下这意味着接收机知道第一跳的开始时间t0。检查你的循环中时间向量t的生成是否从0开始采样间隔1/Fs是否计算准确。一个采样点的错位都可能导致性能急剧下降。载波生成确保发射机的上变频载波exp(1j*2*pi*fc*t)和接收机的解调载波exp(-1j*2*pi*fc*t)中的fc和t在每一跳都是严格对应的。特别注意每一跳的t应该是该跳时段内的局部时间即从0开始而不是全局连续时间。使用全局连续时间可能会导致巨大的相位不连续在解调时引入无法纠正的相位旋转对于BPSK可能还能靠判决方向对于QPSK就彻底乱了。5.3 误码率曲线异常分析如果误码率曲线出现以下情况可以按表排查异常现象可能原因排查方向BER曲线在高SNR时出现平台错误地板存在非噪声引起的恒定错误源。1.干扰检查是否引入了未被跳频避开的固定干扰。2.同步残留误差即使序列对时序可能有微小偏差。3.调制解调映射不一致发射机0-1接收机是否按1-0判决BER曲线比理论曲线差很多整体右移信号能量计算有误或噪声功率添加不准确。1.Eb/N0计算确认awgn函数输入的是SNR还是Eb/N0检查信号功率计算P_sig mean(abs(tx_signal).^2)。2.复信号处理如果使用复信号噪声也应是复噪声实部和虚部独立且功率各为N0/2。awgn函数默认处理复信号。BER曲线在低SNR时比理论好几乎不可能发生除非理论值算错或仿真有误。检查理论BER公式是否正确特别是erfc函数的参数。确认仿真中计算误码时对比的原始比特序列是否完全正确没有错位。BER曲线剧烈抖动不平滑每个SNR点仿真统计的比特数不够。增加num_bits_per_snr。对于低误码率需要仿真极多的比特才能得到稳定统计。可以接受高BER区域点少一些低BER区域用更长的仿真时间。5.4 性能优化与加速技巧MATLAB仿真尤其是蒙特卡洛仿真可能非常耗时。以下技巧可以帮你节省时间向量化操作尽量避免在循环内对长数组进行逐点操作。例如生成载波信号时可以用exp(1j*2*pi*fc * t_vector)一次性生成整个时间向量的载波而不是在循环里逐个计算。预计算和缓存跳频序列、载波信号等不随SNR变化的部分应在主循环外一次性计算好避免重复计算。使用parfor并行循环如果你有多个CPU核心可以尝试用parfor替换for循环来并行计算不同的SNR点。注意变量传递的规则。降低精度快速验证在调试阶段可以先用极少的比特数如1000、较低的采样率、较短的序列跑通整个流程验证逻辑正确性。待逻辑无误后再提高参数进行精确性能仿真。这个跳频通信的MATLAB仿真项目从原理理解、框架搭建、模块实现到调试优化完整地走一遍你对通信系统仿真的掌握会上一个大台阶。它不仅仅是一份课程设计作业更是一个理解复杂系统如何通过模块化建模、分步调试来解决实际问题的经典案例。当你看到自己绘制的时频图清晰地展示出伪随机跳变的规律当你的误码率曲线与理论值完美贴合时那种成就感就是学习工程最好的反馈。本文还有配套的精品资源点击获取
返回列表