资讯动态

16QAM星形与矩形星座的MATLAB调制解调实现与对比

发布时间:2026/9/18 22:24:37 来源:尧图企业网站定制
简介面向软件无线电课程设计和通信原理实验的MATLAB代码解析文档聚焦十六阶正交幅度调制16QAM中星形与矩形两种星座图的调制解调实现。资源为单一PDF文件容量仅四十三KB内容紧凑适合通信工程、电子信息类学生及需要快速理解QAM调制原理的开发者参考。文档完整梳理了从码元速率、滤波器采样率、载波频率等参数定义到随机序列生成、方形与星形调制、基带成型滤波、载波调制解调直至误码率计算与理论曲线对比的仿真流程并附有发送与接收波形、基带眼图及接收端星座图等可视化分析。目前已吸引六百二十二人学习下载可帮助读者快速掌握MATLAB环境下两种16QAM映射方式的程序设计要点节省自行摸索时间。若正在完成软件无线电课程设计或希望深入理解数字调制技术这份解析文档具有直接指导价值。1. 16QAM 星形和矩形星座图MATLAB 调制解调的核心差异如果只在 MATLAB 里调用qammod(16)你拿到的是矩形星座一旦换成星形星座很多现成代码立刻失效。16QAM 并不是只有一种星座形状矩形靠 I/Q 两路四电平叠加星形则把幅度和相位分成两级判决逻辑从直线边界变成环和扇区。这两类星座在功率归一化、最小欧氏距离和判决门限上都有差异直接抄 PDF 里的代码往往忽略这些导致仿真误码率对不上。下面直接用 MATLAB 写两套可复用的调制解调函数覆盖矩形和星形两种结构从比特映射到判决边界、从 AWGN 信道仿真到星座图验证给出可以改参数、算 BER 的最小实现。2. 星形与矩形 16QAM 的映射原理和关键参数2.1 矩形 16QAM 的格雷映射I/Q 两路四电平矩形 16QAM 的本质是两个正交的四电平 PAM 叠加。每个符号包含 4 个比特前 2 位映射到 I 路后 2 位映射到 Q 路。I/Q 各自从{-3,-1,1,3}中取值组合后得到 4×4 网格。为了降低误比特率相邻电平要使用格雷码常用映射关系如下b1 b2电平00-301-1111103Q 路 b3 b4 使用相同规则。这样任意两个相邻星座点之间只差 1 个比特判决错误时大概率只产生 1 个比特错误。生成符号时平均功率为(3^21^2(-1)^2(-3)^2)/4 * 2 10因此送入信道前要除以sqrt(10)把符号功率归一化到 1。很多 PDF 代码会省略这一步导致信噪比设置虚高或虚低。MATLAB 中可以用查表法避免通信工具箱依赖function sym qam16_mod_rect(bits) % bits: 长度为4N的列向量每4位一个符号 bits reshape(bits, 4, []).; % 每行一个符号 lvl [-3 -1 1 3]; % 四个电平格雷顺序 idx [1 2 4 3]; % 二进制00,01,11,10 - 表位置 I zeros(size(bits,1),1); Q zeros(size(bits,1),1); for k 1:size(bits,1) vI bits(k,1)*2 bits(k,2) 1; % 1..4 vQ bits(k,3)*2 bits(k,4) 1; I(k) lvl(idx(vI)); Q(k) lvl(idx(vQ)); end sym (I 1j*Q) / sqrt(10); end参数说明bits必须是列向量长度应为 4 的整数倍idx用于把二进制组合映射到格雷表的实际位置不做这一步符号排序会乱sqrt(10)把平均功率拉回 1后续信噪比才能用10*log10(Es/N0)直接换算。这个函数只用了基础矩阵运算不需要qammod和bi2de旧版 MATLAB 也能跑。2.2 星形 16QAM内环4点与外环12点的半径比星形星座的结构是“一个大环加一个小环”。常见取法内环 4 个点外环 12 个点总共 16 个符号。内环相位为 0、π/2、π、3π/2外环相位与内环错开经典角度基准取 π/12也就是从 15° 开始每隔 30° 放一个外环点。内环半径r1和外环半径r2是两个自由参数。半径比r2/r1影响两个指标内环到外环的最小距离以及外环相邻点之间的弧长距离。若r2太小内外环容易混叠若r2太大外环相邻点变密高频段误码上升。常见试探从r2/r1 1.8 ~ 2.2开始再按最小欧氏距离做局部优化。下面代码生成星形符号并归一化function sym qam16_mod_star(bits, r1, r2) % 星形16QAM内环4点外环12点 % 索引0-3内环4-15外环 bits reshape(bits, 4, []).; idx bi2de_manual(bits); % 二进制转十进制 n length(idx); sym zeros(n,1); for k 1:n i idx(k); if i 4 ph (pi/2) * i; % 0, 90, 180, 270 sym(k) r1 * exp(1j*ph); else ph pi/12 (pi/6) * (i-4); % 外环12点 sym(k) r2 * exp(1j*ph); end end % 归一化到平均功率1 avg (4*r1^2 12*r2^2) / 16; sym sym / sqrt(avg); end function d bi2de_manual(b) d b(:,1)*8 b(:,2)*4 b(:,3)*2 b(:,4); end参数说明索引 0-3 对应内环4-15 对应外环所以编码时 4 个比特直接参与十进制换算avg按点数加权计算平均功率必须放在归一化前计算外环相位基准pi/12是相对内环的相位偏置如果改成 0内外环会有相位重合的点判决边界会变得很不自然。2.3 两种星座的功率、最小距离、PAPR 对比把矩形和星形放在同一张表里仿真前就应决定用哪些指标约束。下表是未归一化时的相对值常用来对比星座特性指标矩形星形 (r11, r22)平均功率103.25峰值功率184峰值平均功率比1.81.23最小欧氏距离2约1.04可以看出星形星座的最小欧氏距离更小理论误码率略差但 PAPR 更低对非线性功放更友好。选择哪种取决于系统瓶颈信道噪声为主时矩形更稳功放回退不足时星形更常用。MATLAB 仿真时不能只看星座图还要把归一化后的最小距离和 PAPR 打印出来用来解释两条 BER 曲线的差异。3. MATLAB 实现 16QAM 调制解调从函数到 BER 仿真3.1 矩形 16QAM 解调按 I/Q 门限判决矩形解调不需要计算全部星座距离。因为 I/Q 独立只需分别把实部和虚部量化到四个电平再反查比特。判决门限取相邻电平中点[-2 0 2]。写成代码如下function bits qam16_demod_rect(sym) lvl [-3 -1 1 3]; I real(sym) * sqrt(10); % 补偿归一化 Q imag(sym) * sqrt(10); I quantize_level(I, lvl); Q quantize_level(Q, lvl); % 反查比特 bitMap [0 0; 0 1; 1 1; 1 0]; % 与调制一致 N length(I); bits zeros(4*N, 1); for k 1:N iIdx find(lvl I(k), 1); qIdx find(lvl Q(k), 1); bits(4*(k-1)(1:4)) [bitMap(iIdx,:), bitMap(qIdx,:)]; end end function y quantize_level(x, lvl) y zeros(size(x)); for k 1:length(x) [~, pos] min(abs(x(k) - lvl)); y(k) lvl(pos); end end逻辑说明量化函数把每个接收值归到最近的电平再通过find(lvl I(k),1)找到表位置。无噪声时接收值会精确落在电平上有噪声时只要不越过门限就不会判错。sqrt(10)必须乘回来否则电平会缩小 3.16 倍判决全部错位。3.2 星形 16QAM 解调环判决加相位量化星形解调先判环再判相位。判决门限取内外半径中点(r1r2)/2但因为符号已经归一化阈值也必须按相同比例缩放。判为内环时看相位接近 0、π/2、π、3π/2 哪一个判为外环时角度先减去 π/12再量化到 12 个相位槽。角度卷绕是最容易出错的地方。function bits qam16_demod_star(sym, r1, r2) avg (4*r1^2 12*r2^2) / 16; r1 r1 / sqrt(avg); r2 r2 / sqrt(avg); thr (r1 r2) / 2; N length(sym); bits zeros(4*N, 1); for k 1:N a abs(sym(k)); if a thr ph angle(sym(k)); if ph 0, ph ph 2*pi; end ph4 round(ph / (pi/2)); % 0..3 ph4 mod(ph4, 4); idx ph4; % 0-3内环 else ph angle(sym(k)); if ph 0, ph ph 2*pi; end ph ph - pi/12; % 外环基线 ph mod(ph, 2*pi); k12 round(ph / (pi/6)); % 0..11 k12 mod(k12, 12); idx 4 k12; % 4-15外环 end b dec2bin(idx, 4) - 0; bits(4*(k-1)(1:4)) b; end end参数说明r1和r2在解调时重新归一化确保阈值与发送端一致外环相位的pi/12偏置去掉后12 点正好每 30° 一个四舍五入到最近的槽位mod对角度和索引都做卷绕避免 359° 和 1° 之间的跳变。这个解调器没有遍历星座表复杂度为 O(N)适合大批量仿真。3.3 主程序AWGN 信道下两种星形的 BER 对比把调制、信道、解调串起来。这里用加性高斯白噪声符号平均功率为 1噪声方差按10^(-snr/10)设置。最容易被忽略的是噪声复数样本的实部和虚部分别使用noise_pow/2方差。% ber_compare.m Nbits 2e5; % 总比特数 N Nbits / 4; % 符号数 snr_dB 0:4:24; ber_rect zeros(size(snr_dB)); ber_star zeros(size(snr_dB)); r1 1; r2 2; for idx 1:length(snr_dB) snr snr_dB(idx); noise_pow 10^(-snr/10); % 矩形 bits randi([0 1], Nbits, 1); sym qam16_mod_rect(bits); n sqrt(noise_pow/2) * (randn(N,1) 1j*randn(N,1)); rx sym n; bits_rx qam16_demod_rect(rx); ber_rect(idx) sum(bits ~ bits_rx) / Nbits; % 星形 bits randi([0 1], Nbits, 1); sym qam16_mod_star(bits, r1, r2); n sqrt(noise_pow/2) * (randn(N,1) 1j*randn(N,1)); rx sym n; bits_rx qam16_demod_star(rx, r1, r2); ber_star(idx) sum(bits ~ bits_rx) / Nbits; fprintf(snr%ddB rect%e star%e\n, snr, ber_rect(idx), ber_star(idx)); end semilogy(snr_dB, ber_rect, o-, snr_dB, ber_star, s-); grid on; xlabel(Es/N0 (dB)); ylabel(BER); legend(矩形,星形);逻辑说明每组星座重新生成随机比特保证不共用比特序列噪声样本每次重新生成统计上是独立的。semilogy适合画 BER 曲线因为 BER 跨度可能有多个数量级。若运行时间过长可以把Nbits降到 5e4但低信噪比下曲线平滑度会变差。4. 影响 16QAM 调制解调结果的关键参数与 MATLAB 踩坑4.1 信噪比定义Es/N0 还是 Eb/N0很多 PDF 代码把 SNR 直接当 Eb/N0 用导致两条星座的 BER 曲线不能与理论值对齐。16QAM 每符号 4 比特换算关系是Es/N0 Eb/N0 10*log10(4)约等于加 6.02 dB。前面主程序用的是 Es/N0如果想画 Eb/N0 曲线噪声方差要改成10^(-(EbN0_dB 6.02)/10)。常用换算如下目标噪声方差表达式Es/N0 SNR_dB10^(-SNR_dB/10)Eb/N0 EbN0_dB10^(-(EbN0_dB 10*log10(4))/10)与 BPSK 对比必须使用 Eb/N0矩形和星形的每符号比特数都是 4换算关系相同。修改噪声方差后BER 曲线会整体平移约 6.02 dB这是正常现象不是代码错误。4.2 星形半径比 r2/r1 对 BER 的影响半径比是星形星座的核心参数。r2 太小内外环靠在一起环判决阈值附近误码明显r2 太大外环相邻点变密中高信噪比时误码上升。可以用循环扫描 r2并同时计算最小欧氏距离找折中值。建议先写一个索引版调制函数function sym qam16_mod_star_index(idx, r1, r2) % idx: 0..15 的整数列向量 N length(idx); sym zeros(N,1); for k 1:N i idx(k); if i 4 sym(k) r1 * exp(1j * pi/2 * i); else sym(k) r2 * exp(1j * (pi/12 pi/6 * (i-4))); end end avg (4*r1^2 12*r2^2) / 16; sym sym / sqrt(avg); end function dmin star_min_distance(r1, r2) sym qam16_mod_star_index((0:15)., r1, r2); D abs(sym - sym.); D(D 0) inf; % 去掉自己到自己的距离 dmin min(D(:)); end参数说明star_min_distance计算 16 个理想点之间的全部距离取最小。扫参时把r2从 1.4 到 2.6 循环打印dmin再看对应 BER。索引调制函数与比特调制函数共享同一套映射避免两边各写一遍造成不一致。4.3 成形滤波与过采样直接符号仿真不能覆盖符号间干扰如果只做 AWGN 基带仿真加噪声直接加在符号上就够了。但真实系统需要对符号插值并用脉冲成形滤波器接收端做匹配滤波后再采样。常见做法是使用根升余弦滤波器。MATLAB 中rcosdesign属于信号处理工具箱调用前最好做存在性检查if exist(rcosdesign, file) ~ 2 error(需要 Signal Processing Toolbox 的 rcosdesign); end filterCoeff rcosdesign(0.35, 8, 8, sqrt);滚降因子 0.35 是常用起步值第一个 8 是滤波器阶数符号间隔第二个 8 是每符号采样数。滤波后接收端要把群延迟对应的样本丢弃再送到解调函数。如果跳过匹配滤波星座点会发散BER 曲线会出现明显地板效应。4.4 解调端不除以归一化因子导致误码率虚低这是从 PDF 代码里最容易看到的错误。调制端把符号除以sqrt(10)或sqrt(avg)解调端必须把归一化补回来否则判决电平整体缩小门限全部不对。更隐蔽的是星形解调thr用r1/r2计算但符号已经归一化所以必须在解调函数里重算avg并缩放半径。前文给出的是正确写法。4.5 符号同步与相位偏置的坑星形外环有固定相位偏置 π/12接收机若用 Costas 环恢复载波锁相环可能锁定在多个稳定点上导致输出星座整体旋转。仿真时不要在信道里添加任意固定相位偏置否则外环判决的pi/12基准会失效。矩形星座受相位旋转影响相对小四个角点仍能区分但星形星座对整体相位非常敏感。工程上需要在接收端先做相位估计把星座旋转回参考相位再进入环形判决。5. 用 MATLAB 画星座图和计算 EVM 验证解调结果5.1 画出矩形与星形星座的接收散点图画星座图最直接的方法是plot不需要通信工具箱。先发送一批已知符号叠加噪声后再画散点function plot_constellation(rx, titleStr) plot(real(rx), imag(rx), ., MarkerSize, 4); grid on; axis equal; xlabel(I); ylabel(Q); title(titleStr); end调用时分别用矩形和星形调制函数生成符号再叠加一个低噪声样本。axis equal必须加否则坐标轴缩放不一致圆形星座会被拉成椭圆肉眼判断会出错。5.2 计算误差向量幅度 EVMEVM 是衡量接收符号与发送符号偏差的常用指标。定义是误差向量均方根与发送符号均方根之比。因为发送符号在归一化后平均功率为 1下面的函数可以直接使用function evm_percent calc_evm(rx, tx) evm_percent sqrt(mean(abs(rx - tx).^2) / mean(abs(tx).^2)) * 100; % % end使用时要注意tx必须是发送端归一化后的符号不是比特序列。如果只想和理想星座点比较可以先解调得到每个符号的索引再用索引重构参考符号再调用calc_evm。EVM 与 BER 不是线性关系通常用 EVM 做链路调优用 BER 做最终判决。5.3 快速自检无噪声时星座图是否落在网格/环上在跑 BER 仿真前先做一次零噪声闭环测试。这一步能最快发现映射表或解调索引不一致bits randi([0 1], 4000, 1); sym_rect qam16_mod_rect(bits); bits_rect qam16_demod_rect(sym_rect); assert(isequal(bits, bits_rect)); sym_star qam16_mod_star(bits, 1, 2); bits_star qam16_demod_star(sym_star, 1, 2); assert(isequal(bits, bits_star));若assert失败优先检查星形解调的相位基准是否与调制端一致再检查矩形解调是否乘回归一化因子。无噪声闭环通过后再加噪声统计 BER这样可以把调制解调逻辑错误和数据信道错误分开定位。最后一个小技巧是把r1/r2也作为输入变量传入解调器而不是在函数内部写死这样半径扫参时才不会忘改两边。本文还有配套的精品资源点击获取

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

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

免费获取报价