Matlab调制库函数fskmod参数及源代码详解
關注回復【fskmod】可看
在用matlab仿真生成fsk信號時,發現matlab庫提供fskmod函數可以直接生成fsk信號,但生成的信號為復信號,于是查看其源碼,結果對其原理看了好久都沒明白,在網上查詢資料也少得可憐,唯一有一篇也是對其中部分代碼進行解釋,且覺得該原函數提供的方法無法理解,然后文章作者最后進行了改動,得到了他想要的結果(筆者沒仔細看,而是主要研究matlab庫源碼),且只是對參數和部分英文幫助進行了說明,并沒有解釋核心源碼的含義。經過查閱相關資料后,筆者終于明白了其調制原理,現分享如下。
函數原型中重要代碼如下:
function y = fskmod(x,M,freq_sep,nSamp,varargin)- x:輸入信號01比特
- M:調制進制數,比如2fsk調制M=2,4fsk調制M=4
- freq_sep:Δf=|f1-f2|,即相鄰頻率間隔
- nSamp:nSamp=Fs/RB,即每符號的采樣點數
- varargin:可變參數,第一個為Fs,第二個為phase_cont
核心源碼解釋:
if (nargin >= 6)phase_type = varargin{2};%check the phase_type stringif ~( strcmpi(phase_type,'cont') || strcmpi(phase_type,'discont') )error(message('comm:fskmod:phaseCont'));end elsephase_type = 'cont'; endif (strcmpi(phase_type, 'cont'))phase_cont = 1; elsephase_cont = 0; endFSK調制分為相位不連續和相位連續2種方式,不指定默認的話是相位連續調制。這幾句主要使判斷Fs后是否還有參數,如果有(也就是>=6),那么判斷字符串是’cont’還是’discont’,從而給變量phase_cont賦值為1(連續)或0(不連續)。
[nRows, nChan] = size(x);獲取輸入數據的總數,即行數和列數,因此可以是2路或多路信號比特輸入。
phaseIncr = (0:nSamp-1)' * (-(M-1):2:(M-1)) * 2*pi * freq_sep/2 * samptime;在剛看到這一句時,完全想不明白這句是如何來的,更不清楚這句代碼的目的是什么。通過查資料,先來看看FSK信號調制的原理。
以2FSK調制為例,信號表達式為
S(t)=m1(t)Acos?(2πf1t+φ1)+m2(t)Acos?(2πf2t+φ2)S(t)={{m}_{1}}(t)A\cos (2\pi {{f}_{1}}t+{{\varphi }_{1}})+{{m}_{2}}(t)A\cos (2\pi {{f}_{2}}t+{{\varphi }_{2}})S(t)=m1?(t)Acos(2πf1?t+φ1?)+m2?(t)Acos(2πf2?t+φ2?)
式中,m1(t)=∑n=?∞∞bng(t?nTb){{m}_{1}}(t)=\sum\limits_{n=-\infty }^{\infty }{{{b}_{n}}g(t-n{{T}_{b}})}m1?(t)=n=?∞∑∞?bn?g(t?nTb?)
m2(t)=∑n=?∞∞bn ̄g(t?nTb){{m}_{2}}(t)=\sum\limits_{n=-\infty }^{\infty }{\overline{{{b}_{n}}}g(t-n{{T}_{b}})}m2?(t)=n=?∞∑∞?bn??g(t?nTb?)
實際上,在理想情況下,載波振蕩的頻率是隨基帶信號線性變化的,此時,調頻信號可表示為
s(t)=Acos?[2πfct+πΔf∫∞tm′(t)dt′+θc]s(t)=A\cos [2\pi {{f}_{c}}t+\pi \Delta f\int_{\infty }^{t}{{m}'(t)}d{t}'+{{\theta }_{c}}]s(t)=Acos[2πfc?t+πΔf∫∞t?m′(t)dt′+θc?]
其中, fcf_cfc?是未調載波頻率,θcθ_cθc?是載波的初始相位,Δf\Delta fΔf是相鄰頻率間隔。
頻率調制是用調制信息去控制載波的頻率,由于瞬時相位是瞬時頻率的積分,在上式中具體體現就是生成一個瞬時相偏πΔf∫∞tm′(t)dt′\pi \Delta f\int_{\infty }^{t}{{m}'(t)}d{t}'πΔf∫∞t?m′(t)dt′,對其數字化即可變為
pi?(0:nSamp?1)′?(?1,+1)?Δf/Fspi*(0:nSamp-1)'*(-1, +1)* Δf/Fspi?(0:nSamp?1)′?(?1,+1)?Δf/Fs
因此這一句就是初始化一個碼元符號內每個采樣點信號相位的變化量(正1增加,負1減少)。
phIncrSym = phaseIncr(end,:);phIncrSym就表示在一個碼元結束時相位的總變化量
phIncrSamp = phaseIncr(2,:);phIncrSamp表示相鄰采樣點之間的相位變化量
Phase = zeros(nSamp*nRows, nChan);其中nChan表示輸入信號路數,一般情況都是1路。輸入信號總碼元數為nRowsnChan,所以最后生成的相位總數為每符號的采樣點碼元總數,即nSampnRowsnChan,該句就是初始化一個變量用來存儲最后的相位。主要分為2種情況:
一、相位不連續,此時又可分為2種情況。
(1) 當一個碼元持續時間相偏總量πΔf∫∞tm′(t)dt′\pi \Delta f\int_{\infty }^{t}{{m}'(t)}d{t}'πΔf∫∞t?m′(t)dt′為2π的整數倍即
if ( (~phase_cont) &&( floor(nSamp*freq_sep/2 * samptime) == nSamp*freq_sep/2 * samptime ) )此時由于相位變化是周期性的,可以直接用以下2句代碼生成調制信號的相位y。
exp_phaseIncr = exp(1i*phaseIncr); y = reshape(exp_phaseIncr(:,x+1),nRows*nSamp,nChan);(2) 當一個碼元持續時間相偏總量πΔf∫∞tm′(t)dt′\pi \Delta f\int_{\infty }^{t}{{m}'(t)}d{t}'πΔf∫∞t?m′(t)dt′不是2π的整數倍時,當前符號的初始相位是:(前一符號最后采樣點相位+每采樣點相位變化量)mod 2π,即
OscPhase = zeros(nChan, M);OscPhase是針對這種情況設置的變量,存放下一符號開始時(第1個采樣點)的相位,初始化為0。
OscPhase(iChan,:) = rem(OscPhase(iChan,:) + phIncrSym + phIncrSamp, 2*pi); ph1 = OscPhase(iChan, x(iSym,iChan)+1);其中ph1中存放的就是當前符號開始時的相位。
二、相位連續
相位連續時,當前符號開始時(第1個采樣點)的相位時:前一符號最后采樣點相位+每采樣點相位變化量,與相位不連續相比,此處少了模2π運算,即
prevPhase = Phase(nSamp*iSym,iChan) + phIncrSamp(x(iSym,iChan)+1); ph1 = prevPhase;綜上所述,最后再用統一的方法計算每個采樣點的相位
Phase(nSamp*(iSym-1)+1:nSamp*iSym,iChan) = ph1*ones(nSamp,1)+ phaseIncr(:,x(iSym,iChan)+1);最后,再生成FSK調制信號的正交基帶數據
y = exp(1i*Phase);以上就是整個fskmod函數的關鍵核心代碼解讀,得到調制的基帶數據之后,再將基帶信號數據正交上變頻至中頻,即乘以 即可。
總結
以上是生活随笔為你收集整理的Matlab调制库函数fskmod参数及源代码详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 好看漂亮带符号的微信昵称100个
- 下一篇: C语言文件读写操作之换行符处理