尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

MATLAB仿真2ASK、2FSK、2PSK调制解调与误码率对比完整教程

MATLAB仿真2ASK、2FSK、2PSK调制解调与误码率对比完整教程 简介面向通信课程实验的2ASK、2FSK、2PSK调制解调MATLAB仿真工程包内容包含6个M脚本文件整体仅3KB压缩包内代码结构精简覆盖二进制序列生成、信号调制/解调、低通滤波及傅里叶变换等环节适合通信原理初学者对照学习。这套仿真将三种数字调制方式集中呈现通过载波幅度、频率与相位的切换直观展示调制差异同时演示FIR/IIR滤波器在波形平滑与去噪中的作用并借助频域变换帮助理解信号分析路径。各脚本按调制方式独立拆分与滤波器、时频变换工具配合便于按需调用和对比学习。资源已有723人学习下载可作为课堂实验、课程设计或考研复习的快速上手范例读者仿照代码可自行修改参数并观察误码表现从而加深对数字通信系统关键模块的理解。 MATLAB仿真2ASK、2FSK、2PSK调制解调这个项目我最近重新写了一遍。以前总觉得三个调制方式分开写代码太麻烦这次干脆把它们整合到一套仿真框架里统一参数、统一加噪方式、统一误码率统计最后把三种方案的误码率曲线和理论值放在一张图上对比效果完全对得上。这套仿真非常适合作通信原理课程设计、考研复试的动手项目或者刚入门数字通信想找个练手工程的人。读完这篇文章你不光能拿到可运行的MATLAB代码还能知道每个参数为什么这么取解调时哪些细节会让误码率突然变成50%以及怎么把仿真曲线和理论曲线对齐。1. 三种调制方式的原理与性能差异1.1 2ASK用“有载波”和“没载波”传信息2ASK的正式名称是二进制振幅键控最常见的实现就是OOKOn-Off Keying。发二进制“1”的时候发送载波发“0”的时候不发送任何信号。所以接收端只需判断“有没有载波”就能还原出原始比特流。它的优点是实现极其简单缺点是抗噪声性能最差。原因也很直观噪声叠加之后接收端很难判断一个很小的幅度到底是有信号还是纯噪声。从频域上看2ASK信号的带宽是码元速率Rb的2倍也就是2Rb属于线性调制和AM有直接的血缘关系。1.2 2FSK用频率变化传信息2FSK在工程上更常见蓝牙、物联网里都有它的变体。它的思路是准备两个不同频率的载波发“0”用一个频率f1发“1”用另一个频率f2。接收端判断“当前收到的是哪个频率”就能解调出数据。有意思的是2FSK在解调时可以采用非相干方式也就是通过包络检波或者过零检测来区分两个频率不需要本地恢复载波。这在工程上意味着接收机可以做得更简单、更便宜。它的代价是频带利用率比较低带宽等于|f2 - f1| 2Rb频率间隔越大占用带宽越大。1.3 2PSK用相位跳变传信息2PSK也叫BPSK是三种方式中抗噪声性能最好的。它用双极性基带信号-1和1去骑载波相位发“0”对应相位0发“1”对应相位π或者反过来。接收端相干解调时只需要看解调后的基带电压是正还是负。但2PSK有一个著名的坑“倒π现象”。如果接收端恢复的本地载波和发送端反相那么所有判决结果都会取反也就是0判成1、1判成0。实际系统中普遍用2DPSK差分编码BPSK来解决这个问题不过那是后话仿真阶段通常假设本地载波完全同步。1.4 三种方式一张表看明白调制方式信息载体信号表达式特征带宽典型解调方式误码率性能2ASK载波幅度单极性基波 × 载波2Rb相干/包络检波最差2FSK载波频率频率随码元切换|f2-f1| 2Rb非相干包络检波中等2PSK载波相位双极性基波 × 载波2Rb相干解调最好从误码率公式看三者本质都是0.5*erfc(sqrt(k*r))的形式区别只在系数k2PSK的k12FSK的k0.52ASK的k0.25。这就是为什么在同一个误码率图上2PSK曲线永远在最左边2FSK次之2ASK最差。2. 仿真参数设计为什么这么取值2.1 参数选择背后的逻辑我在仿真里用了这样一组参数码元速率Rb1000bps采样率Fs100kHz载频fc10kHz2FSK的两个载频分别取10kHz和20kHz。很多初学者会疑惑为什么采样率非要取这么高每个码元采100个点是不是太浪费了答案是为了给滤波留足空间。采样率在数字信号处理里不只是“够用就行”它决定了频率分辨率和滤波器设计的灵活度。如果每个码元只采10个点那么低通滤波器的过渡带必须非常陡峭阶数高、时延大仿真跑起来特别慢。取100kHz之后2kHz基带信号和20kHz的二倍频分量之间隔得非常远一个16阶FIR滤波器就能轻松分开。再看载频为什么取10kHz。它必须远大于码元速率否则调幅信号的上、下边带会重叠频谱混叠之后没法解调。10kHz相对于1kbps的基带信号来说上边带是9k11kHz下边带是-11k-9kHz所有频谱分量都在正半轴分得很清楚。2.2 噪声模型用Eb/N0而不是信噪比通信系统仿真里判断性能的标准不是普通意义的信噪比SNR而是每比特能量Eb与噪声功率谱密度N0的比值写做Eb/N0。原因很简单不同调制方式下每个码元携带的能量不同只有用Eb/N0才能公平对比它们的误码率性能。计算过程不复杂先生成已调信号tx计算每比特能量Eb mean(tx.^2) * sps其中sps是每个码元的采样点数根据目标Eb/N0反推单边噪声功率谱密度N0 Eb / (10^(EbN0_dB/10))生成零均值高斯白噪声方差取N0 * Fs / 2叠加到信号上。这里最容易被忽略的是方差系数。很多人直接用sqrt(N0)*randn结果误码率曲线和理论值对不上。要记住实信号对应的是双边功率谱所以噪声方差要除以2。这个点在下面调试记录里还会重点讲。2.3 总体仿真流程整个仿真分成五步随机生成二进制信源、把比特流映射成NRZ基带信号、调制到载波上、在信道中叠加高斯白噪声、分别用三种解调器恢复比特流并统计误码率。整个过程在同一个for循环里跑遍历不同的Eb/N0值最后把仿真误码率和理论误码率画在同一张图上。3. 调制端实现从信源到已调波形3.1 信源生成与NRZ映射仿真第一步是生成随机二进制序列。为了让实验结果可复现一定要先设置随机种子rng(0); N 2000; % 码元数量 data randi([0 1], 1, N);接下来把二进制序列映射成NRZ基带波形。2ASK需要单极性NRZ也就是0和12PSK需要双极性NRZ也就是-1和12FSK则只在选择频率时需要用到原数据。用repelem函数把每个码元扩展成sps个采样点得到连续基带波形sps Fs / Rb; % 每个码元采样点数100 uni data; % 单极性0/1 bip 2*data - 1; % 双极性-1/1 uni_up repelem(uni, sps); bip_up repelem(bip, sps);3.2 三种已调信号的生成生成载波后三种调制几乎就是一行乘法或者一行索引的事t (0:length(uni_up)-1) / Fs; % 2ASK单极性基带 × 载波 ask_tx uni_up .* sin(2*pi*fc*t); % 2PSK双极性基带 × 载波 psk_tx bip_up .* sin(2*pi*fc*t); % 2FSK频率按码元切换 freq_dev fc1 (fc2 - fc1) * repelem(data, sps); fsk_tx sin(2*pi*cumsum(freq_dev)/Fs);2FSK这行代码值得单独解释一下。网上很多版本的脚本写的是sin(2*pi*freq_dev.*t)从数学角度这个表达式没有问题但放在仿真里会有一个隐藏缺陷它在每个码元边界处不保证相位连续。实际FSK信号在频率切换时相位如果发生跳变会带来额外的频谱泄漏仿真结果不好看。用cumsum(freq_dev)/Fs实际上是对瞬时频率做积分得到连续的相位值这样生成的2FSK就是连续相位FSKCPFSK更接近真实工程中的FSK信号。3.3 生成波形后怎么验证没错调制写完别急着加噪声先把时域波形画出来看几眼。我通常取前20个码元用subplot把ask_tx、fsk_tx、psk_tx分别画出来。2ASK应该能看到明显的通断包络起伏节奏和比特序列一致2PSK应该在码元边界处看到相位180度跳变幅度恒定2FSK则像两个不同周期正弦的交替拼接。如果这三点都符合说明调制端没问题可以继续往下走。4. 解调端实现滤波器、判决与延迟补偿4.1 相干解调的公共步骤2ASK和2PSK的相干解调流程几乎一样都是先乘本地载波再低通滤波最后抽样判决。区别只在于判决门限。乘法器的本质是频谱搬移。已调信号乘上本地载波之后会在零频附近出现基带分量同时在二倍频载波附近出现高频分量。低通滤波器把高频部分滤掉留下的就是携带信息的基带波形。这里有个小技巧乘的本地载波如果是sin(2*pi*fc*t)低通之后的信号幅度会缩水一半。所以代码里推荐乘2*sin(2*pi*fc*t)把幅度补偿回来后面判决门限更好设。滤波器我推荐用designfilt函数直接设计比手写窗函数方便得多lp designfilt(lowpassfir, FilterOrder, 64, ... CutoffFrequency, 1200/(Fs/2));截止频率取1200Hz因为基带信号主瓣带宽是1kHz而二倍频分量在20kHz留出1200Hz的截止带绰绰有余。如果把这句换成FilterOrder16你会发现包络的上升沿变缓眼图睁开度变小误码率也会变差。4.2 2ASK和2PSK的判决区别抽样判决是解调过程中最容易出问题的一步。2ASK的基带波形理论上在0和1之间跳动所以判决门限可以取0.5。实际仿真时由于滤波器非理想、噪声干扰波形幅值会有波动。稳妥的做法是先观察解调后的基带波形再决定门限。代码里可以直接用中值逼近hat_ask base_ask(idx) 0.5 * max(base_ask);2PSK的基带波形理论上在-1和1之间跳动判决门限是固定的0大于0判“1”小于0判“0”不用任何调节。这也是BPSK在实现上特别优雅的原因之一。4.3 2FSK的非相干包络检波2FSK我用的是非相干解调结构上比相干解调简单两路带通滤波器各自提取对应频率的分量再分别取包络比较哪一路的包络大就判成哪个码元。求包络最简单的方式是希尔伯特变换bp1 bandpass(fsk_tx, [9500 10500], Fs); bp2 bandpass(fsk_tx, [19500 20500], Fs); env1 abs(hilbert(bp1)); env2 abs(hilbert(bp2)); hat_fsk env2(idx) env1(idx);这里带通滤波器的中心频率分别对准10kHz和20kHz。2FSK之所以非相干解调也能工作就是因为两路载频隔得足够远互不干扰。如果f1和f2只差几百赫兹带通滤波器就很难把它们分开包络检波基本就废了。4.4 滤波器延迟补偿这是最大的坑调试中遇到最诡异的一个问题所有代码看起来都对误码率却在某些信噪比下高达0.5就像没收到任何信息一样。后来排查发现问题出在滤波器延迟上。任何FIR滤波器都会引入群延迟设计好的低通滤波器通常延迟约等于滤波器阶数的一半也就是32个采样点。如果抽样判决时还用原来的位置去采样采到的就是前一个码元的尾巴判决结果自然全乱。正确做法是在抽样位置索引里加上延迟量delay 32; idx (0:N-1)*sps sps/2 1 delay;想精确获取延迟量可以用grpdelay(lp)函数查询。如果不想手动算延迟也可以整个基带信号用circshift或者直接截取保证抽样点落在码元中点附近。5. 误码率统计与新手最容易踩的坑5.1 理论误码率公式怎么写仿真造完最后一步是统计误码率并且和理论值对比。三种调制在相干解调下的理论比特误码率公式前面已经提到过直接写成MATLAB代码r 10.^(EbN0_dB/10); theory_ask 0.5*erfc(sqrt(r/4)); theory_fsk 0.5*erfc(sqrt(r/2)); theory_psk 0.5*erfc(sqrt(r));如果是2FSK的非相干解调理论公式要换成指数形式0.5*exp(-r/2)这一点容易混淆。画图时用semilogy对数坐标横轴是Eb/N0纵轴是误码率BER。三条仿真曲线和三条理论曲线重合度越高说明整个链路做得越准。5.2 仿真与理论对不齐先排查这三个地方我自己在反复调试中总结了一个清单遇到曲线对不上就按顺序排查噪声功率算错。这是最高频的错误忘了除以2或者把Eb算成所有信号能量再除码元数都会让曲线整体平移几个dB。校验方法很简单固定一组Eb/N0值多次重复实验看仿真误码率是否稳定如果每次差异巨大多半是噪声功率不对或者码元数太少。抽样位置不对。滤波器延迟不补偿、抽样点落在码元边缘误码率会急剧恶化。把解调后的基带波形画出来再把抽样点标在波形上一眼就能看出来有没有踩在最佳位置。码元数太少。N200时低误码率区域的统计波动非常大比如理论误码率是1e-4而实际统计只有200个码元运气好一个错误都没有运气差可能碰到5个错误。建议至少设成N5000低频段比较稳。如果追求精确可以跑到1e5。5.3 波形、眼图和实测数据我最后跑出来的数据和理论曲线基本吻合。在Eb/N010dB时2PSK的仿真误码率在1e-4左右2FSK在1e-3左右2ASK在1e-2左右三条曲线正好拉开3dB左右的间距。这个间距本质上是三种调制方式在欧氏距离上的差别距离越远抗噪声能力越强。做课设的时候我强烈建议在仿真脚本最后加上眼图的绘制eyediagram(base_ask, sps * 2);眼图能直观看出滤波器的码间串扰程度和噪声容限。眼图中央睁开得越大、交叉点越细代表解调质量越好。这个图放进报告里比纯文字描述“性能良好”有说服力得多。另一个加分项是把三种调制的功率谱密度画在一起。用pwelch函数分别估计信号功率谱既能看到2FSK确实比2ASK和2PSK占用更多带宽也能验证理论带宽公式。如果学有余力我还建议再往这个项目里加一个模块升余弦脉冲成型。现在的基带波形是矩形脉冲频域旁瓣很大现实中不会这样直接发出去。使用升余弦滤波器对NRZ波形进行成型之后频谱会变得紧凑同时增加眼图的判断复杂度。加完成型滤波器再跑一次误码率你会发现整个仿真更接近真实通信系统的链路结构。这也是面试时一个很好的进阶亮点。本文还有配套的精品资源点击获取
返回列表