资讯详情 2FSK调制解调MATLAB仿真:参数、眼图与误码率
📅 2026/10/31 16:30:59
简介这份面向通信原理课程设计学习者的2FSK调制解调系统设计文档聚焦MATLAB7.0环境下的数字通信链路仿真与课程设计报告撰写。内容围绕二进制随机信源、开关法2FSK调制、加性高斯白噪声信道、相干解调及抽样判决展开涵盖发送滤波、接收滤波与信宿等模块并给出源程序与仿真波形可用于观察调制信号、信道叠加噪声后的波形及解调眼图绘制信噪比与误码率曲线完成系统性能评价。压缩包仅含1个doc文件约579KB适合直接查阅课程设计结构、参数设置与仿真思路。已有855人学习可作为通信原理课程设计、MATLAB仿真入门和2FSK调制解调实验的参考帮助读者理解开关法调制与相干解调的模块划分、关键参数及性能分析方法。1. 为什么课程设计里 2FSK 总翻车这套 MATLAB 仿真能交付什么2FSK 调制与解调系统设计与仿真这个题目在通信原理课程设计里出镜率极高但真正一次跑通的人不多——大部分时间不是卡在理论上而是卡在 MATLAB 的参数对不上载频、采样率、频偏、信噪比折算四个数随便错一个波形和误码率曲线就全歪。这套基于 MATLAB 7.0 的完整链路覆盖信源产生、2FSK 调制、加性高斯白噪声信道、带通滤波、相干与非相干两路解调、抽样判决、眼图观测和误码率统计解决的问题很具体把书本上那两张原理图变成能出波形、能出眼图、能出 SNR-BER 曲线的可执行脚本。它适合两类人正在做通信原理课设、需要交一份「有波形有数据有对比」的报告以及已经会调 dmod/ddemod、但画出来的误码率曲线明显不符合理论趋势想回头找原因的人。下面按建模、搭链路、统计、排坑、进阶的顺序拆开讲每个参数为什么这么取都会说清楚。2. 开关法建模两个载频、三个采样率参数怎么互相卡死2.1 开关法与调频法的相位差异会咬到哪一步2FSK 信号的产生有两条路。调频法用一个压控振荡器载波频率随基带信号在 f1 和 f2 之间连续变化相邻码元交界处相位连续本质上是 CPFSK开关法用两个独立的振荡器分别产生 f1 和 f2由基带矩形脉冲控制开关选择输出两个码元交界处相位一般不连续跳变多少取决于两路振荡器当时的瞬时相位。这套设计选开关法不是因为它更好而是因为它和代码对得上。MATLAB 通信工具箱里的dmod(...,fsk,M,df)内部就是把符号映射成两个频率分量再拼接属于典型的频率切换你拿它跑出来的就是开关法的波形。任务书里要求「键控法产生 2FSK」两者正好一致报告里写「采用开关法相邻码元相位不一定连续」才算自洽。反过来说如果任务书写的是「相位连续」就不能直接拿dmod的fsk交差得自己按每个码元累加相位 2πfT 重写调制否则答辩时被追问「你的连续相位体现在哪一段代码」会答不上来。相位不连续带来的实际后果落在相干解调的低通输出上。本地恢复的 cos(2πf1t) 与接收信号相乘后低通输出是一个受相位差影响的量码元边界的相位跳变会让这个量出现一段瞬态。只要抽样判决时刻落在码元中点、也就是眼图张开最大的位置瞬态还没蔓延到判决点误码率就不会因此崩掉。但如果你把抽样时刻设偏或者用自己手写的积分清零式判决器而没做定时对齐就会看到眼图迹线糊成一片、误码率莫名飙高——这条在后面排查章节里还会出现。另外选开关法有个隐藏好处它让「2FSK 可以看作两路不同载频的 ASK 叠加」这个结论变得直观。相干解调的两条支路本质上就是两个中心频率不同的 ASK 接收机各自乘本振、低通、抽样最后比大小。理解到这个层面后面调带通滤波器的中心频率和带宽时就不用死记参数了。2.2 采样率、载频、码速率三个数定死之前先算约束这套代码里最容易被忽略、又最容易出事的一组参数是Fc10、Fs40、Fd1。三个数看着随便填其实互相卡得很紧参数取值物理含义隐含约束Fc10 Hz标称载频Fc ± df/2 必须低于 Fs/2Fs40 Hz系统采样率Fs/Fc 建议不低于 8Fd1 Hz码速率 Rb决定射频带宽下限N Fs/Fd40每码元采样点数影响 awgn 折算与眼图迹线数df10 Hz两载频间隔决定正交性与占用带宽M2进制数固定为二进制先看 Fs/Fc 4也就是一个载波周期只有 4 个采样点。这是能画出「看起来像正弦」的绝对下限plot出来已经接近折线想让你报告里的调制波形经得起看最好把 Fs/Fc 提到 8 以上。很多人的波形图被质疑「这不是正弦」根子就在这里改 Fs 或者降 Fc 都能解决但降 Fc 会连带压缩可用带宽通常还是提 Fs 更省事。再看 Fc/Fd 10也就是一个码元内包含 10 个完整的载波周期。这个比值决定了「频率」这个概念在单个码元内是否成立如果每码元只有一两个载波周期频率切换在时域上就退化成相位突变频谱完全糊掉带通滤波器也没法把 f1 和 f2 分开。工程上一般要求每码元至少 5 个载波周期10 是个舒服的取值。最后是 Fs/Fd N 40每码元 40 个采样点。这个数不只是画图好看它还直接进入后面awgn的信噪比折算公式改了这个值而忘了改折算项整条误码率曲线就会整体平移。2.3 频偏 df 的取值正交间隔与混叠边界dmod的fsk模式里df是两个载频之间的间隔实际使用的两个频率是Fc - df/2和Fc df/2。代进这套参数f1 5 Hz、f2 15 Hz。而奈奎斯特频率是 Fs/2 20 Hzf2 距离边界只剩 5 Hz 余量2FSK 的射频带宽粗估为 |f2-f1| 2Rb 12 Hz上边沿顶到 16 Hz 附近勉强没越界。这就是为什么 df 不能随手填大填到 16f2 就变成 18 Hz双边带直接折返混叠误码率曲线会在某个 SNR 之后压平不降看着特别像「仿真坏了」。另一个约束是正交性。相干解调要求两个频率的间隔是 1/(2Tb) 的整数倍非相干解调要求是 1/Tb 的整数倍。Tb 1/Fd 1 s所以相干要求 df 是 0.5 的整数倍、非相干要求 df 是 1 的整数倍。df 10 同时满足两者这也是这套参数能让相干和非相干两条支路共用同一组载频设置、直接对比的前提。如果 df 取 8 或 9非相干支路的正交性就破了你会发现非相干解调的误码率反而比相干还低那不是算法厉害是参数没配对。下面这段自检脚本建议放在主程序最前面跑一遍比事后看波形猜原因省事得多% 2FSK 参数自检混叠、每码元周期数、正交间隔 Fc 10; Fs 40; Fd 1; df 10; f1 Fc - df/2; f2 Fc df/2; fprintf(f1%.2f Hz, f2%.2f Hz, Nyquist%.2f Hz\n, f1, f2, Fs/2); assert(f2 Fs/2, f2 越过奈奎斯特频率必然混叠请增大 Fs 或减小 df); fprintf(每码元载波周期数 Fc/Fd %.1f\n, Fc/Fd); fprintf(每载波周期采样点数 Fs/Fc %.1f\n, Fs/Fc); B abs(f2-f1) 2*Fd; % 2FSK 射频带宽粗估双边 fprintf(射频带宽约 %.2f Hz上边沿约 %.2f Hz\n, B, f2 Fd); Tb 1/Fd; fprintf(df/(1/(2Tb)) %.2f 相干解调应接近整数\n, df/(1/(2*Tb))); fprintf(df/(1/Tb) %.2f 非相干解调应接近整数\n, df/(1/Tb));这段脚本干的事就是把你脑子里的三个约束变成可执行的断言。assert那一行是后悔药混叠一旦发生后面所有波形和曲线都白跑早点报错比事后对着一条压平的 BER 曲线发呆强。输出里的两个比值如果明显偏离整数就说明正交性破了要么改 df要么换解调方式。参数说明方面Fc/Fd控制在 5 到 20 之间、Fs/Fc不低于 8、f2 Fd Fs/2这三条守住链路基本不会出结构性错误。3. 从 dmod 到 ddemod把调制解调链路串起来的五段脚本3.1 信源与基带波形randsrc 与单极性矩形波信源部分要交两样东西二进制随机序列本身和它对应的单极性矩形基带波形。原始代码里只画了stem杆图那是符号级的序列不是基带波形报告里如果只有杆图「数字基带信号采用单极性矩形波」这条要求其实没满足。补上rectpulse做零阶保持一个码元重复 N 个采样点才是真正的矩形波M 2; % 二进制调制 numSymb 25; % 用于波形展示的码元数 Fs 40; Fd 1; Fc 10; df 10; N Fs/Fd; % 每码元采样点数 40 x randsrc(numSymb,1,[0:M-1]); % 0/1 等概随机序列 baseband rectpulse(x, N); % 零阶保持得到单极性矩形波 t_bb (0:length(baseband)-1)/Fs; figure(1); subplot(2,1,1); stem(0:numSymb-1, x, bx); axis([0 numSymb-1 -0.2 1.2]); title(二进制随机序列); xlabel(Symbol Index); ylabel(Amplitude); subplot(2,1,2); plot(t_bb, baseband, LineWidth, 1.2); axis([0 10 -0.2 1.2]); title(单极性矩形基带信号前 10 码元); xlabel(Time (s)); ylabel(Amplitude);randsrc的第三个参数[0:M-1]表示从 0 到 M-1 等概取值这里就是 0 和 1。rectpulse是通信工具箱里的零阶保持函数第二个参数是每个符号的重复次数必须等于Fs/Fd否则时间轴和采样率对不上波形图横坐标就是假的。numSymb 25只适合截图不适合做误码率统计这一点在下一章会展开。如果你手上没有通信工具箱baseband reshape(repmat(x,N,1),[],1)能达到同样效果只是可读性差一点。3.2 调制与信道dmod 的频偏参数与 awgn 的电平折算调制这一步就是一行dmod没什么花活但它的输出长度、时间轴构造方式、以及后面加噪的功率折算是三个容易出错的地方% 2FSK 调制键控法f1 Fc-df/2f2 Fcdf/2 y dmod(x, Fc, Fd, Fs, fsk, M, df); numPlot 15; % 只画前 15 个码元避免横轴过密 numModPlot numPlot * Fs; % 对应采样点数 t (0:numModPlot-1)/Fs; % 仿真时间轴 figure(2); plot(t, y(1:numModPlot), b-); axis([0 max(t) -1.5 1.5]); title(2FSK 调制后的信号); xlabel(Time (s)); ylabel(Amplitude); % 加入加性高斯白噪声 SNRpBit 8; % 每比特信噪比 Eb/N0 (dB) SNR SNRpBit / log2(M); % 折算成每符号信噪比M2 时相同 seed [12345 54321]; randn(state, seed(2)); % 固定噪声种子保证可复现 y_noisy awgn(y, SNR - 10*log10(0.5) - 10*log10(N), measured, [], dB); figure(3); plot(t, y_noisy(1:numModPlot), b-); axis([0 max(t) -1.5 1.5]); title(加入高斯白噪声后的已调信号); xlabel(Time (s)); ylabel(Amplitude);dmod的调用形式是dmod(x, Fc, Fd, Fs, fsk, M, df)七个参数依次是符号序列、标称载频、码速率、采样率、调制方式、进制数、频率间隔。第七个参数df是最容易漏的漏了会报参数个数错误填错则直接影响上一节算好的正交性。真正需要解释的是awgn那一行里的两个修正项。SNRpBit是每比特信噪比单位 dB10*log10(0.5)对应 2FSK 把功率分摊到两个频率分量上单个支路的功率只有总功率的一半10*log10(N)是把每符号信噪比折算到每个采样点上因为awgn是按采样点加噪的。两个修正项合起来才是「给定 Eb/N0实际该往每个采样点上加多少噪声」。这两个项在 MATLAB 官方示例里是成套出现的但一旦你改了Fs、Fd或者调制方式就必须跟着重算照抄别人的数字是曲线整体平移的头号原因。randn(state, ...)这行在旧版本里用于固定噪声随机种子新版 MATLAB 已改为rng(seed)。固定种子的意义在于调参数的时候误码率不会因为随机噪声本身波动而在 1e-2 和 1e-3 之间乱跳你能确定变化是参数引起的。3.3 相干与非相干解调ddemod 的两种调用与眼图解调部分保留两条支路用同一组含噪信号这样报告里的对比才成立% 相干解调本地载波与接收信号相乘 - 低通 - 抽样判决 figure(4); z1 ddemod(y_noisy, Fc, Fd, Fs, fsk/eye, M, df); title(相干解调后的眼图); % 非相干解调带通 - 包络检波 - 抽样判决 figure(6); z2 ddemod(y_noisy, Fc, Fd, Fs, fsk/eye/noncoh, M, df); title(非相干解调后的眼图); % 原序列与两路解调结果的逐位对比 figure(5); stem(0:numPlot-1, x(1:numPlot), bx); hold on; stem(0:numPlot-1, z1(1:numPlot), ro); hold off; axis([0 numPlot-1 -0.5 1.5]); legend(原输入序列,相干解调输出); title(相干解调结果与原序列对比); figure(7); stem(0:numPlot-1, x(1:numPlot), bx); hold on; stem(0:numPlot-1, z2(1:numPlot), ro); hold off; axis([0 numPlot-1 -0.5 1.5]); legend(原输入序列,非相干解调输出); title(非相干解调结果与原序列对比);ddemod的第一个参数是接收信号后面依次是载频、码速率、采样率、解调方式字符串、进制数、频率间隔。字符串fsk/eye表示相干解调并额外画出眼图fsk/eye/noncoh表示非相干解调加眼图/eye这个后缀只是让函数顺手画一张眼图不改变解调算法本身。眼图的作用是给你一个定时质量的直观判据迹线张开得越宽抽样余量越大如果迹线糊成一条带说明定时或滤波出了问题这时候再看误码率就没意义了。两个细节值得注意。一是ddemod的输出长度和输入符号数一致但内部有滤波器延迟前几个符号可能因为瞬态被判错统计误码率时如果发现错误集中在开头几个位置那是滤波器群时延导致的不是算法错。二是相干解调需要接收端知道确切的载波相位仿真里ddemod默认本地载波与发射端严格同相这是理想假设真实系统里要靠载波恢复电路会引入相位误差这个差别在报告里最好点一句显得你知道边界在哪。4. 误码率曲线25 个码元统计不出 1e-3要扫多少才算数4.1 单点 symerr 的分辨率问题原始代码里numSymb 25然后[errorSym, ratioSym] symerr(x, z1)。这个写法本身没错但 25 个码元能给出的误码率分辨率是 1/25 4e-2也就是最低只能测到 4% 的误码率。如果你在 8 dB 信噪比下测到 0 个错误那不代表误码率是 0只代表错误率低于 4%。报告里把这个数写成「误码率约为 0」是可以的写成「误码率 1e-4」就是编的。要统计到 1e-3 这个量级至少需要 1e5 个码元才能期望出现 100 个错误统计置信度才够看。代价是仿真时间1e5 个码元、每码元 40 个采样点就是 4e6 个采样点dmod和ddemod各跑一遍普通笔记本几秒到几十秒能出结果完全可以接受。所以合理的做法是分工波形图用 15 到 25 个码元图清爽误码率统计单独开一轮用 1e5 个码元不画波形。4.2 SNR 扫描把曲线跑出来单点误码率说服力有限报告里真正撑场面的是 SNR-BER 曲线。做法是把信噪比做成向量循环调制、加噪、解调、统计两路解调各存一条曲线EbN0_dB 0:2:12; % 每比特信噪比扫描范围 numSymb 1e5; % 统计用码元数保证低误码率可分辩 ber_coh zeros(size(EbN0_dB)); ber_non zeros(size(EbN0_dB)); for k 1:numel(EbN0_dB) x randsrc(numSymb,1,[0 1]); y dmod(x, Fc, Fd, Fs, fsk, 2, df); % Eb/N0 - 每采样点 SNR双频功率减半 过采样增益 snr_samp EbN0_dB(k) - 10*log10(0.5) - 10*log10(N); y awgn(y, snr_samp, measured, [], dB); z1 ddemod(y, Fc, Fd, Fs, fsk, 2, df); % 相干 z2 ddemod(y, Fc, Fd, Fs, fsk/noncoh, 2, df); % 非相干 [~, ber_coh(k)] symerr(x, z1); [~, ber_non(k)] symerr(x, z2); fprintf(Eb/N0%2d dB BER_coh%.3e BER_non%.3e\n, ... EbN0_dB(k), ber_coh(k), ber_non(k)); end figure(8); semilogy(EbN0_dB, ber_coh, bo-, EbN0_dB, ber_non, rs-, LineWidth, 1.2); grid on; xlabel(E_b/N_0 (dB)); ylabel(BER); legend(相干解调,非相干解调,Location,southwest); title(2FSK 误码率随信噪比变化曲线);循环体里只有一处需要你根据自己参数改的就是snr_samp那一行。-10*log10(0.5)对应双频分路、-10*log10(N)对应过采样这两个修正项和 3.2 节完全一致改参数时两边要同步改否则单点图和曲线图会互相矛盾。semilogy是对数纵轴误码率跨几个数量级时必须用它线性轴上看不出低信噪比段的差异。运行时会看到低信噪比段两路误码率都接近 0.5那是正常的信噪比太低时判决基本等于掷硬币。真正有信息量的是曲线开始下弯的那一段以及两条曲线之间的间距。4.3 叠上理论曲线判断仿真对不对的唯一标准仿真曲线画出来只是一半能不能站住要看它和理论值贴不贴。2FSK 的两条理论公式可以直接用qfunc算EbN0 10.^(EbN0_dB/10); % dB 转线性 ber_th_coh qfunc(sqrt(EbN0)); % 相干 2FSKQ(sqrt(Eb/N0)) ber_th_non 0.5 * exp(-EbN0/2); % 非相干 2FSK0.5*exp(-Eb/(2N0)) figure(9); semilogy(EbN0_dB, ber_coh, bo, EbN0_dB, ber_th_coh, b-, ... EbN0_dB, ber_non, rs, EbN0_dB, ber_th_non, r-); grid on; xlabel(E_b/N_0 (dB)); ylabel(BER); legend(相干-仿真,相干-理论,非相干-仿真,非相干-理论,Location,southwest);相干 2FSK 的理论误码率是 Q(sqrt(Eb/N0))非相干是 0.5·exp(-Eb/(2N0))。这两条式子在大信噪比下大约差 1 dB 量级的信噪比也就是说同样要达到 1e-4 的误码率非相干解调要多花约 1 dB。如果你跑出来的两条仿真曲线间距远大于这个数或者仿真点系统性地偏离理论线几个 dB那基本可以判定是信噪比折算写错了而不是「我的系统性能特别好」。另一个判据是曲线的斜率。理论和仿真在对数坐标下应该近似平行如果仿真曲线在高信噪比段突然变平那是碰到了分辨率下限码元数不够或者出现了混叠。把numSymb提到 1e6 再看如果曲线继续往下走就是分辨率问题如果不走回头查 2.3 节的assert。5. 踩坑排查五条从波形到误码率的翻车记录5.1 波形与滤波器环节的两次翻车坑一调制波形画出来像三角波被质疑「这不是正弦」。现象是figure(2)里的已调信号边缘笔直、峰值尖锐完全看不出正弦的形状。原因只有一个每个载波周期的采样点太少。原始参数 Fs/Fc 4一个周期四个点plot用直线把点连起来出来的当然是折线。解决办法是把Fs提到 160 或把Fc降到 5保证 Fs/Fc 不低于 8后者会连带压缩可用带宽通常选前者。改完记得同步改N Fs/Fd和awgn里的10*log10(N)这两处是联动的只改一处会让波形好看但误码率错。坑二Simulink 里带通滤波器一加解调波形严重失真。现象是滤波后的信号幅度忽大忽小、包络畸变判决输出成片出错。常见原因有三个带通中心频率没对准 f1 和 f2带宽取得比码速率还窄把有用边带削掉了滤波器阶数给得太高群时延陡变导致码元间干扰。解决思路是先按 f1、f2 分别设两个带通中心频率精确对齐带宽取 2 倍码速率左右阶数控制在 4 到 6 之间然后在滤波器输出端接一个示波器看波形有没有明显拖尾。如果拖尾严重说明群时延没补偿可以在判决前加一段延时对齐或者在报告里明确说明这是滤波器引入的固定延迟。这一条是血泪经验滤波器参数不是越陡越好阶数上去了时域拖尾会让你怀疑人生。5.2 信噪比与判决环节的三次翻车坑三误码率曲线在高信噪比段压平怎么加码元都不降。现象是曲线降到 1e-2 附近就横住了和理论线明显分叉。原因大概率是混叠df取大了f2 Fc df/2 逼近甚至越过 Fs/2两个频率分量的边带折返回来互相污染这时候再怎么提信噪比都没用因为干扰不是噪声而是自己的镜像。解决办法是跑 2.3 节那段自检脚本确认 f2 Fd 小于 Fs/2不满足就提高 Fs 或者减小 df同时回头检查 df 是否还满足正交间隔的整数倍要求。这个坑的迷惑性在于波形图看着挺正常只有误码率曲线会露馅。坑四仿真曲线整体比理论线偏移好几 dB但形状完全对。现象是两条曲线平行只是横向平移说明算法没问题、功率标定错了。原因基本锁定在awgn的修正项上换了Fs、Fd、M或者调制方式之后-10*log10(0.5)和-10*log10(N)没有跟着重算或者从别处抄来的示例里这两个系数根本对应不同的调制体制。解决办法是把折算公式重新推一遍或者干脆用awgn(y, SNR, measured)让函数自己测功率先确认量级对不对再回头用解析折算做精调。判断是否属于这个坑有个简单办法看偏移量是不是恰好等于某个 10*log10 的整数倍是的话几乎可以确定。坑五Simulink 的误码率计算模块一直报错调不出来。现象是 Error Rate Calculation 模块提示维度不匹配或采样率不一致换了几种接法都不行。原因通常是收发两路的信号采样率不同一路是符号率、一路是采样率或者模块的延迟参数没设、把收发序列错位对齐了。这个问题在图形化环境里排查成本很高因为它不告诉你哪一位错了。比较务实的做法是放弃在 Simulink 里算误码率用 To Workspace 模块把发送序列和判决输出导出到工作区在脚本里用symerr算几行代码的事还能顺便画曲线。我自己遇到这类模块报错一般不在图形界面里死磕直接退回脚本层可控性高得多。6. 进阶升余弦滤波与眼图让报告里的曲线站得住链路跑通、曲线出来之后还有一步能把报告的质量拉开档次在接收端加一级升余弦滤波器把带外噪声滤掉同时用眼图证明你的定时是干净的。Delay 3; R 0.5; % 群时延 3 个码元滚降系数 0.5 [yf, tf] rcosine(Fd, Fs, fir, R, Delay); % 设计升余弦 FIR [yo2, to2] rcosflt(y_noisy, Fd, Fs, filter, yf); % 对含噪信号滤波 figure(10); plot(t, y_noisy(1:numModPlot), r-); hold on; plot(to2, yo2, b-); hold off; axis([0 30 -1.5 1.5]); legend(含噪已调信号,升余弦滤波后); title(升余弦滤波前后波形比较); xlabel(Time (s)); ylabel(Amplitude); eyediagram(yo2(1:200*N), N); % 每屏 200 码元每 trace N 点 title(升余弦滤波后的眼图);rcosine的第四个参数是滚降系数 R取 0.5 是个折中R 越小频谱越陡、频带利用率越高但时域拖尾越长对定时误差越敏感R 接近 1 时拖尾短、鲁棒但占用带宽翻倍。做课设报告0.5 足够交差真要论证可以扫 0.2、0.5、0.8 三组做对比。第五个参数 Delay 是滤波器的群时延单位是码元数取 3 意味着输出会比输入滞后 3 个码元所以to2和t对不齐是正常的画图时不要硬把两条曲线起点拉平那等于人为制造了一个相位错误。eyediagram的第二个参数必须等于Fs/Fd也就是每码元采样点数。这个数填错是眼图糊掉的常见原因填大了一个 trace 里塞进好几个码元迹线互相重叠填小了只显示码元的一部分看不出张开程度。第一段参数200*N控制参与叠加的采样点总数200 个码元叠出来的眼图清晰度和计算量比较平衡。判读眼图就看两点眼睛张开的高度噪声容限和张开的位置最佳抽样时刻两者都正常你报告里的误码率数据才有支撑。从那以后我每次做这类仿真都强制自己先跑一遍参数自检、再跑单点波形、最后才跑扫描曲线顺序反了就会在一条压平的曲线上浪费一整晚。希望帮到你。本文还有配套的精品资源点击获取