制解調(diào)仿真:MATLAB/Simulink實現(xiàn)與性能分析)
簡介這份資源面向通信原理課程學(xué)習(xí)者和數(shù)字調(diào)制技術(shù)入門研究者圍繞16QAM調(diào)制解調(diào)系統(tǒng)的建模與性能評估展開幫助讀者理解QAM的星座圖分布、調(diào)制解調(diào)原理及Simulink通信仿真流程。資源包內(nèi)含1個doc文檔約979KB以完整研究報告形式呈現(xiàn)涵蓋緒論、正交振幅調(diào)制原理、Simulink概述及仿真實驗等章節(jié)可對照學(xué)習(xí)16QAM系統(tǒng)在加噪前后的星座圖與眼圖變化并獲取不同信噪比條件下的誤碼率曲線同時包含與2DPSK系統(tǒng)的對比分析便于理解兩種調(diào)制方式在傳輸速率與抗噪性能上的差異。已有273人學(xué)習(xí)適合需要完成通信系統(tǒng)仿真作業(yè)或補充調(diào)制性能分析思路的讀者參考。1. 從一張“糊掉”的星座圖說起這套 16QAM 仿真到底能干什么第一次把 16QAM 的星座圖跑出來時我盯著屏幕上那 16 個點看了半天——加噪前整整齊齊排成 4×4 的方陣加噪后像被人用橡皮擦蹭過點全糊成一團(tuán)。當(dāng)時帶我的某導(dǎo)師只說了一句點散得越開你的系統(tǒng)越扛不住噪聲。這句話比任何公式都直觀也讓我意識到通信原理課上的誤碼率曲線原來是可以“看見”的。這套基于 MATLAB/Simulink 的 16QAM 調(diào)制解調(diào)系統(tǒng)性能研究干的就是這件事用 Simulink 搭出完整的 16QAM 收發(fā)鏈路把信號源、串并轉(zhuǎn)換、2/4 電平轉(zhuǎn)換、正交載波相乘、AWGN 信道、相干解調(diào)、電平判決、并串轉(zhuǎn)換全部連起來然后輸出加噪前后的星座圖、眼圖再掃一遍信噪比拿到誤碼率曲線最后拉一個 2DPSK 系統(tǒng)做橫向?qū)Ρ?。它適合兩類人一類是通信原理、數(shù)字通信課程里要做仿真大作業(yè)的學(xué)生照著能跑通、能改參數(shù)、能出圖另一類是剛接觸 Simulink 通信模塊集、想找一個完整鏈路當(dāng)模板的工程師拿它當(dāng)骨架往里面塞自己的信道模型或編碼模塊。關(guān)鍵詞 MATLAB、Simulink、通信原理在這套東西里不是標(biāo)簽是三個必須同時咬合的齒輪。2. 系統(tǒng)架構(gòu)拆解一條 16QAM 鏈路是怎么被切成模塊的2.1 整體信號流從二進(jìn)制比特到復(fù)平面上的 16 個點先把鏈路攤開看。發(fā)送端從伯努利二進(jìn)制信源出來經(jīng)過串并轉(zhuǎn)換拆成 I、Q 兩路每路再做 2/4 電平轉(zhuǎn)換——也就是把 2 個比特映射成 4 個電平之一-3、-1、1、3 這種等間隔取值然后分別乘上同相載波 cos(2πfct) 和正交載波 sin(2πfct)兩路相加得到 16QAM 已調(diào)信號。接收端反過來信號分成兩路各自與本地恢復(fù)的正交載波相干相乘過低通濾波后做 4/2 電平判決再并串轉(zhuǎn)換還原比特流。這條鏈路在 Simulink 里不是一整塊而是被拆成若干子系統(tǒng)Subsystem。我一般會按“信源—基帶映射—載波調(diào)制—信道—相干解調(diào)—判決—信宿”七段來切每段封一個 Subsystem好處是調(diào)試時能單獨把某一級的 Scope 拉出來看波形不用在幾百個模塊里找線。原文的目錄結(jié)構(gòu)其實已經(jīng)暗示了這種切法4.1 節(jié)講調(diào)制模塊信號源、串并轉(zhuǎn)換、2/4 電平轉(zhuǎn)換、其余模塊4.2 節(jié)講解調(diào)模塊相干解調(diào)、4/2 電平判決、并串轉(zhuǎn)換一一對應(yīng)。這里有個容易被忽略的點16QAM 的“16”指的是 16 個符號狀態(tài)每個符號攜帶 4 個比特log?164所以串并轉(zhuǎn)換是把 4 比特一組拆成 I 路 2 比特、Q 路 2 比特。很多人第一次搭的時候按 2 比特一組拆結(jié)果星座圖只有 4 個點排查半天才發(fā)現(xiàn)是進(jìn)制搞錯了。這個坑后面第 5 章還會細(xì)說。2.2 調(diào)制端三個關(guān)鍵子系統(tǒng)信源、串并轉(zhuǎn)換、2/4 電平轉(zhuǎn)換信源部分用 Bernoulli Binary Generator 就夠采樣時間設(shè)成符號周期的整數(shù)倍輸出 0/1 序列。串并轉(zhuǎn)換在 Simulink 里沒有現(xiàn)成的“16QAM 專用”模塊常見做法是用 Buffer 或者 Reshape 把串行比特流按 4 比特一組緩存再用 Selector 或 Demux 拆成兩路各 2 比特。我一般用 Buffer 設(shè) output buffer size 為 4后面接一個 Demux 輸出兩路這樣 I、Q 各拿 2 比特時序也對得上。2/4 電平轉(zhuǎn)換是整條鏈路里最“手工”的一環(huán)。Simulink 通信模塊集里有現(xiàn)成的 Rectangular QAM Modulator Baseband但原文走的是自己搭模塊的路子目的是把映射過程攤開給人看。自己搭的話核心是一張查找表2 比特輸入 00/01/10/11 對應(yīng) -3/-1/1/3 四個電平。實現(xiàn)方式可以用 Lookup Table 模塊也可以用 MATLAB Function 寫個 switch。下面這段是我常用的 MATLAB Function 寫法放在 2/4 電平轉(zhuǎn)換子系統(tǒng)里function y level_2to4(b) % 輸入 b2 比特向量取值 0/1 % 輸出 y4 電平之一格雷映射 -3/-1/1/3 idx b(1)*2 b(2); % 把 2 比特拼成 0~3 的索引 switch idx case 0 y -3; % 00 - -3 case 1 y -1; % 01 - -1 case 2 y 1; % 10 - 1 case 3 y 3; % 11 - 3 end end邏輯說明b(1)*2 b(2)把兩個比特按高位、低位拼成一個 0 到 3 的整數(shù)switch 再把它映射到四個等間隔電平。參數(shù)上唯一要盯的是映射順序——這里用的是格雷映射相鄰電平只差 1 個比特目的是讓噪聲導(dǎo)致的相鄰符號誤判只錯 1 比特降低誤比特率。如果你改成自然二進(jìn)制映射星座圖看著一樣但誤碼率曲線會整體右移這是很多人對不上理論曲線的原因之一。提示電平取值 -3/-1/1/3 對應(yīng)平均功率 5歸一化后也可以寫成 -3/√10 這類形式。Simulink 里如果后面接了 AWGN 模塊注意信噪比的參考功率設(shè)置要和你的電平幅度匹配否則測出來的誤碼率會整體偏移。2.3 載波調(diào)制與信道正交相乘、AWGN 加噪的位置兩路電平信號分別乘 cos 和 sin 載波這一步用 Product 模塊加 Sine Wave 源就能搭。載波頻率要滿足采樣定理Simulink 里離散仿真時載波頻率和采樣率的關(guān)系要算清楚如果符號速率是 Rs載波頻率 fc 一般取 Rs 的整數(shù)倍采樣率至少 2fc 以上否則正弦波在離散點上會失真。我一般把采樣率設(shè)成 fc 的 8 到 16 倍波形看著才順。AWGN Channel 模塊的位置很關(guān)鍵。它應(yīng)該加在兩路相加之后、接收端相干解調(diào)之前也就是模擬信道對已調(diào)信號的污染。有人圖省事把噪聲直接加在基帶電平上星座圖看著也會散但那是基帶等效模型和真實載波傳輸?shù)难蹐D對不上。原文要出“加噪前后的星座圖”和“眼圖”噪聲必須加在已調(diào)信號上接收端解調(diào)后再觀察星座點這樣散開的點才對應(yīng)真實的信道損傷。AWGN 模塊里有兩個參數(shù)要盯Eb/No 模式和 SNR 模式。做誤碼率曲線時用 Eb/No 更規(guī)范因為它和調(diào)制階數(shù)解耦換 16QAM 還是 2DPSK 都能直接比。模塊里的“Input signal power”如果選 Measured 就自動測選 Port 就外部輸入我一般選 Measured但前提是仿真跑夠長功率估計才穩(wěn)。2.4 解調(diào)端相干解調(diào)、4/2 判決與并串還原接收端先把已調(diào)信號分成兩路分別乘本地 cos 和 sin再過低通濾波器。低通濾波器的截止頻率要卡在符號速率附近太高噪聲濾不干凈太低會把有用信號邊沿磨平眼圖閉合。我一般用 Butterworth 低通階數(shù) 4 到 6截止頻率取 0.8 到 1 倍符號速率具體看眼圖調(diào)。4/2 電平判決本質(zhì)是四個門限-2、0、2。輸入電平落在哪個區(qū)間就判成對應(yīng)的 2 比特。實現(xiàn)上可以用 Quantizer 加 Lookup也可以直接寫 MATLAB Functionfunction b decide_4to2(y) % 輸入 y帶噪聲的 4 電平信號 % 輸出 b判決出的 2 比特 if y -2 b [0 0]; % 判為 -3 elseif y 0 b [0 1]; % 判為 -1 elseif y 2 b [1 0]; % 判為 1 else b [1 1]; % 判為 3 end end門限 -2/0/2 正好落在相鄰理想電平的中點這是最大似然判決在等概、等間隔星座下的簡化形式。判決完兩路各 2 比特用 Mux 拼成 4 比特再經(jīng)并串轉(zhuǎn)換還原成串行比特流最后和發(fā)送端延遲對齊后送進(jìn) Error Rate Calculation 模塊算誤碼率。延遲對齊這一步經(jīng)常被忘信源和信宿之間因為濾波、判決會差若干采樣點不對齊的話誤碼率永遠(yuǎn)是 0.5 左右看著像系統(tǒng)完全失效其實是比對錯位了。3. 從零跑通建模、參數(shù)配置與出圖流程3.1 環(huán)境準(zhǔn)備與模型文件組織這套東西依賴 MATLAB 和 Simulink原文用的是 MATLAB 7.9 / Simulink 4.0 這一代現(xiàn)在新版本打開老 .mdl 文件可能會提示升級點升級一般能跑但個別模塊參數(shù)名變了要手動核對。我的習(xí)慣是新建一個工程文件夾里面放三樣?xùn)|西模型文件.slx 或 .mdl、初始化腳本.m負(fù)責(zé)把符號速率、載波頻率、信噪比掃描范圍這些參數(shù)一次性 load 進(jìn)工作區(qū)、以及一個出圖腳本跑完仿真后統(tǒng)一畫星座圖、眼圖、誤碼率曲線。初始化腳本大概長這樣% init_params.m —— 仿真參數(shù)統(tǒng)一入口 Rs 1e6; % 符號速率 1 MHz fc 4e6; % 載波頻率 4 MHz fs 32e6; % 采樣率取 fc 的 8 倍 M 16; % 16QAM k log2(M); % 每符號比特數(shù) 4 EbNo_dB 0:2:12; % 信噪比掃描范圍 simTime 0.01; % 單次仿真時長把這些參數(shù)寫進(jìn)腳本而不是散落在各個模塊對話框里好處是換一套參數(shù)只改一處跑信噪比掃描時用 for 循環(huán)改EbNo_dB再sim就行。我見過有人每個模塊手填數(shù)字改一次符號速率要開十幾個對話框血淚經(jīng)驗別這么干。3.2 搭建調(diào)制解調(diào)鏈路的操作順序搭模型建議按信號流方向一段一段來每搭完一段就接一個 Scope 看波形別一口氣連完再調(diào)。順序是先放 Bernoulli 信源和 Buffer/Demux確認(rèn)輸出是 4 比特一組、I/Q 各 2 比特再接兩個 2/4 電平轉(zhuǎn)換子系統(tǒng)用 Display 模塊看輸出是不是 -3/-1/1/3然后接載波相乘和加法Scope 看已調(diào)波形是不是幅度和相位都在變接著放 AWGN對比加噪前后波形最后搭解調(diào)端逐級看低通輸出、判決輸出、并串輸出。每段的采樣時間要統(tǒng)一。Simulink 里離散模塊的 Sample time 參數(shù)如果留 -1 表示繼承混用連續(xù)和離散模塊時容易出現(xiàn)采樣率不匹配的報錯。我的做法是全局用離散采樣所有源模塊顯式寫1/fs這樣時序一目了然。3.3 星座圖、眼圖與誤碼率曲線的出圖方法星座圖在 Simulink 里可以用 Constellation Diagram 模塊直接接在解調(diào)端低通輸出后面它會自動把 I/Q 兩路畫到復(fù)平面。要對比加噪前后就在 AWGN 前后各接一個或者跑兩次仿真分別存圖。眼圖用 Eye Diagram 模塊接在判決前橫軸是時間、縱軸是幅度眼張開程度直接反映定時和噪聲余量。誤碼率曲線建議用腳本跑循環(huán)而不是手動改一次信噪比跑一次% run_ber_sweep.m —— 掃信噪比出誤碼率 ber zeros(size(EbNo_dB)); for i 1:length(EbNo_dB) EbNo EbNo_dB(i); out sim(qam16_model.slx); % 跑一次仿真 ber(i) out.BER(end); % 取 Error Rate 模塊輸出 end semilogy(EbNo_dB, ber, o-); grid on; xlabel(Eb/No (dB)); ylabel(BER);這里out.BER來自 Error Rate Calculation 模塊勾選“輸出到工作區(qū)”。仿真時長要夠長低信噪比下誤碼率在 1e-3 量級時至少要有上萬個符號才能統(tǒng)計穩(wěn)定否則曲線抖得沒法看。我一般讓simTime對應(yīng) 1e5 個符號以上跑一次幾分鐘掃 7 個點半小時左右能接受。3.4 2DPSK 對照系統(tǒng)的搭建要點原文最后拿 2DPSK 做對比目的是說明 16QAM 在頻譜效率上的優(yōu)勢。2DPSK 鏈路簡單得多差分編碼、BPSK 調(diào)制、相干或差分檢測、差分譯碼。Simulink 里可以用 DPSK Modulator Baseband 直接搭也可以用邏輯模塊手搭差分編碼。對比時要注意公平性——兩者要在相同 Eb/No 下比且 16QAM 的符號速率和 2DPSK 的比特速率關(guān)系要換算清楚否則誤碼率曲線的橫軸對不齊結(jié)論就站不住。原文得出的“16QAM 相對優(yōu)越”是在頻譜效率意義上說的同樣的帶寬下 16QAM 傳的比特數(shù)是 2DPSK 的兩倍代價是抗噪門限高幾個 dB這個 trade-off 在曲線上看得很清楚。4. 核心模塊代碼與參數(shù)逐段講透4.1 串并轉(zhuǎn)換的位寬與時序?qū)R串并轉(zhuǎn)換看著簡單翻車率卻不低。Buffer 模塊的 output buffer size 設(shè) 4但它的輸出是 4 維向量后面 Demux 要設(shè)成 [2 2] 才能拆成兩路各 2 比特。如果 Demux 設(shè)成 2它會把 4 維向量拆成兩個 2 維向量正好對如果設(shè)錯成 4就變成 4 路單比特后面電平轉(zhuǎn)換直接報維度錯誤。時序上Buffer 會引入 4 個采樣周期的延遲接收端并串轉(zhuǎn)換后比對時要把這個延遲算進(jìn)去Error Rate 模塊的 Receive delay 參數(shù)就是干這個的。我一般會在信源后加一個原始比特的“參考支路”經(jīng)過同樣的延遲鏈后和接收端比對而不是直接拿信源輸出比。這樣延遲對齊是結(jié)構(gòu)性的不依賴手填數(shù)字換采樣率也不用改。4.2 電平映射與格雷碼為什么映射順序影響誤碼率前面給的level_2to4用的是格雷映射。為什么強調(diào)這個因為 16QAM 星座里相鄰點只差一個電平噪聲讓判決落到隔壁點時格雷映射保證只錯 1 比特自然二進(jìn)制映射可能錯 2 比特甚至更多。理論誤比特率和誤符號率的關(guān)系是 Pb ≈ Ps/log?M格雷映射、高信噪比下如果映射錯了這個關(guān)系不成立你測出來的曲線和教科書對不上還以為是仿真錯了。驗證方法很直接固定 Eb/No10dB分別用格雷和自然二進(jìn)制映射跑一次看誤比特率差多少。格雷映射應(yīng)該明顯低一截。這個對比我建議每個搭 16QAM 的人都做一遍比看十頁公式管用。4.3 相干解調(diào)的載波同步假設(shè)與濾波器設(shè)計這套仿真里接收端載波和發(fā)送端是“理想同步”的——直接用同一個頻率的 Sine Wave相位也對齊。這是仿真簡化的常見做法目的是先隔離出噪聲對性能的影響把載波恢復(fù)、定時恢復(fù)這些單獨拎出去。真實系統(tǒng)里載波有頻偏相偏需要 Costas 環(huán)或判決反饋環(huán)來恢復(fù)那是另一個話題。看這篇的讀者如果要做更接近實際的仿真可以在接收端載波上加一個小的頻偏比如 fc 的 1e-4觀察星座圖旋轉(zhuǎn)再補一個載波恢復(fù)模塊。低通濾波器的設(shè)計直接影響眼圖。截止頻率取符號速率的 0.8 倍時眼圖張開但碼間干擾略大取 0.5 倍時噪聲濾得干凈但邊沿變緩。我一般先用 0.8 倍跑看眼圖如果閉合明顯再往下調(diào)。濾波器階數(shù)太高會引入額外延遲記得在延遲對齊里算進(jìn)去。4.4 誤碼率統(tǒng)計模塊的配置陷阱Error Rate Calculation 模塊有三個參數(shù)容易設(shè)錯Receive delay、Computation mode、Output data。Receive delay 前面說了要對齊收發(fā)延遲Computation mode 選“Entire frame”是整幀統(tǒng)計選“Running”是滑動統(tǒng)計做誤碼率曲線用 Entire frame 更穩(wěn)Output data 要選“Port”或“Workspace”不然腳本拿不到數(shù)。還有一個隱藏坑模塊的“Stop simulation”選項如果勾了誤碼數(shù)到閾值就停掃低信噪比時可能提前終止曲線缺尾。我一般關(guān)掉它靠仿真時長控制。5. 避坑與排查五個真實踩過的坑5.1 星座圖只有 4 個點現(xiàn)象跑出來星座圖是 4 個點而不是 16 個。原因串并轉(zhuǎn)換按 2 比特一組拆I/Q 各 1 比特電平轉(zhuǎn)換只出 2 個電平組合起來 2×24 個狀態(tài)。解決確認(rèn) Buffer 的 output buffer size 是 4Demux 輸出兩路各 2 比特電平轉(zhuǎn)換是 2 比特進(jìn) 4 電平出。進(jìn)制和比特數(shù)的換算 log?164 要刻在腦子里。5.2 誤碼率恒為 0.5現(xiàn)象不管信噪比多高誤碼率都在 0.5 附近。原因收發(fā)比特流沒對齊Error Rate 模塊在拿發(fā)送端第 n 個比特和接收端第 nk 個比特比等于隨機比對。解決算清楚 Buffer、濾波器、判決引入的總延遲填進(jìn) Receive delay或者用參考支路做結(jié)構(gòu)性對齊。這個坑我踩過兩次第二次是因為換了濾波器階數(shù)忘了改延遲。5.3 眼圖完全閉合現(xiàn)象眼圖看不到張開。原因低通濾波器截止頻率太低或者采樣率不夠?qū)е螺d波失真或者判決前信號幅度沒歸一化。解決先把濾波器截止頻率提到符號速率附近看眼圖是否張開再逐步往下調(diào)檢查采樣率是否至少 2 倍載波頻率確認(rèn) AWGN 的輸入功率參考沒設(shè)錯噪聲壓過了信號。5.4 仿真跑得極慢現(xiàn)象一次仿真要十幾分鐘。原因采樣率設(shè)得過高比如 fs 取 fc 的 100 倍或者仿真時長對應(yīng)符號數(shù)過多或者用了連續(xù)求解器跑離散系統(tǒng)。解決采樣率取 fc 的 8 到 16 倍夠用誤碼率統(tǒng)計用 1e5 符號量級不要盲目加長求解器選離散Discrete并指定固定步長比變步長快一個數(shù)量級。5.5 新舊版本打開模型報模塊參數(shù)錯誤現(xiàn)象老 .mdl 在新 MATLAB 里打開某些模塊標(biāo)紅。原因模塊庫升級后參數(shù)名或端口變了比如通信模塊集里 QAM 相關(guān)模塊的歸一化方式改過。解決讓 Simulink 自動升級然后逐個檢查標(biāo)紅模塊的參數(shù)對話框?qū)φ债?dāng)前版本文檔重設(shè)實在不行就用基礎(chǔ)模塊Product、Sum、Lookup Table重搭反而更可控。6. 二次開發(fā)把這套仿真改成你自己的性能評估平臺這套東西的價值不在“跑出一張圖”而在它是個可擴展的骨架。我拿它改過幾個方向說兩個最實用的。第一個方向是換調(diào)制階數(shù)做橫向?qū)Ρ?。?2/4 電平轉(zhuǎn)換換成 4/16 電平轉(zhuǎn)換對應(yīng) 64QAM星座圖變 8×8誤碼率曲線整體右移。改的時候注意三點Buffer 的 buffer size 從 4 改成 6log?646電平查找表從 4 項擴到 8 項AWGN 的 Eb/No 參考要重新核對。改完把 16QAM 和 64QAM 的曲線畫在一張圖上頻譜效率和抗噪能力的 trade-off 一目了然寫報告或做方案對比直接能用。第二個方向是加信道編碼。在信源和串并轉(zhuǎn)換之間插一個卷積編碼器接收端并串轉(zhuǎn)換后接 Viterbi 譯碼就變成編碼 16QAM。這時候誤碼率曲線會出現(xiàn)“瀑布”下降編碼增益在 10?? 量級能有幾個 dB。注意編碼會引入額外延遲Receive delay 要重算另外編碼后的比特速率變了Eb/No 的定義要按編碼后的符號能量折算不然對比不公平。改造點改動模塊關(guān)鍵參數(shù)驗證方法64QAM電平轉(zhuǎn)換、Bufferbuffer size 6、8 電平表星座圖 64 點、BER 右移卷積編碼信源后加編碼器碼率 1/2、約束長度 7BER 瀑布曲線、編碼增益載波頻偏接收端載波源頻偏 1e-4·fc星座圖旋轉(zhuǎn)、加恢復(fù)后收斂多徑信道AWGN 后加多徑兩徑時延、增益比眼圖閉合、均衡后恢復(fù)驗證方法我一般固定一套流程先看星座圖點數(shù)對不對再看眼圖張不張最后掃誤碼率曲線和理論值或已知結(jié)果對。三步都過才算改對。有一次我改 64QAM 忘了改 Buffer 位寬星座圖出來是 16 個點盯著看了十分鐘才反應(yīng)過來是位寬沒跟上——從那以后我每次改調(diào)制階數(shù)都強制先把“比特數(shù)—電平數(shù)—星座點數(shù)”這三個數(shù)在紙上寫一遍再動手。希望這套骨架到你手里也能少走幾個我走過的彎路幫到你。本文還有配套的精品資源點擊獲取