
簡介本資源是一套面向通信工程專業本科生及MATLAB初學者的64QAM軟解調鏈路仿真教學包聚焦數字調制系統誤碼率性能分析這一核心實驗任務。資源包含5個文件2個主程序腳本.m、2個運行日志.log、1個操作指引.txt總大小僅5KB輕量易用其中main1.m與main2.m實現64QAM調制、AWGN信道建模、軟判決解調及BER計算全流程全部代碼配有詳盡中文注釋邏輯清晰、模塊分明配套操作視頻已通過txt文件提供觀看地址可直觀掌握MATLAB當前路徑設置、腳本運行與結果可視化關鍵步驟。已有193人學習下載特別適合課程設計、通信原理實驗復現或畢業設計前期驗證使用開箱即用無需額外依賴庫有效降低軟解調算法理解與仿真實踐門檻。1. 項目概述從理論到實踐的64QAM鏈路仿真如果你正在學習數字通信或者工作中需要評估一個通信系統的性能那么“誤碼率仿真”這個詞你一定不陌生。它就像是通信工程師的“試金石”在真正把硬件做出來之前先用軟件跑一遍看看這個設計在理論上能有多“抗造”。今天要聊的就是一個非常經典且實用的仿真案例64QAM調制結合軟解調的完整通信鏈路誤碼率仿真。我會用MATLAB作為工具帶你從零開始手把手搭建這條鏈路并解釋清楚每一個模塊背后的“為什么”。64QAM全稱64進制正交幅度調制是當前4G/5G乃至Wi-Fi等高速通信系統的核心技術之一。簡單來說它就像在一個坐標平面上精心布置了64個不同的點我們稱之為“星座點”每個點代表一個6比特的二進制組合。通過改變發射信號的幅度和相位讓它落到對應的星座點上從而在一個符號周期內傳輸6個比特效率遠高于傳統的BPSK1比特/符號或QPSK2比特/符號。但高收益伴隨著高風險64個點挨得很近對噪聲和干擾極其敏感這就對解調技術提出了更高要求。“軟解調”正是應對這一挑戰的利器。傳統的“硬判決”解調接收端看到信號后會直接“猜”它離哪個星座點最近然后輸出對應的比特0或1。這個過程是“非黑即白”的丟失了“這個猜測有多可靠”這一寶貴信息。而軟解調不同它不急于做決定而是為每一個比特計算一個“似然比”或“軟信息”這個值反映了該比特是0還是1的“置信度”。這個軟信息可以交給后續的信道譯碼器如Viterbi或LDPC譯碼器進行更智能的糾錯從而大幅提升系統在惡劣信道下的性能。可以說沒有軟解調高階QAM的實用價值將大打折扣。這個仿真項目的核心價值就在于將“64QAM調制”和“軟解調”這兩個關鍵環節串聯起來構建一個包含完整發端、信道、收端的基帶仿真模型。通過它你可以直觀地看到信號是如何從比特流變成復雜的調制信號經過噪聲“污染”后又如何被接收機盡力恢復出來并最終以“誤碼率”這個硬指標來量化系統性能。無論你是通信專業的學生想深化理解還是工程師需要驗證算法或教學這個仿真都能提供一個清晰、可操作、可修改的模板。接下來我們就深入鏈路內部看看每一個模塊究竟是如何工作的。2. 64QAM調制原理與MATLAB實現細節要仿真首先得把信號正確地產生出來。64QAM調制器是發射機的核心它的任務是把一串二進制比特流映射到我們前面提到的那個有64個點的星座圖上。2.1 星座圖映射比特到符號的“翻譯官”64QAM的星座圖通常采用矩形網格狀分布這也是最常用、能量分布最均勻的一種。具體來說在復平面的實部I路和虛部Q路方向上各取8個等間隔的電平值。例如我們可以將電平歸一化到[-7, -5, -3, -1, 1, 3, 5, 7]這8個值上這樣任意一個星座點都可以表示為a b*j其中a和b都來自這個集合。那么如何將6個比特(b5b4b3b2b1b0)映射到一個具體的(I, Q)坐標呢這里采用格雷碼映射是關鍵。格雷碼的特點是相鄰星座點所對應的二進制組合之間只有1個比特不同。這樣做的好處是當噪聲導致接收信號錯判到相鄰星座點時只會產生1個比特的錯誤而不是多個這能顯著降低誤比特率。一種常見的映射規則是將6個比特分成高3位(b5b4b3)和低3位(b2b1b0)分別用于決定I路和Q路的電平。3個比特有8種狀態正好對應8個電平。通過一個查找表將3位格雷碼映射到前述的8個電平值上。在MATLAB中我們無需手動計算每個映射可以利用qammod函數。但為了透徹理解我們可以先自己實現一遍% 參數定義 M 64; % 調制階數 k log2(M); % 每符號比特數 6 % 生成隨機比特流 numBits 10000; dataIn randi([0 1], numBits, 1); % 將比特流分組每6比特一組 dataInMatrix reshape(dataIn, k, length(dataIn)/k).; % 將二進制轉換為十進制范圍0-63 dataSymbolsIn bi2de(dataInMatrix, left-msb); % 定義歸一化的64QAM星座矩形格雷碼映射 % 使用comm.RectangularQAMModulator對象或自定義映射 % 方法1使用通信工具箱函數最簡單 if exist(qammod, file) % 注意默認的qammod可能使用非格雷碼建議指定gray映射 modSignal qammod(dataSymbolsIn, M, gray, InputType, integer, UnitAveragePower, true); else % 方法2自定義格雷碼映射教學目的 % 1. 生成格雷碼序列 graySeq 0:M-1; graySeq bitxor(graySeq, floor(graySeq/2)); % 十進制轉格雷碼 % 2. 定義歸一化星座點坐標平均功率為1 constellation qammod(0:M-1, M, UnitAveragePower, true); % 先用默認方式生成坐標 % 3. 根據格雷碼序列重新排序星座點 [~, idx] sort(graySeq); constellation constellation(idx); % 4. 映射輸入的十進制符號索引0-63對應到constellation中的值 modSignal constellation(dataSymbolsIn 1); % 1因為MATLAB索引從1開始 end注意UnitAveragePower參數設置為true至關重要。這會將星座點的平均功率歸一化為1瓦特。這樣我們在后面添加噪聲時信噪比Eb/N0或Es/N0的定義才是清晰且一致的。如果忘記歸一化計算出的噪聲功率將是錯誤的導致仿真結果完全不可信。2.2 脈沖成形與過采樣讓信號適應連續時間信道直接生成的調制符號modSignal是一個一個的離散點。但在實際信道中傳輸的是連續時間波形。脈沖成形濾波器的作用就是把這些離散的符號點“連接”成平滑的波形同時將信號的頻譜限制在一定的帶寬內避免干擾相鄰信道。最常用的脈沖是平方根升余弦滾降濾波器。這里有個關鍵概念過采樣。我們的符號速率假設是1 Baud每秒1個符號。為了用離散序列較好地表示連續波形我們需要用更高的采樣率比如每個符號采樣spsSamples Per Symbol次。sps通常為4或8。% 脈沖成形參數 sps 8; % 每個符號的采樣點數 span 10; % 濾波器的符號長度通常兩邊各span/2個符號 rolloff 0.25; % 滾降因子典型值0.2~0.5 % 設計平方根升余弦濾波器 rrcFilter rcosdesign(rolloff, span, sps, sqrt); % 對調制信號進行上采樣和濾波 % 上采樣在每個符號之間插入 sps-1 個零 upSampledSignal upsample(modSignal, sps); % 濾波 txSignal filter(rrcFilter, 1, upSampledSignal); % 注意濾波會引入群延遲長度為 (length(rrcFilter)-1)/2 個采樣點。 % 在接收端進行匹配濾波后需要去除這個延遲才能正確對齊符號進行判決。 filterDelay (length(rrcFilter) - 1) / 2;經過脈沖成形后txSignal就是一個準備好了的基帶發射信號可以送入信道模型了。這里生成的信號是復信號包含了同相I和正交Q兩路。3. 信道模型模擬現實世界的噪聲與衰落一個理想的仿真環境沒有意義我們需要引入信道損傷來檢驗系統的魯棒性。最基本的也是最重要的損傷就是加性高斯白噪聲。3.1 加性高斯白噪聲的精確添加AWGN信道是幾乎所有通信系統性能分析的起點。添加噪聲的關鍵在于根據設定的信噪比Eb/N0精確計算噪聲功率。首先明確幾個功率關系Eb每比特能量。Es每符號能量。對于64QAMEs Eb * log2(64) Eb * 6。信號平均功率我們已經通過UnitAveragePower將調制符號的平均功率歸一化為1。但經過脈沖成形濾波器后信號功率可能會發生變化。實際上一個設計良好的RRC濾波器是能量保持的輸入輸出功率基本不變。但為了絕對精確我們可以在濾波后重新測量信號功率。噪聲功率譜密度N0N0 2 * sigma^2其中sigma^2是復噪聲每個維度I或Q的方差。添加噪聲的步驟如下% 設定仿真信噪比范圍以dB為單位 EbN0_dB 0:2:16; % 例如從0dB到16dB步進2dB numSNR length(EbN0_dB); % 初始化誤碼率結果存儲 ber_soft zeros(1, numSNR); ber_hard zeros(1, numSNR); % 用于和硬判決對比 for snrIdx 1:numSNR current_EbN0_dB EbN0_dB(snrIdx); % 1. 將dB值轉換為線性值 current_EbN0 10^(current_EbN0_dB / 10); % 2. 計算每符號信噪比 Es/N0 EsN0 current_EbN0 * k; % k log2(64) 6 % 3. 計算信號功率測量濾波后信號的平均功率更準確 signalPower mean(abs(txSignal).^2); % 4. 計算所需的噪聲功率譜密度 N0 % 根據 Es/N0 signalPower / (N0 * 采樣率因子?) 需要小心。 % 在離散時間仿真中我們處理的是采樣后的信號。 % 更通用的方法是根據 Es/N0 計算每個采樣點的噪聲方差。 % 對于復基帶信號噪聲方差 sigma^2 N0 / (2 * 過采樣率?) 這里容易混淆。 % 推薦的標準方法 % 我們的符號能量 Es signalPower * 符號周期Ts。 % 在離散仿真中采樣間隔為 Ts/sps。信號序列的功率是 signalPower。 % 那么一個符號周期內的信號能量對應于 sps 個采樣點。 % 因此平均到每個采樣點上的信號“能量”是 signalPower * (Ts/sps) * sps? 這很亂。 % 最清晰、不易錯的方法從比特級別推導。 % 已知Eb/N0 (線性值) % 總比特數 numBits % 信號總能量 信號功率 * 信號持續時間。 % 信號持續時間 符號數 * 符號周期 (numBits/k) * Ts。 % 在采樣點層面信號總能量 sum(|txSignal|.^2) * (Ts/sps)。 % 令采樣間隔 T Ts/sps則總能量 sum(|txSignal|.^2) * T。 % 而總比特能量 Eb * numBits。 % 所以 sum(|txSignal|.^2) * T Eb * numBits。 % 又因為 Eb/N0 已知所以 N0 Eb / (Eb/N0)。 % 那么噪聲功率譜密度 N0 已知。 % 對于離散復高斯噪聲每個維度的方差 sigma^2 N0 / (2 * T) % 實際上對于采樣率為 fs 1/T 的系統離散噪聲序列的方差 sigma_n^2 N0 * fs / 2 N0 / (2T)。 % 為了避免混亂通信工具箱提供了最直接的函數awgn。 % 但為了理解原理我們手動計算一次 % 方法A使用 awgn 函數確保信號功率已測量 rxSignal awgn(txSignal, current_EbN0_dB 10*log10(k) - 10*log10(sps), measured); % 解釋awgn函數的第二個參數是信噪比SNR(dB)。 % 我們需要的是 Es/N0 (dB)。因為信號是過采樣的其采樣點功率不等于符號功率。 % measured 模式會根據輸入信號 txSignal 的功率計算信號功率然后添加相應功率的噪聲。 % 所以我們需要告訴它目標 Es/N0。 % Es/N0 (dB) Eb/N0 (dB) 10*log10(k) % 但 awgn 默認認為輸入參數是信號采樣點的 SNR (dB)。 % 對于過采樣信號采樣點 SNR 與 Es/N0 的關系是采樣點 SNR (dB) Es/N0 (dB) - 10*log10(sps) % 因此awgn 的目標 SNR (dB) Eb/N0_dB 10*log10(k) - 10*log10(sps) % 方法B手動添加噪聲加深理解 % 測量信號功率 sigPower mean(abs(txSignal).^2); % 計算每個采樣點的信噪比 SNR_linear (線性值) % 目標 Es/N0 (Eb/N0)*k EsN0_linear current_EbN0 * k; % 采樣點 SNR 信號功率 / 噪聲功率 (Es/Ts) / (N0 * fs) ? 需要統一。 % 更簡單噪聲功率 信號功率 / (采樣點 SNR) % 而 采樣點 SNR (線性值) EsN0_linear / sps % 因為 Es 是符號能量分散在 sps 個采樣點上每個采樣點能量為 Es/sps。 % 噪聲功率譜密度為 N0帶寬內的噪聲功率為 N0 * (1/Ts)不對。 % 對于采樣率 fs sps/Ts噪聲帶寬為 fs/2 基帶信號是復的正頻率部分帶寬為 1/(2Ts) 太復雜。 % 結論對于復基帶仿真最穩妥且通用的公式是 % 噪聲方差 sigma^2 (信號功率) / (Es/N0_linear) * (1/sps) % 但根據能量守恒符號能量 Es 信號功率 * Ts。 % 采樣點功率 Ps 信號功率。 % 采樣點噪聲方差 N0 / (2 * T_sample) N0 * fs / 2。 % 而 N0 Es / EsN0_linear。 % 所以 sigma^2 (Es / EsN0_linear) * (sps/Ts) / 2 (Ps * Ts / EsN0_linear) * (sps/Ts) / 2 Ps / (2 * EsN0_linear / sps) % 令 SNR_sample_linear EsN0_linear / sps % 則 sigma^2 Ps / (2 * SNR_sample_linear) SNR_sample_linear EsN0_linear / sps; noiseVar sigPower / (2 * SNR_sample_linear); % 復噪聲每個維度的方差 noise sqrt(noiseVar/2) * (randn(size(txSignal)) 1i*randn(size(txSignal))); % 生成復高斯噪聲 rxSignal_manual txSignal noise; % 通常使用方法Aawgn函數更簡單且不易出錯。這里為了演示我們使用 rxSignal_manual 繼續。 rxSignal rxSignal_manual; end這段代碼包含了信道添加噪聲的核心。其中最關鍵的是信噪比換算這是通信仿真中最容易出錯的地方之一。務必理解Eb/N0、Es/N0以及過采樣系統采樣點信噪比之間的關系。3.2 可選的信道損傷擴展除了AWGN一個更完整的仿真可能還需要考慮多徑衰落、相位噪聲、頻偏等。例如添加一個簡單的多徑信道% 定義一個兩徑瑞利衰落信道 channel [0.8, 0, 0, 0, 0.3]; % 主徑增益0.8延遲4個采樣點的多徑增益0.3 rxSignalMultipath filter(channel, 1, txSignal); % 注意這會引入碼間串擾 % 然后再添加噪聲 rxSignal awgn(rxSignalMultipath, ...);在初步的誤碼率仿真中通常從最簡單的AWGN信道開始因為它給出了系統性能的理論下界在無碼間串擾、無衰落的情況下。有了這個基準再引入其他損傷就能看出系統性能的下降程度。4. 接收機處理匹配濾波與定時同步信號經過信道帶著噪聲到達接收機。接收機的首要任務是從連續的、被污染的信號波形中最佳地恢復出發送的符號序列。這第一步就是匹配濾波和符號定時同步。4.1 匹配濾波最大化信噪比匹配濾波器的沖激響應是發射脈沖成形濾波器的共軛反轉。對于實系數的平方根升余弦濾波器匹配濾波器就是它本身。匹配濾波有兩個作用1. 使采樣時刻的信噪比最大化2. 與發射濾波器共同構成一個升余弦滾降濾波器從而滿足奈奎斯特第一準則在理想同步下消除碼間串擾。% 接收端匹配濾波 rxFiltered filter(rrcFilter, 1, rxSignal); % 匹配濾波同樣會引入延遲 % 總延遲是發射濾波和接收濾波延遲之和 totalDelay 2 * filterDelay; % 因為發射和接收用了同一個濾波器rrcFilter4.2 符號定時同步找到最佳采樣點經過匹配濾波后我們得到了一個波形需要在每個符號周期的特定時刻通常是最佳采樣點即波形眼圖張開最大的時刻進行采樣才能得到用于判決的符號值。在仿真中我們通常知道精確的符號定時因為是我們自己生成的所以可以理想采樣。但在實際中或更高級的仿真里需要定時同步算法。% 理想定時同步已知延遲和過采樣率 % 1. 去除濾波器引入的延遲 rxFilteredAlign rxFiltered(totalDelay1 : end); % 確保長度是sps的整數倍方便下采樣 effectiveLen floor(length(rxFilteredAlign) / sps) * sps; rxFilteredAlign rxFilteredAlign(1:effectiveLen); % 2. 下采樣在每個符號周期的中心點采樣假設理想同步 % 我們通常選擇在濾波后波形的穩定區中心采樣。對于RRC最佳采樣點就是符號間隔的中心。 % 由于我們上采樣時在符號前補零濾波后波形峰值會出現在符號周期中間。 % 因此下采樣索引可以從 (sps/2 1) 開始每隔 sps 個點取一個。 startIdx ceil(sps/2); % 例如 sps8, startIdx4 sampledSignal rxFilteredAlign(startIdx : sps : end);現在sampledSignal的長度應該等于發送的符號數(numBits/k)。這些點就是受到噪聲干擾后散布在64QAM星座圖各個理想點周圍的接收符號。接下來就要對這些點進行解調恢復出比特信息。5. 軟解調算法詳解與MATLAB實現這是本仿真的核心與難點。硬判決解調很簡單計算接收符號到64個理想星座點的歐氏距離選擇距離最小的點然后根據映射規則反解出6個比特。但軟解調需要為每一個比特輸出一個軟信息通常是該比特為0的對數似然比。5.1 對數似然比計算原理對于加性高斯白噪聲信道接收符號y在發送符號為x條件下的概率密度函數是復高斯分布。比特b_i的對數似然比定義為LLR(b_i) log( P(b_i0 | y) / P(b_i1 | y) )根據貝葉斯公式和等概發送的假設可以推導出近似公式LLR(b_i) ≈ (1/(2*sigma^2)) * [ min_{x in S_i^1} |y - x|^2 - min_{x in S_i^0} |y - x|^2 ]其中S_i^0表示所有使第i個比特為0的星座點集合S_i^1表示所有使第i個比特為1的星座點集合。sigma^2是噪聲方差每個維度。這個公式的直觀意義是對于第i個比特分別找到離接收點y最近的、該比特為0的星座點和最近的、該比特為1的星座點。計算y到這兩個點的距離平方。如果離“0點”更近差值為負LLR為負值傾向于判0反之LLR為正值傾向于判1。LLR的絕對值大小反映了判決的置信度。5.2 高效LLR計算的MATLAB實現直接按照定義計算需要遍歷集合對64QAM來說每個比特需要對64個點計算距離并比較計算量較大。對于矩形格雷碼映射的QAM可以利用其星座圖的對稱性推導出基于接收信號I、Q分量的近似LLR計算公式這能極大簡化運算。這里我們展示通用但稍慢的“最小距離”法以及更高效的分段線性近似法。方法一最小距離法通用易于理解function llr qam64_soft_demod_min_distance(y, M, sigma2) % y: 接收符號復數標量或向量 % M: 調制階數 64 % sigma2: 噪聲方差每個維度的即上面的 sigma^2 k log2(M); % 生成所有理想星座點格雷碼映射歸一化平均功率為1 constellation qammod(0:M-1, M, gray, UnitAveragePower, true); % 為每個比特預分配LLR llr zeros(length(y), k); % 對于每個接收符號 for idx 1:length(y) y_scalar y(idx); % 計算到所有星座點的距離平方 dist2 abs(y_scalar - constellation).^2; % 1x64向量 % 對于每個比特位 for bitIdx 0:k-1 % 找出該比特為0和1的星座點索引 % 需要知道格雷碼映射下每個星座點對應的比特圖案 % 我們可以反解對于 constellation 中的第m個點其對應的比特圖案是 % 因為 constellation 是按格雷碼順序排列的所以第m個點對應的整數符號就是 m-1 (0-63) % 將 m-1 轉換為 k 位二進制格雷碼順序需要先將整數轉為格雷碼再轉二進制 % 實際上我們生成 constellation 時用了 gray 選項那么 qammod 的輸入整數 0:63 就對應格雷碼索引。 % 所以符號索引 symIdx 0:63 直接對應格雷碼。 % 我們需要知道對于給定的 symIdx它的第 bitIdx 位是0還是1。 % 生成所有符號的比特矩陣 allSymbols (0:M-1).; % 格雷碼轉二進制因為我們的符號索引是格雷碼 % 格雷碼轉二進制二進制最高位等于格雷碼最高位此后每一位等于格雷碼當前位與前一位二進制異或 graySeq allSymbols; binSeq zeros(size(graySeq)); for i 1:k binSeq(:, i) bitget(graySeq, k-i1); % 先獲取格雷碼的各個位 end % 格雷碼轉二進制算法 bin zeros(size(graySeq)); bin(:,1) binSeq(:,1); % 最高位相同 for i 2:k bin(:,i) xor(binSeq(:,i), bin(:,i-1)); end % 現在 bin 是一個 M x k 的矩陣bin(m, bitIdx1) 就是符號索引 m-1 的第 bitIdx 個比特值最高位在前取決于bitget順序 % 注意bitget 默認是低位在前LSB而我們在映射時可能約定高位在前。這里需要與調制映射保持一致。 % 為了避免混亂一個更清晰但計算量大的方法是直接遍歷 % 初始化最小距離 min_dist_0 inf; min_dist_1 inf; for m 1:M sym constellation(m); dist abs(y_scalar - sym)^2; % 判斷這個星座點對應的第 bitIdx 個比特是0還是1 % 我們需要一個函數給定星座點索引 m-1返回其比特圖案按照調制時的映射規則 bits get_bits_from_symbol_index(m-1, k); % 假設有這個函數 if bits(bitIdx1) 0 if dist min_dist_0 min_dist_0 dist; end else if dist min_dist_1 min_dist_1 dist; end end end % 計算LLR llr(idx, bitIdx1) (min_dist_1 - min_dist_0) / (2*sigma2); end end end % 輔助函數根據符號索引和格雷碼映射規則返回比特數組 function bits get_bits_from_symbol_index(symIdx, k) % symIdx: 0~63 % 假設調制時使用了標準的格雷碼映射矩形星座。 % 對于矩形格雷碼映射I路和Q路獨立進行格雷碼映射。 % 將 symIdx 分解為 I路索引 (0-7) 和 Q路索引 (0-7) i_index floor(symIdx / 8); % 0~7 q_index mod(symIdx, 8); % 0~7 % 將十進制索引轉換為3位格雷碼二進制 % 注意這里的映射需要與調制器完全一致。我們假設使用自然二進制轉格雷碼。 i_gray bitxor(i_index, floor(i_index/2)); q_gray bitxor(q_index, floor(q_index/2)); % 將兩個3位格雷碼合并成6位比特高3位是I路低3位是Q路或反之需與調制器對應 bits [de2bi(i_gray, 3, left-msb), de2bi(q_gray, 3, left-msb)]; end這個方法邏輯清晰但計算復雜度是O(符號數 * 64 * 6)當仿真大量符號時非常慢。方法二分段線性近似法高效適用于矩形格雷碼QAM對于矩形格雷碼映射的QAMLLR可以近似為接收信號I、Q分量經過一個非線性函數的結果。這個函數通常可以用分段線性函數或查表來近似速度極快。MATLAB的通信工具箱函數qamdemod在指定OutputType為llr或approxllr時就采用了這種近似算法。% 使用通信工具箱進行軟解調推薦 % 首先需要知道噪聲方差 sigma2 % sigma2 的計算方法見前面信道部分 noiseVar ...; % 計算得到的噪聲方差每個維度 % 計算LLR llr qamdemod(sampledSignal, M, gray, OutputType, approxllr, ... UnitAveragePower, true, NoiseVariance, noiseVar); % 或者使用 llr后者是更精確但計算量稍大的方法。 % approxllr 使用近似公式速度更快在中等及以上信噪比下精度足夠。實操心得在實際仿真中強烈建議使用qamdemod函數進行軟解調。它不僅速度快而且經過充分優化和測試結果可靠。自己編寫最小距離法代碼主要用于教學和理解原理。在使用qamdemod時務必確保UnitAveragePower和NoiseVariance參數與調制端和信道模型完全匹配這是結果正確的關鍵。5.3 硬判決解調對比為了凸顯軟解調的優勢我們同時實現硬判決作為對比% 硬判決解調 hardDecisionSymbols qamdemod(sampledSignal, M, gray, OutputType, integer, UnitAveragePower, true); % 將符號解映射為比特流 dataOutHard de2bi(hardDecisionSymbols, k, left-msb).; dataOutHard dataOutHard(:); % 轉換為列向量 % 軟解調輸出已經是LLR可以用于后續信道譯碼。 % 如果直接對比誤碼率我們需要將LLR轉換為硬比特判決LLR0判為0LLR0判為1。 dataOutSoftBits llr 0; % 注意LLR的定義 log(P(0)/P(1))0 傾向于00 傾向于1。 dataOutSoftBits dataOutSoftBits(:);6. 誤碼率計算與仿真結果分析有了發射比特流dataIn和接收端恢復的比特流dataOutHard、dataOutSoftBits就可以計算誤碼率了。誤碼率是錯誤比特數與總比特數之比。6.1 計算與繪圖我們需要對每一個仿真信噪比EbN0_dB點進行多次蒙特卡洛仿真或者發送足夠多的比特使得誤碼率統計結果可靠例如錯誤比特數至少幾十個。% 續接前面的主循環 for snrIdx 1:numSNR % ... [前面的調制、信道、接收、解調代碼] ... % 解調完成后計算誤碼率 % 確保比較的比特流長度一致去除可能因延遲處理導致的頭尾不對齊 minLen min(length(dataIn), length(dataOutHard)); [~, ber_hard(snrIdx)] biterr(dataIn(1:minLen), dataOutHard(1:minLen)); minLenSoft min(length(dataIn), length(dataOutSoftBits)); [~, ber_soft(snrIdx)] biterr(dataIn(1:minLenSoft), dataOutSoftBits(1:minLenSoft)); % 如果需要還可以計算符號錯誤率 % ... end % 繪制誤碼率曲線 figure; semilogy(EbN0_dB, ber_hard, b-o, LineWidth, 1.5, DisplayName, 硬判決); hold on; semilogy(EbN0_dB, ber_soft, r-s, LineWidth, 1.5, DisplayName, 軟判決直接判決LLR); grid on; xlabel(Eb/N0 (dB)); ylabel(誤比特率 (BER)); title(64QAM在AWGN信道下的誤碼率性能); legend(Location, best);6.2 結果分析與理論對比運行完整的仿真后你會得到兩條曲線。軟判決的性能應該明顯優于硬判決尤其是在中高信噪比區域。為了驗證仿真代碼的正確性一個重要的步驟是與理論值進行對比。對于AWGN信道下的矩形64QAM其理論誤符號率有閉式表達式而誤比特率在格雷碼映射下可以近似為BER ≈ (1/k) * SER。我們可以將理論曲線畫在同一張圖上。% 計算64QAM的理論誤符號率AWGN相干解調 % 參考公式SER 2*(1-1/sqrt(M))*Qfunc( sqrt(3*k*EbN0_lin/(M-1)) ) * ... % (1 - (1-1/sqrt(M))*Qfunc( sqrt(3*k*EbN0_lin/(M-1)) ) ); % 更常用的近似公式 M 64; k log2(M); EbN0_lin 10.^(EbN0_dB/10); % 平均符號能量 Es k * Eb % 對于單位平均功率的星座最近鄰距離 d_min sqrt(2/(M-1)*3) 需要查標準公式。 % 使用通信工具箱函數 ser_theory berawgn(EbN0_dB, qam, M); % 注意berawgn返回的是理論誤比特率近似值 % berawgn 給出的就是格雷碼映射下的理論BER近似。 % 因此我們可以直接對比。 % 繪制理論曲線 semilogy(EbN0_dB, ser_theory, k--, LineWidth, 1.5, DisplayName, 理論 (格雷碼映射));如果仿真曲線特別是硬判決曲線與理論曲線在高信噪比時基本重合說明你的仿真鏈路搭建正確信道噪聲添加、功率歸一化等環節沒有錯誤。軟判決曲線應該位于理論曲線下方展現出編碼增益盡管這里我們沒有加信道編碼但軟信息本身提供了“內在”的增益。6.3 常見問題與調試技巧曲線不重合或形狀怪異首先檢查功率歸一化。確保調制時UnitAveragePower設置為true。檢查awgn函數中信噪比參數的換算是否正確。最可靠的調試方法是在極高信噪比如30dB下仿真此時誤碼率應趨近于0。如果還有錯誤說明是系統性的映射錯誤或同步問題。軟解調性能反而比硬判決差檢查LLR的符號定義。qamdemod輸出的LLR正負值分別對應比特0和1的置信度。在直接判決時llr 0判為1這個規則是否與你的比特映射一致可以用一個簡單例子驗證發送全零序列在極高信噪比下接收到的LLR應該全部是很大的正數判決結果應為全0。仿真速度太慢如果自己實現了最小距離軟解調速度會非常慢。對于大規模仿真務必使用內置的qamdemod函數或提前計算好查找表。另外蒙特卡洛仿真中低誤碼率點需要仿真大量比特非常耗時。可以采用“錯誤計數達到一定數目就停止”的策略來加速。星座圖可視化在調試階段繪制發射和接收的星座圖非常有幫助。figure; subplot(1,2,1); plot(real(modSignal), imag(modSignal), b.); title(發射星座圖); axis square; grid on; subplot(1,2,2); plot(real(sampledSignal), imag(sampledSignal), r.); title(接收星座圖加噪聲后); axis square; grid on;通過觀察接收星座圖可以直觀感受噪聲大小以及是否存在明顯的相位旋轉或幅度失真如果信道模型包含了這些效應。通過這個完整的64QAM軟解調鏈路仿真你不僅得到了誤碼率曲線這個最終結果更重要的是你走通了從比特到波形再到噪聲信道最后恢復出軟硬判決信息的全流程。這個模型是一個強大的基礎你可以在此基礎上輕松地修改參數如滾降因子、過采樣率、替換信道模型如瑞利衰落、或者接入真正的信道譯碼器如Viterbi譯碼器來評估級聯系統的性能。把程序模塊化寫好注釋它就是你通信算法工具箱里一件非常趁手的兵器。本文還有配套的精品資源點擊獲取