简介:资源包为MATLAB无线通信系统仿真入门资料,面向通信工程、电子信息类学生或需要快速搭建ASK链路仿真的人员。仅含1个m脚本,大小约3KB,实现单音频信号作为模拟信源,在AWGN信道下完成振幅键控(ASK)调制与相干解调完整流程,并绘制解调器输出端性能曲线与信噪比SNR的关系。已有150人学习下载。脚本结构清晰,包含信号生成、调制、加噪、解调与误码率统计模块,适合学习通信原理时对照验证,也可作为修改参数、扩展多径信道等实验的基础模板。通过运行此脚本,读者能直观理解加性高斯白噪声对ASK系统性能的影响,掌握MATLAB通信工具箱的基本用法。
1. 从单音频信源到2ASK:这个仿真到底在复现什么
如果你拿到的课程设计是“用MATLAB仿真一个无线通信系统,信源是单音频,调制方式是ASK,信道有两径和AWGN,接收端做相干解调,最后画出性能曲线与SNR的关系”,那这个仿真题目的重点其实不在MATLAB本身,而在三个容易被低估的细节:单音频信源到底怎么变成比特流、两径信道的时延会不会导致幅度相消,以及awgn函数里的点信噪比和最终误码率曲线的横坐标是不是同一个量。很多人把ask.m打开后第一件事就是改参数,结果发现BER曲线在低SNR段就直线往下掉,或者高SNR段直接变成0。这不是代码写错了,而是信噪比定义、判决阈值和符号统计数量三者没有对齐。这套仿真适合正在学通信原理、准备课程设计或者想快速搭一条完整链路验证想法的工程师,它能让你在一小时内把调制、信道、解调、误码率统计这四个环节全部跑通。
2. 单音频信源与ASK调制:比特序列和载波参数怎么选
2.1 单音频信源如何变成可统计的比特流
ASK是数字调制,但题目指定信源为单音频模拟信号,因此第一步要解决模拟信源和数字调制之间的接口。常规做法是让单音频信号经过一个比较器,过零输出方波,再按符号周期采样得到二进制序列。这样既保留了“模拟信源”的存在感,又能直接统计误码率。这里刻意把单音频频率f0设为1.3kHz,与符号速率1kbps不成整数倍关系,采样点落在正弦波不同相位上,于是得到的比特序列接近伪随机。如果直接把f0设为1kHz且与符号速率相同,每个符号首采样点相位相同,生成的全是1或全是0,后面的误码率统计就完全失真。
fs = 100e3; % 采样率,100kHz fc = 10e3; % 载波频率,10kHz Rb = 1e3; % 符号速率,1kbps sps = fs / Rb; % 每符号采样数,100 N = 10000; % 符号总数 t_total = N / Rb; % 总时长 t = 0 : 1/fs : t_total - 1/fs; % 单音频信源:正弦波过零比较后按符号周期采样 f0 = 1.3e3; analog_src = sin(2 * pi * f0 * t); sym_idx = 1 : sps : length(analog_src); bits = analog_src(sym_idx) > 0;这段代码里,sym_idx取了每个符号第一个采样点的索引,相当于在每个符号周期做一次瞬时抽样。因为f0与Rb的比值不是整数,每个符号的抽样相位都在变化,所以产生的是类似随机序列的比特。这里的analog_src长度严格等于N*sps,确保后面按符号扩展时不会发生长度错位。如果你手头有现成的音频文件,也可以把它替换成audioread读取的波形,再走相同的过零判决流程。
2.2 把比特流扩成波形并完成2ASK调制
得到比特序列后,需要把每个比特扩展成持续sps个采样点的基带波形。2ASK在这里采用OOK方式,即发送1时载波幅度为1,发送0时载波幅度为0。调制公式就是基带波形与余弦载波相乘。
bits_wave = reshape(repmat(bits, sps, 1), 1, N * sps); tx = bits_wave .* cos(2 * pi * fc * t);repmat(bits, sps, 1)把每个比特纵向复制sps次,形成一个sps行、N列的矩阵,再reshape成一行,得到每个符号内电平保持恒定的矩形基带波形。载波频率10kHz远大于符号速率1kHz,频域上基带谱和载波谱离得足够开,后面低通滤波时可以干净地留下基带分量。这里故意不做成型滤波,让波形是理想矩形,这样能更直白地看到多径和AWGN对幅度的影响。
2.3 参数选择依据与ASK选型边界
整个链路的几个关键参数可以归纳成一张表,方便课程设计报告直接引用。
| 参数 | 数值 | 选取依据 |
|---|---|---|
| fs | 100 kHz | 25倍过采样,满足波形观察精度 |
| fc | 10 kHz | 远大于Rb,且小于fs/2,避免混叠 |
| Rb | 1 kbps | 方便观察符号波形,sps=100 |
| f0 | 1.3 kHz | 与Rb不成整数倍,生成近似随机比特 |
| N | 10000 | BER统计保证至少10个错误点 |
选择ASK而不是FSK或PSK,是因为这个仿真的核心目标是多径信道和AWGN下的幅度性能。ASK的相干解调只需要乘本地载波再判决幅度,链路短,便于把注意力集中在信道建模和SNR计算上。工程上ASK在光通信和低速无线传感节点中仍有应用,但它的抗噪声能力比PSK差,这一点通过后面的性能曲线也能直观看到。
3. 两径信道建模与AWGN功率控制
3.1 两径信道模型:抽头延迟线形式
两径信道最常见的描述是抽头延迟线模型:接收信号由直射路径和一条延迟、衰减的路径叠加而成。这里设h1=0.8、h2=0.4,第二径相对第一径延迟5个采样点。延迟量要控制在一个很小的范围,因为5个采样只占一个符号周期的5%,等间隔抽样仍然能保持同步;如果延迟接近几十甚至上百个采样,就必须额外做符号同步和均衡,这已经超出项目范围。
h1 = 0.8; h2 = 0.4; delay = 5; path1 = h1 * tx; path2 = h2 * [zeros(1, delay), tx(1:end-delay)]; rx_no_noise = path1 + path2;代码里用矩阵拼接实现离散延迟:[zeros(1, delay), tx(1:end-delay)]把第二径信号整体向右移动delay个采样点,前部补零,等价于离散时间系统的y(n) = h1*x(n) + h2*x(n-delay)。这种写法和filter或conv对比,好处是你能明确知道第二径延迟了多少个采样点,也不会被滤波器群延迟干扰。实际信道中两径的幅度和延迟通常由环境决定,这里取h2=0.4、delay=5是为了让曲线能看到明显的性能下降,又不至于让误码率完全失真。
3.2 AWGN的功率控制与点信噪比
加性高斯白噪声在MATLAB中用awgn函数实现。很多初学者直接把awgn(signal, SNR)写进去,结果SNR和预期差好几个dB,原因是没有告诉MATLAB当前信号的实际功率。awgn函数的第二个参数是目标信噪比,第三个参数如果写'measured',它就会先测量输入信号功率,再据此产生对应方差的高斯噪声。
snr_point = 10; rx = awgn(rx_no_noise, snr_point, 'measured');这里把“点信噪比”定义为每个采样点上的信号功率与噪声功率之比,单位dB。awgn内部按sqrt(10^(snr_point/10))换算噪声标准差,所以不需要手动计算噪声方差。如果你使用randn自行加噪,则需要先计算信号功率P = mean(abs(rx_no_noise).^2),再生成sqrt(P / (10^(snr_point/10))) * randn(size(t)),两条路得到的结果一致,但awgn更稳妥。
3.3 多径叠加时会出现的反相问题
两径信号的时延差如果对应载波相位差为奇数个π,叠加后就会幅度相消。以当前参数计算,2*pi*fc*delay/fs = 2*pi*10000*5/100000 = pi,第二径和直射径恰好反相,接收幅度从1.2变成了0.4。这意味着即使没有噪声,接收端的解调信号也比单径情况弱很多。这个现象很容易被误判成噪声过大或信道增益设置错误,其实是两径叠加后的合法结果。想验证多径相位差的影响,可以把delay从0到50逐步扫描,观察接收信号功率的变化。这个检查在调试ask.m时非常有用。
4. 相干解调与误码率统计:ask.m逐段拆解
4.1 相干解调:本地载波、低通滤波、抽样判决
相干解调的前提是接收端有与发送端同频同相的本地载波。把接收信号乘上cos(2*pi*fc*t)后,ASK频带信号被搬回基带,同时产生一个位于2fc的高频分量,需要低通滤波去除。这里的低通截止频率取2kHz,保留基带中1kHz附近的成分,同时压住载波二倍频分量。
rx_demod = rx .* cos(2 * pi * fc * t); [b, a] = butter(5, 2 * fc / (fs / 2)); % 截止频率2kHz的5阶巴特沃斯 rx_filtered = filter(b, a, rx_demod); rx_i = rx_filtered(sps / 2 : sps : end); % 每个符号中点抽样butter(5, 2*fc/(fs/2))中的频率参数需要使用归一化频率,2*fc是截止频率2kHz,除以fs/2后得到0到1之间的归一化值。由于fs=100kHz,2kHz对应归一化频率0.04,这是一个很窄的低通,能有效滤除高频分量。抽样点选在每个符号的中点,即sps/2 : sps : end,避开符号边缘的上升沿和下降沿。这个位置在码间干扰不严重时是判决可靠性最高的采样点。
4.2 多径延迟和滤波器带来的符号对齐问题
实际运行时,rx_i的长度是N,和发送比特bits长度一致,但不能直接逐位比较,因为第二径延迟和滤波器群延迟会让接收比特整体偏移几个采样点。当delay只有5个采样、低通滤波器群延迟也较小时,中点抽样仍能落在正确的符号区间里。如果延迟增加到半个符号周期以上,就必须在使用前先做符号同步。课程设计里常见做法是发送一段已知前导序列,用互相关估计时延偏移,再把接收比特循环移位对齐。
这里为了保持项目聚焦,直接在代码里采用理想符号同步假设:认为接收端已经知道符号起点,rx_i中的每个元素对应一个发送比特。如果追求更严格的结果,可以在BER计算前先丢弃前后少量保护比特,或者用circshift配合互相关做整数倍符号对齐。这个对齐误差在高SNR下会表现为误码率平台,属于典型的多径+非同步坑。
4.3 完整SNR扫描循环与性能曲线绘制
把信号生成、调制、多径信道、AWGN、相干解调、抽样判决全部放进SNR循环,就能得到一条BER-SNR曲线。这里的SNR_dB扫描范围选择0到16dB,步长2dB。
SNR_dB = 0:2:16; BER = zeros(size(SNR_dB)); for k = 1:length(SNR_dB) bits_wave = reshape(repmat(bits, sps, 1), 1, N * sps); tx = bits_wave .* cos(2 * pi * fc * t); path1 = h1 * tx; path2 = h2 * [zeros(1, delay), tx(1:end-delay)]; rx_no_noise = path1 + path2; rx = awgn(rx_no_noise, SNR_dB(k), 'measured'); rx_demod = rx .* cos(2 * pi * fc * t); [b, a] = butter(5, 2 * fc / (fs / 2)); rx_filtered = filter(b, a, rx_demod); rx_i = rx_filtered(sps / 2 : sps : end); % 自适应判决阈值:使用接收基带平均幅度的一半 threshold = 0.5 * mean(abs(rx_i)); rx_bits = rx_i > threshold; n_use = min(length(bits), length(rx_bits)); BER(k) = sum(rx_bits(1:n_use) ~= bits(1:n_use)) / n_use; end semilogy(SNR_dB, BER, 'o-'); xlabel('点信噪比 SNR (dB)'); ylabel('BER'); grid on;这段代码中,mean(abs(rx_i))估计接收信号的平均电平,阈值取平均电平的一半。相比固定阈值0,这种方式能自适应多径信道造成的幅度缩放。每个SNR点都重新执行完整信道和解调流程,确保噪声独立。semilogy把BER放到对数坐标,曲线的陡峭程度能直观反映这一调制方式的抗噪能力。
4.4 高信噪比下曲线掉零的处理思路
运行这段代码会发现,SNR达到14dB以上时BER会变成0,semilogy上对应的点直接消失。原因是N=10000不足以统计到足够低的误码率。如果需要让曲线在12dB之后仍然连续,常见的做法是提高高SNR段的符号数。例如当SNR_dB(k)大于等于12时,把N改为50000,然后重新生成t、analog_src和bits。这个调整会让计算量明显上升,但能改善尾部曲线的可信度。
5. 从曲线到可信结论:参数调节、判决阈值和仿真时长控制
5.1 自适应延长符号数,压住高SNR段抖动
BER仿真有一个经验规则:每个SNR点至少需要累计到约50个错误比特,该点的BER才可信。N=10000时,如果真实BER是1e-4,期望错误数只有1个,一个点都没有的几率为e^{-1},即37%的概率得到BER=0。所以不要盲目把SNR扫到16dB,不如先根据目标BER下限估算N:目标BER为1e-4,N至少取50/1e-4=50万。课程设计报告中,我更建议把SNR范围控制在0到12dB,N稳定在10000,这样曲线完整且计算时间可控。
if SNR_dB(k) < 8 N = 1e4; elseif SNR_dB(k) < 12 N = 5e4; else N = 2e5; end这种分段N设置能在低SNR段保持效率,在高SNR段保证统计稳定性。修改N后需要同步更新t、analog_src和sym_idx,否则长度不匹配会直接报错。实际任务中我一般用while循环不断加长符号序列,直到错误数超过50再进入下一个SNR点,这是工程上更标准的蒙特卡洛做法。
5.2 多径时延与载波相位差的联动验证
调试ask.m时,先不要急着画BER曲线,而是先验证多径模型是否正确。下面这段代码可以快速观察不同delay下的接收功率。
delay_list = 0:5:50; for d = delay_list path2 = h2 * [zeros(1, d), tx(1:end-d)]; P = mean((path1 + path2).^2); fprintf('delay=%d, 接收功率=%.3f\n', d, P); end运行后会看到功率随delay呈周期性变化,周期等于fs/fc=10个采样点。delay=0或10时两径同相叠加,功率最大;delay=5时两径反相相消,功率最小。这个现象能解释为什么BER-SNR曲线比单径情况差,也因此提醒你,多径信道中单纯增大发射功率可能无法按预期降低误码率。这是本项目中除误码率曲线外最值得写进报告的一张侧视图。
本文还有配套的精品资源,点击获取