處理實(shí)戰(zhàn):濾波、調(diào)制解調(diào)與小波分析全鏈路解析)
做信號(hào)處理的工程師大概都有同感MATLAB不是萬(wàn)能的但沒(méi)有MATLAB的科研生活是萬(wàn)萬(wàn)不能的。尤其是濾波、調(diào)制解調(diào)、小波分析這三大塊幾乎覆蓋了從通信鏈路仿真到故障特征提取的絕大多數(shù)場(chǎng)景。這篇文章我想把這三塊內(nèi)容串起來(lái)講不是單獨(dú)堆幾個(gè)函數(shù)調(diào)用而是從實(shí)際工程項(xiàng)目怎么思考問(wèn)題開(kāi)始把設(shè)計(jì)邏輯、參數(shù)選擇、踩過(guò)的坑都攤開(kāi)說(shuō)清楚。無(wú)論你是剛開(kāi)始接觸數(shù)字信號(hào)處理的學(xué)生還是正在做通信系統(tǒng)或狀態(tài)監(jiān)測(cè)的工程師里面的代碼思路和調(diào)試方法應(yīng)該都能直接拿過(guò)去用。整個(gè)項(xiàng)目的核心其實(shí)就一句話用一個(gè)統(tǒng)一的MATLAB環(huán)境把“信號(hào)怎么來(lái)—怎么把干擾濾掉—怎么搬上載波—怎么用解調(diào)取回信息—怎么用更精細(xì)的時(shí)頻分析找特征”這整條鏈路打通。很多人單獨(dú)學(xué)濾波器的時(shí)候很明白單獨(dú)做調(diào)制解調(diào)也能跑通但一旦把三者放進(jìn)同一個(gè)項(xiàng)目里就會(huì)出現(xiàn)各種銜接問(wèn)題濾波器延遲導(dǎo)致解調(diào)符號(hào)錯(cuò)位小波去噪把調(diào)制包絡(luò)削沒(méi)了頻譜畫(huà)出來(lái)和理論對(duì)不上。這些恰恰是實(shí)際工程里最常見(jiàn)的痛點(diǎn)我會(huì)在后面一一展開(kāi)。1. 項(xiàng)目整體怎么拆三大模塊其實(shí)是一條鏈路1.1 為什么非要用MATLAB搭信號(hào)處理環(huán)境說(shuō)句實(shí)話Python生態(tài)現(xiàn)在很強(qiáng)NumPy、SciPy都能做但MATLAB在信號(hào)處理領(lǐng)域至今依然有它不可替代的地方一個(gè)是調(diào)參反饋極快designfilt拉一個(gè)界面改截止頻率、階數(shù)波形立刻刷新另一個(gè)是工具箱統(tǒng)一通信工具箱、小波工具箱、DSP System Toolbox全都基于同一套數(shù)據(jù)結(jié)構(gòu)和采樣率體系變量類型不打架仿真結(jié)果直接對(duì)應(yīng)到Simulink工程。就拿濾波來(lái)說(shuō)MATLAB里可以一行代碼完成FIR帶通濾波器設(shè)計(jì)再用fvtool看幅頻響應(yīng)和群延遲這種所見(jiàn)即所得的調(diào)試體驗(yàn)在項(xiàng)目前期確定方案時(shí)能節(jié)省相當(dāng)多時(shí)間。更重要的是調(diào)制解調(diào)、小波去噪這些模塊在MATLAB里都有高度封裝好的函數(shù)但封裝并不意味黑盒我們可以通過(guò)輸入輸出數(shù)據(jù)反推中間過(guò)程這也是做全鏈路仿真時(shí)最舒服的一點(diǎn)。1.2 三個(gè)模塊在項(xiàng)目里的實(shí)際分工很多初學(xué)者會(huì)把這三個(gè)模塊看成三個(gè)獨(dú)立練習(xí)濾波是去噪調(diào)制解調(diào)是通信小波分析是另一種去噪/特征提取。但在真實(shí)項(xiàng)目里它們是串在一起的。以我常做的一個(gè)通信接收機(jī)前端模擬項(xiàng)目為例發(fā)射端先做基帶調(diào)制得到復(fù)數(shù)基帶信號(hào)后要經(jīng)過(guò)一個(gè)成型濾波器然后上變頻到中頻接收端第一步是帶通濾波把帶外噪聲和鄰道干擾去掉再下變頻回基帶之后用匹配濾波和載波同步把符號(hào)恢復(fù)出來(lái)。整個(gè)過(guò)程中的每一個(gè)環(huán)節(jié)都會(huì)引入畸變而小波分析就在這里起作用——它既可以用小波閾值去噪平滑信號(hào)包絡(luò)也可以用連續(xù)小波變換做時(shí)頻圖看看符號(hào)跳變的位置和頻點(diǎn)漂移情況。這個(gè)鏈路里濾波解決的是“能不能看清”調(diào)制解調(diào)解決的是“信息怎么傳”小波分析解決的是“特征怎么抓”。三者合在一起才是一個(gè)完整的信號(hào)處理項(xiàng)目而不是孤立的函數(shù)演示。2. 濾波實(shí)戰(zhàn)從選型到參數(shù)落地2.1 FIR還是IIR關(guān)鍵看群延遲和實(shí)時(shí)性濾波器設(shè)計(jì)第一步不是寫(xiě)代碼而是回答一個(gè)問(wèn)題這個(gè)濾波器用在什么環(huán)節(jié)允許多大的相位畸變IIR濾波器比如Butterworth、Chebyshev的優(yōu)點(diǎn)是相同階數(shù)下過(guò)渡帶更陡計(jì)算量小。但它的相位是非線性的也就是說(shuō)信號(hào)里不同頻率分量經(jīng)過(guò)濾波器后延遲不一樣波形會(huì)被拉歪。這個(gè)特性在語(yǔ)音、生物電等“波形形狀”有意義的場(chǎng)景里非常致命。FIR濾波器則能實(shí)現(xiàn)嚴(yán)格線性相位群延遲恒定波形不會(huì)畸變?nèi)秉c(diǎn)是同樣性能下階數(shù)高延遲大適合離線處理和允許延時(shí)存在的場(chǎng)景。我一般的原則是如果做包絡(luò)檢波、調(diào)制信號(hào)恢復(fù)這類對(duì)相位敏感的工作優(yōu)先選FIR如果做的是頻譜監(jiān)測(cè)、指標(biāo)粗測(cè)且資源受限選IIR也能接受。這個(gè)原則在MATLAB里體現(xiàn)得很直接fir1、firpm設(shè)計(jì)FIRbutter、cheby1設(shè)計(jì)IIR這條線要分清否則后面解調(diào)出來(lái)的眼圖一塌糊涂你根本不知道是濾波器的問(wèn)題還是同步的問(wèn)題。2.2 低通濾波器設(shè)計(jì)的具體步驟假設(shè)有一個(gè)中頻信號(hào)載波頻率是5kHz采樣率50kHz信號(hào)帶寬2kHz要濾出基帶部分。最直接的方法是設(shè)計(jì)一個(gè)低通濾波器通帶截止頻率設(shè)在2.5kHz阻帶起始頻率設(shè)在3.5kHz左右。代碼里我會(huì)這樣寫(xiě)fs 50e3; fp 2.5e3; % 通帶邊界 fst 3.5e3; % 阻帶邊界 Ap 0.5; % 通帶最大衰減 dB Ast 40; % 阻帶最小衰減 dB % 用designfilt一步到位 d designfilt(lowpassfir, ... PassbandFrequency, fp, ... StopbandFrequency, fst, ... PassbandRipple, Ap, ... StopbandAttenuation, Ast, ... SampleRate, fs); fvtool(d, Fs, fs);這一步做完fvtool會(huì)彈出幅頻響應(yīng)、零極點(diǎn)圖和群延遲圖。設(shè)計(jì)完不要急著用先看三個(gè)指標(biāo)通帶有沒(méi)有掉下去、阻帶衰減夠不夠、群延遲在通帶內(nèi)是不是一根平線。這三個(gè)沒(méi)問(wèn)題再用filter函數(shù)實(shí)際濾波。要注意designfilt返回的是濾波器對(duì)象filter(d, x)可以直接對(duì)信號(hào)濾波。如果是離線仿真我更推薦用filtfilt做零相位濾波因?yàn)樗鼤?huì)正向反向各濾一次群延遲相互抵消。filtfilt的問(wèn)題是不能實(shí)時(shí)使用且信號(hào)長(zhǎng)度不能太短但在MATLAB離線分析里它的波形保真度比f(wàn)ilter好很多。2.3 濾波器階數(shù)、頻率分辨率與邊界效應(yīng)一個(gè)隱藏很深的坑是濾波器階數(shù)過(guò)高帶來(lái)的數(shù)值不穩(wěn)定。比如用butter設(shè)計(jì)一個(gè)30階的低通IIR濾波器看起來(lái)頻譜很完美但在16位定點(diǎn)環(huán)境下系數(shù)量化誤差可能導(dǎo)致濾波器變成一個(gè)振蕩器。MATLAB里可以用tf2sos把傳遞函數(shù)轉(zhuǎn)成二階節(jié)級(jí)聯(lián)再用sosfilt濾波數(shù)值穩(wěn)定性會(huì)好很多。另一個(gè)問(wèn)題是濾波后的邊緣效應(yīng)。filter函數(shù)計(jì)算時(shí)初始狀態(tài)為零信號(hào)開(kāi)頭幾個(gè)采樣點(diǎn)的輸出會(huì)有一段瞬態(tài)過(guò)程不影響穩(wěn)態(tài)但如果后面做解調(diào)符號(hào)判決開(kāi)頭那幾十個(gè)符號(hào)就被污染了。我的習(xí)慣是把信號(hào)前后各加一段零濾完波再截掉或者用filtfilt避免相位突變。這個(gè)細(xì)節(jié)在綜合項(xiàng)目里非常關(guān)鍵稍微偷懶誤碼率就會(huì)莫名升高。3. 調(diào)制解調(diào)全流程從基帶到誤碼率曲線3.1 調(diào)制方式怎么選ASK、FSK、PSK還是QAM調(diào)制解調(diào)是通信系統(tǒng)仿真的主戰(zhàn)場(chǎng)。MATLAB通信工具箱里pskmod、qammod、fskmod這幾個(gè)函數(shù)對(duì)應(yīng)不同調(diào)制格式。選哪種不能只看速率還要看信道環(huán)境和解調(diào)復(fù)雜度。ASK實(shí)現(xiàn)最簡(jiǎn)單但抗噪聲性能最差通常用于光纖和射頻標(biāo)簽這類信道穩(wěn)定的場(chǎng)景。FSK對(duì)幅度衰落不敏感適合無(wú)線傳感器和淺海聲通信。PSK和QAM則兼顧頻譜效率和誤碼性能BPSK、QPSK是通信原理課程的絕對(duì)主角16QAM、64QAM則用在寬帶無(wú)線鏈路里。我在做仿真時(shí)通常先畫(huà)一個(gè)星座圖把理想符號(hào)點(diǎn)、加噪聲后的接收符號(hào)、經(jīng)過(guò)均衡后的符號(hào)都疊在一起看。這個(gè)習(xí)慣比任何理論分析都直觀星座圖從一團(tuán)云變成清晰的四個(gè)點(diǎn)說(shuō)明解調(diào)鏈路的每個(gè)模塊都對(duì)齊了。MATLAB里用scatterplot就可以畫(huà)省事得很。3.2 用MATLAB實(shí)現(xiàn)BPSK調(diào)制解調(diào)下面給一個(gè)完整的BPSK仿真流程包含發(fā)送、加噪、匹配濾波、判決和誤碼率統(tǒng)計(jì)。% 參數(shù) fs 100e3; % 采樣率 fc 20e3; % 載波頻率 Rs 1e3; % 符號(hào)速率1kHz sps fs / Rs; % 每個(gè)符號(hào)的采樣數(shù) N 10000; % 符號(hào)數(shù) % 隨機(jī)數(shù)據(jù)與調(diào)制 data randi([0 1], N, 1); % BPSK映射0--1, 1-1 symbols 2 * data - 1; % 成型濾波升余弦 rrc rcosdesign(0.35, 6, sps, sqrt); up_sig upsample(symbols, sps); tx_sig filter(rrc, 1, up_sig); % 上變頻 t (0:length(tx_sig)-1) / fs; carrier cos(2 * pi * fc * t); tx tx_sig .* carrier.; % 信道加噪 snr 10; rx awgn(tx, snr, measured); % 接收下變頻 低通濾波 rx_baseband rx .* carrier.; d_lp designfilt(lowpassfir, ... PassbandFrequency, Rs * 2, ... StopbandFrequency, Rs * 4, ... PassbandRipple, 0.5, ... StopbandAttenuation, 40, ... SampleRate, fs); rx_filtered filtfilt(d_lp, rx_baseband); % 匹配濾波 采樣判決 rx_sampled filter(rrc, 1, rx_filtered); t_sample rrc.NormalizationDelay * rrc.FilterSpanInSymbols; % 找到最佳采樣點(diǎn)位置 offset floor(t_sample / 2); samples rx_sampled(offset (1:sps:end) * sps); demod real(samples) 0; % 誤碼率 err sum(data ~ demod(1:length(data))); BER err / N;這段代碼有幾個(gè)必須敲黑板的地方。第一upsample之后要加成型濾波器不然信號(hào)帶寬超過(guò)奈奎斯特限制會(huì)引入碼間串?dāng)_。第二接收端必須再做一次匹配濾波和發(fā)送端的根升余弦濾波器完全一致才能獲得最大信噪比。第三采樣點(diǎn)位置不能隨便取必須根據(jù)濾波器的群延遲算出來(lái)否則誤碼率會(huì)高到離譜。對(duì)了awgn的‘measured’參數(shù)會(huì)自動(dòng)按信號(hào)功率生成噪聲這個(gè)是最不容易出錯(cuò)的做法。3.3 載波同步與定時(shí)同步的工程細(xì)節(jié)上面例子假設(shè)接收端知道載波相位和符號(hào)時(shí)序這是理想情況。真實(shí)系統(tǒng)里載波頻率偏移和相位偏移會(huì)讓星座圖整體旋轉(zhuǎn)定時(shí)偏差會(huì)讓采樣點(diǎn)落在碼元邊緣。MATLAB里可以用comm.CarrierSynchronizer和comm.SymbolSynchronizer這兩個(gè)通信工具箱對(duì)象來(lái)做同步。前者基于判決引導(dǎo)的鎖相環(huán)后者基于Gardner算法或Mueller-Muller算法。調(diào)它們的時(shí)候環(huán)路帶寬是關(guān)鍵帶寬太小鎖得慢帶寬太大噪聲大我通常先從環(huán)路增益0.01開(kāi)始摸索觀察星座圖收斂情況再微調(diào)。如果只是離線仿真我會(huì)用更粗暴但有效的方法先做FFT估算載波頻偏再用相關(guān)法找最佳采樣相位。和完整同步環(huán)路相比這種一次性的估計(jì)在短數(shù)據(jù)處理里更穩(wěn)定也不容易出現(xiàn)環(huán)路失鎖的問(wèn)題。4. 小波分析頻譜圖之外的另一雙眼睛4.1 為什么有了FFT還要用小波FFT告訴我們信號(hào)里有哪些頻率成分但丟失了“這些頻率出現(xiàn)在什么時(shí)候”的信息。短時(shí)傅里葉變換STFT能彌補(bǔ)一部分但窗口固定之后時(shí)間和頻率分辨率就鎖死了低頻需要長(zhǎng)窗口、高頻需要短窗口這對(duì)矛盾永遠(yuǎn)解決不了。小波變換的聰明之處在于用可伸縮的窗函數(shù)低頻自動(dòng)變寬高頻自動(dòng)變窄這正是時(shí)頻分析需要的自適應(yīng)能力。在MATLAB里cwt函數(shù)做連續(xù)小波變換可以直接畫(huà)出時(shí)頻圖wavedec做離散小波分解。這兩個(gè)工具的適用場(chǎng)景不一樣cwt適合看信號(hào)的全貌比如某種瞬態(tài)干擾發(fā)生在哪個(gè)時(shí)刻wavedec適合做后處理比如把信號(hào)分解到不同頻帶再做重構(gòu)或者閾值去噪。4.2 小波基怎么選不是越長(zhǎng)越好小波基的選擇是新手最容易懵的地方。db2、db4、sym8、bior3.7這么多名字怎么選我的經(jīng)驗(yàn)分三檔第一檔看信號(hào)形態(tài)。如果信號(hào)里是尖銳的瞬態(tài)脈沖選Haar或者db1這類緊支撐小波時(shí)間定位準(zhǔn)不容易把脈沖攤開(kāi)。如果是平滑的振蕩信號(hào)選sym8或者db8頻帶特性更好分解出來(lái)的細(xì)節(jié)分量更平滑。第二檔看計(jì)算量。小波分解層數(shù)越高、濾波器越長(zhǎng)計(jì)算越慢但也不是越長(zhǎng)越好太長(zhǎng)的小波濾波器在邊界處會(huì)產(chǎn)生明顯振鈴。第三檔看重構(gòu)誤差??梢杂靡粋€(gè)小測(cè)試信號(hào)分解再重構(gòu)比較原始信號(hào)和重構(gòu)信號(hào)的最大誤差哪個(gè)小選哪個(gè)。我甚至?xí)堰@一招寫(xiě)成腳本每次遇到新數(shù)據(jù)先自動(dòng)掃一遍候選小波基。離散小波分解的核心函數(shù)是[ca, cd] dwt(x, sym8); [c, l] wavedec(x, 5, sym8);其中c把所有層的小波系數(shù)連在一起l記錄了每層系數(shù)的長(zhǎng)度后面重構(gòu)和去噪都靠這兩個(gè)變量。4.3 小波閾值去噪?yún)?shù)的拿捏小波去噪的邏輯很簡(jiǎn)單噪聲在小波域的系數(shù)小信號(hào)在小波域的系數(shù)大把小的閾值縮掉再重構(gòu)就得到干凈信號(hào)。MATLAB里最快捷的方式是wdenx_denoised wden(x, heursure, s, mln, 5, sym8);這里面的參數(shù)要解釋一下。‘heursure’表示啟發(fā)式閾值選擇規(guī)則它綜合了無(wú)偏風(fēng)險(xiǎn)估計(jì)和固定閾值適合信噪比未知的情況。‘s’表示軟閾值軟閾值會(huì)導(dǎo)致信號(hào)稍微變平滑硬閾值則可能保留更多毛刺?!甿ln’表示噪聲模型對(duì)應(yīng)多重似然選擇。最關(guān)鍵的參數(shù)是分解層數(shù)5以及小波基sym8。分解層數(shù)如果太少低頻里還殘留不少噪聲太多則會(huì)把信號(hào)的低頻細(xì)節(jié)也當(dāng)成噪聲濾掉導(dǎo)致去噪后的波形失真。我一般先做3、5、7層的對(duì)比看重構(gòu)信號(hào)的均方根誤差和粗糙度指標(biāo)。去噪和濾波不一樣濾波是頻率選擇小波去噪是“幅度選擇”所以它對(duì)瞬態(tài)尖峰的保留比傳統(tǒng)濾波器好得多這也是它在故障診斷里特別受歡迎的原因。4.4 連續(xù)小波變換看時(shí)頻細(xì)節(jié)除了去噪小波分析最迷人的應(yīng)用是時(shí)頻圖。cwt函數(shù)用法很簡(jiǎn)單cwt(x, fs); % 自動(dòng)選擇小波基 title(時(shí)頻圖);它會(huì)返回一幅以時(shí)間為橫軸、頻率為縱軸、顏色代表幅度的譜圖。我在調(diào)制解調(diào)項(xiàng)目中用它來(lái)看跳頻信號(hào)的頻點(diǎn)切換時(shí)刻也能用它在滾動(dòng)軸承振動(dòng)信號(hào)里看到故障沖擊的小波脊。不過(guò)cwt的默認(rèn)參數(shù)有時(shí)會(huì)讓人誤導(dǎo)尤其是小波基的類型是自動(dòng)選擇的如果你需要可重復(fù)的實(shí)驗(yàn)結(jié)果我建議顯式指定小波基和頻率范圍比如[cfs, freqs] cwt(x, fs, amor);amor是復(fù)Morlet小波適合分析振蕩信號(hào)的幅值和相位隨時(shí)間的變化。換到通信信號(hào)里它能同時(shí)顯示調(diào)制符號(hào)的幅度跳變和相位旋轉(zhuǎn)非常直觀。5. 把三個(gè)模塊合體一個(gè)完整的綜合仿真案例5.1 場(chǎng)景設(shè)定帶噪FSK信號(hào)的接收與去噪為了說(shuō)明前面幾節(jié)不是互相獨(dú)立這里給一個(gè)完整的綜合案例。假設(shè)我們要接收一個(gè)2FSK信號(hào)載波頻率在10kHz和14kHz之間切換符號(hào)速率500波特采樣率100kHz。接收端第一步是帶通濾波第二步是正交解調(diào)第三步用小波去噪來(lái)平滑判決前的包絡(luò)曲線。這個(gè)場(chǎng)景和實(shí)際無(wú)線遙控、電力線通信的接收端結(jié)構(gòu)很接近難點(diǎn)在于信號(hào)里疊加了強(qiáng)高斯白噪聲而且還有一個(gè)窄帶干擾落在12kHz附近。5.2 實(shí)現(xiàn)步驟與關(guān)鍵代碼先定義參數(shù)fs 100e3; fc1 10e3; fc2 14e3; Rs 500; sps fs / Rs; N 4000; data randi([0 1], N, 1); t (0:N*sps-1) / fs; freqs data * (fc2 - fc1) fc1; % 用頻率積分構(gòu)造FSK信號(hào) phase cumsum(2 * pi * freqs / fs); x_fsk cos(phase);這樣構(gòu)造的FSK信號(hào)相位連續(xù)更接近真實(shí)調(diào)制器輸出。然后加噪和帶通濾波x_noisy awgn(x_fsk, 8, measured); % 帶通濾波器覆蓋兩個(gè)載波頻率 bp designfilt(bandpassfir, ... StopbandFrequency1, 8e3, ... PassbandFrequency1, 10.5e3, ... PassbandFrequency2, 13.5e3, ... StopbandFrequency2, 16e3, ... StopbandAttenuation, 40, ... PassbandRipple, 1, ... SampleRate, fs); x_bp filtfilt(bp, x_noisy);濾波后用兩個(gè)相關(guān)器分別解調(diào)頻率fc1和fc2ref1 cos(2 * pi * fc1 * t); ref2 cos(2 * pi * fc2 * t); % 低通濾波取包絡(luò) env1 filtfilt(d_lp, x_bp .* ref1); env2 filtfilt(d_lp, x_bp .* ref2); % 小波去噪平滑包絡(luò) env1_den wden(env1, heursure, s, mln, 5, sym8); env2_den wden(env2, heursure, s, mln, 5, sym8); % 判決 decision env1_den env2_den; BER sum(decision ~ data) / N;這段流程值得注意的地方是小波去噪不要用在原始信號(hào)上而是用在解調(diào)后的包絡(luò)信號(hào)上。原始FSK信號(hào)的頻率切換點(diǎn)是非常短的瞬態(tài)小波去噪可能會(huì)把它當(dāng)成高頻噪聲給削平導(dǎo)致判決困難。而包絡(luò)信號(hào)本身是緩變的去噪效果就很安全。5.3 結(jié)果怎么看誤碼率、星座圖與時(shí)頻圖聯(lián)審跑完程序后我不會(huì)只看一個(gè)BER數(shù)值。我會(huì)同時(shí)畫(huà)四張圖帶噪信號(hào)時(shí)域圖、濾波后時(shí)域圖、解調(diào)包絡(luò)對(duì)比圖、FSK信號(hào)的cwt時(shí)頻圖。時(shí)頻圖能一眼看出10kHz和14kHz兩條頻率脊線如果小波去噪?yún)?shù)太激進(jìn)時(shí)頻圖中頻率脊周圍的紋理會(huì)變糊這時(shí)就要回頭調(diào)整wden的層數(shù)或者閾值策略。這種多圖聯(lián)審的習(xí)慣幫我避免過(guò)很多“數(shù)據(jù)好看但實(shí)際鏈路不對(duì)”的假象。很多時(shí)候BER看起來(lái)不錯(cuò)但解調(diào)后星座圖的點(diǎn)云發(fā)散了說(shuō)明濾波器的群延遲沒(méi)補(bǔ)償好或者時(shí)頻圖里有明顯突變但時(shí)域波形顯示得很平滑說(shuō)明信號(hào)構(gòu)造和你預(yù)期的不一致。只有把多個(gè)角度都看一遍仿真才算真正閉環(huán)。6. 常見(jiàn)問(wèn)題與調(diào)試心得6.1 頻率分辨率不夠頻譜圖上的峰變成一片很多人用fft分析信號(hào)發(fā)現(xiàn)兩個(gè)很近的頻點(diǎn)根本分不開(kāi)。這不是FFT算法的問(wèn)題是分辨率不夠。分辨率等于fs/FFT點(diǎn)數(shù)。如果fs100kFFT用1024點(diǎn)分辨率大約是97.7Hz那兩個(gè)相差50Hz的頻率當(dāng)然分不開(kāi)。解決辦法不是提高采樣率而是增加FFT點(diǎn)數(shù)或者用零填充。注意零填充只是讓頻譜看起來(lái)更平滑并不是真正提高分辨率。要害還是信號(hào)本身的長(zhǎng)度。如果信號(hào)只有100msfs50k那么實(shí)際分辨率就是10Hz就算FFT做8192點(diǎn)有效信息量也沒(méi)有變多。作圖時(shí)可以用pwelch做加窗譜估計(jì)參數(shù)設(shè)置靈活很多。6.2 濾波器階數(shù)過(guò)高導(dǎo)致信號(hào)“發(fā)瘋”在線性仿真里高濾波階數(shù)可能導(dǎo)致數(shù)值誤差累積尤其是IIR濾波器。具體表現(xiàn)是信號(hào)在濾波后末尾出現(xiàn)一段高頻振蕩甚至直接發(fā)散。應(yīng)對(duì)辦法是把傳遞函數(shù)轉(zhuǎn)成二階節(jié)級(jí)聯(lián)sos并改用sosfilt。代碼很簡(jiǎn)單[b, a] butter(12, 0.2); sos tf2sos(b, a); y sosfilt(sos, x);如果是FIR濾波器階數(shù)高不會(huì)不穩(wěn)定但計(jì)算量大、延遲長(zhǎng)。遇到實(shí)時(shí)性要求高的場(chǎng)景可以用multistage multirate的方法先降采樣再濾波再把輸出插值回來(lái)速度提升非常明顯。6.3 小波分解層數(shù)的經(jīng)驗(yàn)法則層數(shù)選擇沒(méi)有唯一的公式但有個(gè)經(jīng)驗(yàn)判斷方法采樣率越高、信號(hào)帶寬越寬需要分解的層數(shù)越多。一般來(lái)說(shuō)每一層分辨的頻率范圍只是上一層的一半。如果某一層細(xì)節(jié)系數(shù)的能量和原始信號(hào)相比已經(jīng)非常低說(shuō)明高頻細(xì)節(jié)基本沒(méi)了再往下分意義不大可以停。我寫(xiě)過(guò)一個(gè)自動(dòng)判斷的小腳本對(duì)每一層細(xì)節(jié)系數(shù)計(jì)算標(biāo)準(zhǔn)差如果標(biāo)準(zhǔn)差突然比上一層下降了90%以上說(shuō)明這一層剩下的大多是噪聲就選擇這個(gè)層數(shù)作為分解上限。這樣比拍腦袋定層數(shù)靠譜得多。6.4 調(diào)試全鏈路的三板斧最后聊聊我調(diào)試這種綜合項(xiàng)目最常用的三個(gè)工具。第一板斧是分段檢查。把發(fā)射、濾波、調(diào)制、解調(diào)、去噪每一步的輸出都單獨(dú)畫(huà)出來(lái)用局部變量存中間結(jié)果不要一個(gè)長(zhǎng)腳本跑完。哪一段波形不符合直覺(jué)就縮小到那一段去debug。第二板斧是用理論值做標(biāo)定。比如發(fā)射端符號(hào)速率1k那采樣的眼圖張開(kāi)最寬的位置應(yīng)該是一個(gè)符號(hào)周期的中心如果偏了馬上能看出有沒(méi)有群延遲沒(méi)補(bǔ)償。第三板斧是保存隨機(jī)種子。在做仿真對(duì)比時(shí)很多人用randi生成隨機(jī)數(shù)據(jù)后不固定隨機(jī)種子導(dǎo)致每次結(jié)果都不同根本沒(méi)法判斷改動(dòng)是變好了還是變差了。設(shè)計(jì)初期先設(shè)一次rng(2024)等邏輯穩(wěn)定了再切換成隨機(jī)模式這是很多仿真團(tuán)隊(duì)的經(jīng)驗(yàn)但新手往往容易忽略。這三招用下來(lái)基本上任何通信信號(hào)處理仿真題目都能在半天內(nèi)調(diào)通。說(shuō)實(shí)話MATLAB的文檔和示例庫(kù)已經(jīng)很全但真正拉開(kāi)差距的是這些從實(shí)戰(zhàn)里沉淀下來(lái)的小習(xí)慣。工具只是手段對(duì)鏈路每一環(huán)的理解才決定你能走多遠(yuǎn)。希望這篇文章能幫你在濾波、調(diào)制解調(diào)、小波分析這條路上少踩幾個(gè)坑。