资讯动态

MATLAB仿真解析四种数字基带码型:DNRZ、DRZ、SNRZ、SRZ的时域与频域特性

发布时间:2026/8/13 12:57:39 来源:尧图企业网站定制
1. 项目缘起为什么从这四种基本码型开始在数字通信系统里我们常把一串串的“0”和“1”叫做数字基带信号。但计算机里的0和1是逻辑电平没法直接在电缆或空气中传输。所以第一步就是把它们变成实实在在的、看得见摸得着的电信号波形这个过程就是“码型编码”。你可能会觉得这不就是画个方波吗高电平代表1低电平代表0。但实际工程中远没这么简单。信号的能量分布、有没有直流分量、是否方便接收端提取时钟、抗干扰能力如何这些全都和选择的码型息息相关。而双极性不归零码DNRZ、双极性归零码DRZ、单极性不归零码SNRZ和单极性归零码SRZ就是构成这个庞大码型世界的四块基石。几乎所有复杂的、工程中实用的码型比如曼彻斯特码、AMI码其设计思想都能从这四种基本码型里找到影子。搞懂它们不仅是应付考试更是为了在以后设计或调试通信链路时当示波器上出现一个奇怪的波形或者频谱仪上显示能量异常你能立刻反应过来“哦这可能是码型选择不当引起的。”这次我们不空谈理论直接上手MATLAB把这四种码型的时域波形和它们的“身份证”——功率谱密度给画出来。通过仿真你能直观地看到“归零”与“不归零”、“单极性”与“双极性”究竟带来了哪些本质区别。相信我当你亲手运行代码看着波形和频谱图在屏幕上跳出来时那种“原来如此”的感觉比看十遍公式推导都要深刻。2. 仿真前的核心概念拆解别再混淆这些术语动手之前我们必须把四个码型的定义和关键参数掰扯清楚这是后续一切仿真的基础。很多初学者容易在这里犯迷糊。2.1 “单极性”与“双极性”电平的参照系不同这是第一个分水岭核心在于信号幅度是否关于零电平对称。单极性码Unipolar用一种极性的电平来表示二进制信息。通常我们用正电平比如1V或A伏表示二进制“1”用零电平0V表示二进制“0”。它的全部信号幅度都在零轴的一侧通常是正侧。你可以把它想象成“单腿跳”始终在零线以上活动。双极性码Bipolar用两种相反极性的电平来表示二进制信息。通常用正电平A伏表示“1”用负电平-A伏表示“0”。它的信号幅度关于零电平对称。这就像是“正常走路”一步在前正一步在后负。关键点双极性码的“0”不是没信号而是一个负脉冲这是和单极性码最直观的区别。双极性码的直流分量通常很小甚至为零这对于通过变压器耦合或电容耦合的信道非常有利。2.2 “归零”与“不归零”脉冲的“休息”哲学这是第二个分水岭决定了在一个码元周期内电平是否“坚守岗位”。不归零码Non-Return-to-Zero, NRZ在一个码元周期Tb比特间隔内电平保持恒定不变。如果当前是“1”那么在整个Tb时间内都保持高电平如果是“0”则在整个Tb时间内保持低电平单极性或负电平双极性。它很“敬业”从不中途开小差。归零码Return-to-Zero, RZ在一个码元周期Tb内电平只在一部分时间通常是一半时间即 τ Tb/2内保持有效状态然后在周期结束前提前返回到零电平。比如对于“1”它可能在前半个周期是高电平后半个周期就回到0V对于“0”则可能是前半个周期是低或负电平后半个周期回到0V。它懂得“劳逸结合”每个周期都回零休息一下。关键点“归零”归的是“零电平”而不是归到负电平。对于双极性归零码表示“0”的负脉冲也会在周期中途归零。归零码因为每个比特都有电平跳变回到零更有利于接收端从信号中提取定时时钟但代价是带宽更宽。把这四个概念两两组合就得到了我们的四位主角双极性不归零码DNRZ1A 0-A 电平持续整个Tb。双极性归零码DRZ1A持续 Tb/2 0-A持续 Tb/2 每个比特后半段都归零。单极性不归零码SNRZ1A 00 电平持续整个Tb。单极性归零码SRZ1A持续 Tb/2 00持续整个 Tb 或也归零这里有个细节。注意对于单极性归零码常见的定义是只有“1”码元产生一个归零脉冲“0”码元在整个周期内保持为零电平。即“0”是没有脉冲的。这与双极性归零码中“0”也对应一个负的归零脉冲不同。这是我们仿真时需要特别注意的也是它频谱特性不同的根源之一。3. 仿真环境搭建与核心参数设定我们使用MATLAB进行仿真因为它处理信号和绘图非常方便。这里假设你已有基本的MATLAB操作知识。3.1 基础参数定义在脚本开头我们先定义一组全局参数确保四种码型在同等条件下比较。clear all; close all; clc; % 基础参数设置 Rb 1000; % 比特率单位bps (bits per second) Tb 1 / Rb; % 比特间隔单位秒 (s) fs 100 * Rb; % 采样频率为了准确绘制波形采样率要远高于比特率这里取100倍 dt 1 / fs; % 采样间隔 A 1; % 信号幅度设为1方便归一化分析 % 生成随机的二进制信息序列 % 为了对比我们使用同一组随机序列 N_bits 50; % 生成50个比特进行演示 bit_sequence randi([0, 1], 1, N_bits); % 生成50个随机的0和1 % 时间轴生成 % 总时间 比特数 * 比特间隔 t_total N_bits * Tb; % 时间向量从0开始以dt为步进直到接近总时间避免浮点误差 t 0:dt:(t_total - dt/2); % t_total - dt/2 是为了确保时间点个数正好是 N_bits * Tb / dt参数选择背后的逻辑Rb1000bps这是一个典型的低速数据率便于我们观察波形细节。速率太高一个图里显示不了几个周期。fs100*Rb根据奈奎斯特采样定理采样频率至少是信号最高频率的2倍。对于方波这类富含高频分量的信号为了在时域上画出光滑的方波边沿需要很高的采样率。100倍是一个经验值能很好地平衡精度和计算量。N_bits50比特数太少统计特性不明显比如功率谱太多时域波形图会过于密集看不清。50个比特是一个折中的选择既能看清局部波形又能让功率谱有一定平滑度。使用同一组bit_sequence这是对比的关键只有源数据一致我们才能说波形和频谱的差异纯粹是由码型变换引起的而不是随机序列不同导致的。3.2 构建码型生成函数为了代码清晰和复用我们为每种码型编写一个独立的生成函数。函数输入是比特序列和时间轴输出是生成的信号波形。function signal generate_DNRZ(bits, t, Tb, A) % 生成双极性不归零码 % bits: 二进制序列 (行向量) % t: 时间向量 % Tb: 比特间隔 % A: 幅度 signal zeros(size(t)); for i 1:length(bits) bit bits(i); % 确定当前比特的时间范围 t_start (i-1) * Tb; t_end i * Tb; % 找到在这个时间范围内的所有时间点索引 indices (t t_start) (t t_end); if bit 1 signal(indices) A; % 比特为1赋值 A else signal(indices) -A; % 比特为0赋值 -A end end end function signal generate_DRZ(bits, t, Tb, A) % 生成双极性归零码 (占空比50%) % 归零脉冲宽度 tau Tb / 2 tau Tb / 2; signal zeros(size(t)); for i 1:length(bits) bit bits(i); t_start (i-1) * Tb; t_pulse_end t_start tau; % 脉冲结束时间 % 脉冲期间的时间索引 indices (t t_start) (t t_pulse_end); if bit 1 signal(indices) A; else signal(indices) -A; end % 归零期间 (t_pulse_end 到 t_startTb) 信号默认为0已由zeros初始化 end end function signal generate_SNRZ(bits, t, Tb, A) % 生成单极性不归零码 signal zeros(size(t)); for i 1:length(bits) bit bits(i); t_start (i-1) * Tb; t_end i * Tb; indices (t t_start) (t t_end); if bit 1 signal(indices) A; % 比特为1赋值 A else signal(indices) 0; % 比特为0赋值 0 end end end function signal generate_SRZ(bits, t, Tb, A) % 生成单极性归零码 (占空比50%) % 注意通常定义中只有1码元产生归零脉冲0码元持续为0。 tau Tb / 2; signal zeros(size(t)); for i 1:length(bits) bit bits(i); if bit 1 t_start (i-1) * Tb; t_pulse_end t_start tau; indices (t t_start) (t t_pulse_end); signal(indices) A; % 仅当比特为1时在前半段产生脉冲 end % 比特为0时全程为0无需操作 end end实操心得在编写这类波形生成函数时最核心也最容易出错的就是时间索引的计算。务必注意MATLAB中向量索引从1开始而时间从0开始。使用(t t_start) (t t_end)这种逻辑索引方式非常稳健能精确匹配时间段。避免使用基于采样点数的计算如(i-1)*sps1 : i*sps因为当Tb/fs不是整数时会产生误差。逻辑索引法能自动处理时间对齐问题。4. 时域波形生成与对比分析现在我们调用函数生成波形并将它们绘制在一起进行对比。% 生成四种码型的波形 dnrz_signal generate_DNRZ(bit_sequence, t, Tb, A); drz_signal generate_DRZ(bit_sequence, t, Tb, A); snrz_signal generate_SNRZ(bit_sequence, t, Tb, A); srz_signal generate_SRZ(bit_sequence, t, Tb, A); % 绘制时域波形对比图 (前10个比特) figure(Position, [100, 100, 1200, 800]); num_bits_to_show 10; % 只显示前10个比特便于观察细节 t_show_limit num_bits_to_show * Tb; show_indices t t_show_limit; % 子图1: 双极性不归零码 (DNRZ) subplot(4,1,1); plot(t(show_indices)*1000, dnrz_signal(show_indices), b-, LineWidth, 1.5); grid on; ylim([-1.5*A, 1.5*A]); title(双极性不归零码 (DNRZ) 时域波形); ylabel(幅度); xlabel(时间 (ms)); % 添加比特序列标注可选使图形更清晰 hold on; for i 1:min(num_bits_to_show, length(bit_sequence)) text((i-0.5)*Tb*1000, 1.2*A, num2str(bit_sequence(i)), ... HorizontalAlignment, center, FontWeight, bold); end hold off; % 子图2: 双极性归零码 (DRZ) subplot(4,1,2); plot(t(show_indices)*1000, drz_signal(show_indices), r-, LineWidth, 1.5); grid on; ylim([-1.5*A, 1.5*A]); title(双极性归零码 (DRZ) 时域波形 (占空比50%)); ylabel(幅度); xlabel(时间 (ms)); hold on; for i 1:min(num_bits_to_show, length(bit_sequence)) text((i-0.5)*Tb*1000, 1.2*A, num2str(bit_sequence(i)), ... HorizontalAlignment, center, FontWeight, bold); end hold off; % 子图3: 单极性不归零码 (SNRZ) subplot(4,1,3); plot(t(show_indices)*1000, snrz_signal(show_indices), g-, LineWidth, 1.5); grid on; ylim([-0.2*A, 1.5*A]); % y轴从-0.2开始以便看清零线 title(单极性不归零码 (SNRZ) 时域波形); ylabel(幅度); xlabel(时间 (ms)); hold on; for i 1:min(num_bits_to_show, length(bit_sequence)) text((i-0.5)*Tb*1000, 1.2*A, num2str(bit_sequence(i)), ... HorizontalAlignment, center, FontWeight, bold); end hold off; % 子图4: 单极性归零码 (SRZ) subplot(4,1,4); plot(t(show_indices)*1000, srz_signal(show_indices), m-, LineWidth, 1.5); grid on; ylim([-0.2*A, 1.5*A]); title(单极性归零码 (SRZ) 时域波形 (占空比50%)); ylabel(幅度); xlabel(时间 (ms)); hold on; for i 1:min(num_bits_to_show, length(bit_sequence)) text((i-0.5)*Tb*1000, 1.2*A, num2str(bit_sequence(i)), ... HorizontalAlignment, center, FontWeight, bold); end hold off;运行这段代码你会得到一张包含四个子图的时域波形对比图。现在我们来逐一点评DNRZ (图1)波形最“干净利落”。每个比特周期内电平要么是1要么是-1并且持续整整1ms因为Rb1000bps,Tb1ms。当出现连续的“1”或“0”时你会看到一条长时间不变的水平线。问题来了如果传输一长串“1”接收端怎么知道每个比特的边界在哪里这就需要额外的时钟同步信号或者采用自带时钟信息的码型比如我们下面的归零码。DRZ (图2)与DNRZ使用相同的比特序列。最明显的特征是每个比特周期中间电平都会“归零”。对于“1”是一个持续0.5ms的正脉冲对于“0”是一个持续0.5ms的负脉冲。注意看即便是连续的“1”或“0”每个比特周期内也都有一次从有效电平到零的跳变。这个跳变就是接收端用来恢复时钟的宝贵信息代价是为了传输同样的比特信息DRZ需要更快的电平变化这意味着它需要更宽的带宽。SNRZ (图3)波形全部在零轴以上。“1”是1“0”就是0V。同样在连续“1”或连续“0”时没有电平变化。一个致命缺点暴露了由于“0”和“1”的平均电平不同“1”多则平均电平高信号中存在显著的直流分量。直流分量无法通过变压器或电容耦合的信道会造成能量浪费和基线漂移。SRZ (图4)这是最“偷懒”的码型。只有“1”的时候才在前半段产生一个正脉冲“0”的时候整个周期都是安静的0V。你可以看到当出现连续“0”时波形就是一条长长的零线。它的优点和DRZ类似每个“1”比特都自带时钟跳变信息但“0”没有。缺点也很明显直流分量更大因为只有正脉冲且当连续“0”过多时接收端会失去同步参考。踩坑记录在绘制时域图时最初我尝试用stem函数画离散序列图但发现对于展示码型这种持续一段时间的电平信号plot连线图更能体现“电平保持”的概念。另外时间轴乘以1000转换为毫秒是因为1ms对于人类视觉感知来说是一个更舒服的单位。这些小细节决定了你的仿真结果是否直观、专业。5. 功率谱密度计算窥探信号的频率“指纹”时域波形告诉我们信号随时间怎么变而功率谱密度PSD则告诉我们信号的能量在不同频率上是如何分布的。这对于评估信号需要多大的信道带宽、是否会产生干扰至关重要。5.1 为什么用周期图法如何计算对于有限长的随机信号我们通常用周期图法来估计其功率谱。MATLAB中的pwelch函数是实现这一方法的利器。它通过将长信号分段、加窗、求各段周期图平均来得到相对平滑、稳定的PSD估计。% 计算功率谱密度 (PSD) % 使用pwelch函数采用Welch平均周期图法 % 设置窗函数和重叠点数以获得平滑的谱估计 window hamming(1024); % 使用汉明窗减少频谱泄漏 noverlap 512; % 重叠点数一般为窗长的一半 nfft 4096; % FFT点数决定频率分辨率点数越多分辨率越高曲线越光滑 [PSD_dnrz, f_dnrz] pwelch(dnrz_signal, window, noverlap, nfft, fs, power); [PSD_drz, f_drz] pwelch(drz_signal, window, noverlap, nfft, fs, power); [PSD_snrz, f_snrz] pwelch(snrz_signal, window, noverlap, nfft, fs, power); [PSD_srz, f_srz] pwelch(srz_signal, window, noverlap, nfft, fs, power); % 将频率转换为kHz功率转换为dBm/Hz (以1mW为基准) 或 dBW/Hz (以1W为基准) % 这里我们计算相对功率谱密度关注形状而非绝对值所以常用dB表示 PSD_dnrz_dB 10*log10(PSD_dnrz); PSD_drz_dB 10*log10(PSD_drz); PSD_snrz_dB 10*log10(PSD_snrz); PSD_srz_dB 10*log10(PSD_srz); f_kHz_dnrz f_dnrz / 1000; % 转换为kHz % 绘制功率谱密度对比图 figure(Position, [100, 100, 1200, 800]); % 子图1: 线性坐标对比 (观察主瓣宽度和零点) subplot(2,1,1); plot(f_kHz_dnrz, PSD_dnrz, b-, LineWidth, 1.5); hold on; plot(f_kHz_dnrz, PSD_drz, r-, LineWidth, 1.5); plot(f_kHz_dnrz, PSD_snrz, g-, LineWidth, 1.5); plot(f_kHz_dnrz, PSD_srz, m-, LineWidth, 1.5); hold off; grid on; xlim([0, 10*Rb/1000]); % 显示到10倍比特率频率10kHz title(四种基带码型的功率谱密度 (线性坐标)); xlabel(频率 (kHz)); ylabel(功率谱密度 (W/Hz)); legend(DNRZ, DRZ, SNRZ, SRZ, Location, best); % 子图2: 对数坐标对比 (观察旁瓣衰减和动态范围) subplot(2,1,2); plot(f_kHz_dnrz, PSD_dnrz_dB, b-, LineWidth, 1.5); hold on; plot(f_kHz_dnrz, PSD_drz_dB, r-, LineWidth, 1.5); plot(f_kHz_dnrz, PSD_snrz_dB, g-, LineWidth, 1.5); plot(f_kHz_dnrz, PSD_srz_dB, m-, LineWidth, 1.5); hold off; grid on; xlim([0, 10*Rb/1000]); ylim([-100, 10]); % 设置合理的dB范围 title(四种基带码型的功率谱密度 (对数坐标单位: dB)); xlabel(频率 (kHz)); ylabel(功率谱密度 (dB)); legend(DNRZ, DRZ, SNRZ, SRZ, Location, best);5.2 功率谱图深度解读理论与仿真的碰撞运行上述代码你会得到两张功率谱图一张线性坐标一张对数坐标。我们结合理论重点看对数坐标图因为它能清晰展示能量分布的细节。1. DNRZ的谱特征主瓣宽度它的能量主要集中在低频段。理论上NRZ码的功率谱形状为(sin(πfTb)/(πfTb))^2即sinc函数的平方。第一个零点出现在f Rb处本例中为1kHz。我们的仿真图中可以看到在1kHz附近DNRZ的谱线确实降到了很低。旁瓣衰减在主瓣之外能量以1/f^2的速度衰减每倍频程下降6dB。图中可以看到明显的旁瓣结构。直流分量由于是双极性且0和1等概理论上直流分量为零。仿真中在0Hz处没有明显的冲激线与理论相符。2. DRZ的谱特征主瓣宽度明显变宽因为归零脉冲更窄τTb/2其频谱主瓣宽度是不归零码的两倍。第一个零点出现在f 1/τ 2Rb处本例中为2kHz。图中清晰显示DRZ的能量在2kHz之后才显著下降。旁瓣衰减与DNRZ类似但因为它相当于用了一个更窄的矩形窗其旁瓣衰减速度与DNRZ相同。时钟分量由于每个比特都有归零动作信号中存在周期性的成分尽管幅度随机这可能在频谱的Rb1kHz及其谐波处产生离散的谱线用于时钟提取。仿真中可能表现为在1kHz、2kHz等处有小的凸起。3. SNRZ的谱特征主瓣宽度与DNRZ相同第一个零点也在f Rb处。致命的直流分量这是单极性码最显著的特征在频谱的0Hz处有一个非常高的尖峰这代表了信号中的平均直流功率。在线性坐标图中这个尖峰会异常突出在对数坐标图中0Hz处的值也远高于其他频点。这意味着大量能量被浪费在无法传输的直流上。连续谱形状除了直流冲激其连续谱部分与DNRZ相似但整体电平更高因为增加了直流功率。4. SRZ的谱特征主瓣宽度与DRZ相同因为脉冲宽度也是τTb/2第一个零点在f 2Rb(2kHz)。直流分量同样存在因为只有正脉冲信号平均值大于零。0Hz处也有尖峰但可能比SNRZ的小因为“1”码只占半个周期。时钟分量非常强由于“1”码产生规则的正脉冲而“0”码全为零信号中包含了很强的Rb1kHz基频及其谐波分量。这在频谱图上表现为在1kHz、2kHz等处有明显的离散谱线。这正是接收端用窄带滤波器就能轻松提取出时钟信号的原因。参数设置心得pwelch函数的参数设置直接影响谱估计的质量。nfft越大频率分辨率越高曲线越光滑但计算量也越大。window选择汉明窗或汉宁窗可以有效抑制“频谱泄漏”即能量扩散到不该有的频率上。noverlap设置重叠可以增加用于平均的段数使最终谱估计更平滑。对于这类随机数字信号我通常从nfft2048或4096开始尝试。如果谱线起伏太大就增加nfft或使用更长的window。6. 从仿真结果看工程选型如何为你的系统挑选码型仿真图表很漂亮但最终要落到实际应用。这四种基本码型各自适合什么场景又有什么坑要避开6.1 带宽效率与时钟恢复的权衡追求带宽效率选NRZDNRZ和SNRZ的主瓣窄在Rb处就有第一个零点这意味着传输它们所需的最小理论带宽尼奎斯特带宽约为Rb/2。在带宽紧张的场合如高速长途光纤通信NRZ码是主流。代价需要独立的时钟信道或复杂的时钟恢复电路如锁相环PLL来从长连0/1序列中提取时钟。追求时钟恢复简单选RZDRZ和SRZ频谱中富含时钟线特别是SRZ接收端用一个简单的窄带滤波器或锁相环就能轻松提取出稳定的时钟。代价带宽需求翻倍主瓣宽到2Rb。在同样的信道带宽下你能传输的数据速率只有NRZ的一半。工程中的折衷于是就有了“扰码”和“线路编码”。比如在光纤SDH/SONET系统中先对NRZ数据进行扰码打乱长连0/1再传输。接收端先恢复时钟再解扰码。这样既保持了NRZ的带宽效率又解决了时钟恢复难题。6.2 直流分量与信道适应性避免直流选双极性DNRZ和DRZ没有直流分量在0、1等概时可以通过变压器或电容耦合适合有线信道。它们对信道低频响应不敏感。小心直流慎用单极性SNRZ和SRZ有显著的直流分量。如果信道不能传输直流比如通过交流耦合的射频链路或光纤信号会产生严重的基线漂移导致判决错误。除非系统专门为单极性设计了直流恢复电路否则应避免使用。一个经典应用早期的以太网10BASE5, 10BASE2使用的就是曼彻斯特码它是一种特殊的双极性归零码。每个比特中间都有跳变“0”是低到高跳变“1”是高到低跳变。它完美结合了归零码自带时钟和双极性码无直流的优点当然代价是带宽效率最低需要两倍带宽。6.3 抗噪声与误码性能在加性高斯白噪声AWGN信道下如果比较最佳接收的性能匹配滤波器采样判决对于相同的比特能量Eb双极性码的抗噪声性能优于单极性码。直观理解DNRZ中“1”和“0”的信号距离是2A而SNRZ中“1”和“0”的距离只有A。在同样的噪声水平下距离越大越不容易判错。定量分析在0、1等概时达到相同误码率单极性码需要的信噪比SNR比双极性码高3dB。这意味着发射功率需要翻倍所以从抗噪声角度看DNRZ是这四种基本码型中的“优等生”带宽效率高、无直流、抗噪性好。它的主要短板就是时钟恢复。7. 仿真进阶验证理论公式与探索边界条件我们的仿真不能只停留在画图上还要用它来验证理论甚至发现理论中忽略的细节。7.1 验证功率谱公式我们可以编写代码计算上述四种码型的理论功率谱密度公式并将其与仿真得到的周期图进行叠加比较。以双极性不归零码DNRZ为例其理论功率谱公式为P(f) A^2 * Tb * (sin(πfTb)/(πfTb))^2 A^2 * Tb * sinc^2(fTb)假设0、1等概且独立。% 绘制DNRZ理论PSD与仿真PSD对比 figure; % 理论计算 f_theory f_dnrz; % 使用相同的频率点 P_theory_dnrz (A^2 * Tb) * (sinc(f_theory * Tb)).^2; % sinc(x) sin(πx)/(πx) % 绘制对比 plot(f_kHz_dnrz, PSD_dnrz, b-, LineWidth, 1.5, DisplayName, 仿真 (Welch)); hold on; plot(f_kHz_dnrz, P_theory_dnrz, r--, LineWidth, 2, DisplayName, 理论公式); hold off; grid on; xlim([0, 10*Rb/1000]); title(DNRZ功率谱密度仿真 vs. 理论); xlabel(频率 (kHz)); ylabel(功率谱密度); legend(show); % 计算并显示均方误差 (MSE)量化仿真精度 mse mean((PSD_dnrz - P_theory_dnrz).^2); fprintf(DNRZ仿真与理论PSD的均方误差(MSE)为: %e\n, mse);运行这段代码你会看到两条曲线高度重合并且MSE值非常小例如10^-6量级。这强有力地证明了我们仿真方法的正确性。对于其他码型你也可以找到对应的理论公式进行验证例如单极性NRZ的谱包含一个直流冲激函数δ(f)和一个连续谱部分。7.2 探索非等概情况的影响我们之前的仿真默认“0”和“1”等概出现randi([0,1])。但实际数据中可能会出现“0”多或“1”多的情况。这会对功率谱尤其是直流分量产生什么影响% 生成非等概序列1的概率为p 0.8 p 0.8; N_bits 10000; % 使用更多比特以获得稳定的统计特性 bit_seq_biased rand(1, N_bits) p; % 以概率p生成1 % 生成非等概下的SNRZ信号 t_long 0:dt:(N_bits*Tb - dt/2); snrz_signal_biased generate_SNRZ(bit_seq_biased, t_long, Tb, A); % 计算其功率谱 [PSD_snrz_biased, f_snrz_biased] pwelch(snrz_signal_biased, window, noverlap, nfft, fs, power); PSD_snrz_biased_dB 10*log10(PSD_snrz_biased); % 与等概情况对比重新用长序列生成等概SNRZ bit_seq_equal randi([0,1], 1, N_bits); snrz_signal_equal generate_SNRZ(bit_seq_equal, t_long, Tb, A); [PSD_snrz_equal, ~] pwelch(snrz_signal_equal, window, noverlap, nfft, fs, power); PSD_snrz_equal_dB 10*log10(PSD_snrz_equal); % 绘图对比 figure; plot(f_snrz_biased/1000, PSD_snrz_biased_dB, r-, LineWidth, 1.5, DisplayName, sprintf(SNRZ (p%.1f), p)); hold on; plot(f_snrz_biased/1000, PSD_snrz_equal_dB, b--, LineWidth, 1.5, DisplayName, SNRZ (p0.5)); hold off; grid on; xlim([0, 5]); ylabel(功率谱密度 (dB)); xlabel(频率 (kHz)); title(单极性不归零码(SNRZ)在不同比特概率下的功率谱); legend(show);你会发现当“1”的概率p增大到0.8时SNRZ频谱在0Hz处的直流尖峰显著升高。因为信号的直流平均值A*p变大了。同时连续谱部分的形状也会发生改变。这验证了理论单极性码的直流分量与“1”的概率成正比。这在实际系统中是个大问题如果数据流中长时间出现连续的“1”比如传输一个全亮图像直流分量会剧增可能导致接收端放大器饱和。而对于双极性码DNRZ理论分析表明其直流分量为A*(2p-1)。当p0.5时直流分量为零当p偏离0.5时也会产生直流分量。通过修改上面的代码测试DNRZ你会看到类似但可能更微妙的变化。7.3 眼图更直观的性能评估工具功率谱告诉我们频域特性而“眼图”则是评估数字基带信号时域传输质量的终极工具。它通过将不同比特周期的波形叠加在一起形成像眼睛一样的图案。眼图的张开度、噪声容限、定时误差灵敏度等一目了然。% 绘制DNRZ和DRZ的眼图 % 眼图通常需要展示2-3个比特周期的叠加 sps round(fs / Rb); % 每比特采样点数 span 2; % 显示2个比特周期的眼图 offset 0; % 从第几个采样点开始 % 选取一段信号用于生成眼图 signal_for_eye dnrz_signal(offset1 : offset span*sps*10); % 取10个“眼”的长度 % 重塑矩阵每一列代表一个“眼”的波形 eye_matrix reshape(signal_for_eye, span*sps, []); figure; subplot(2,1,1); plot((0:size(eye_matrix,1)-1)/fs * 1000, eye_matrix, b-); grid on; xlabel(时间 (ms)); ylabel(幅度); title(sprintf(双极性不归零码 (DNRZ) 眼图 (每眼%d个比特周期), span)); xlim([0, span*Tb*1000]); % 对DRZ做同样处理 signal_for_eye_drz drz_signal(offset1 : offset span*sps*10); eye_matrix_drz reshape(signal_for_eye_drz, span*sps, []); subplot(2,1,2); plot((0:size(eye_matrix_drz,1)-1)/fs * 1000, eye_matrix_drz, r-); grid on; xlabel(时间 (ms)); ylabel(幅度); title(sprintf(双极性归零码 (DRZ) 眼图 (每眼%d个比特周期), span)); xlim([0, span*Tb*1000]);观察生成的眼图DNRZ眼图在比特周期边界处0ms和1ms所有轨迹都汇聚于一点1或-1眼图是张开的。但在周期中间由于是连续电平轨迹是水平的眼图中间是“实心”的。这反映了NRZ码在周期中间时刻对定时抖动不敏感因为电平不变但在边界时刻要求精确同步。DRZ眼图眼图更加清晰在每个比特周期中间0.5ms处所有轨迹都回归到零形成一个清晰的“眼孔”。这个孔的大小直接反映了系统的噪声容限。眼图越开阔、越清晰说明信号质量越好对定时抖动的容忍度越高。通过眼图工程师可以直观判断码间串扰、噪声大小和最佳采样时刻。这是仿真分析中不可或缺的一环。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价