1.解调算法
多进制频移键控(MFSK)是2FSK体制的推广。在4FSK中采用4个不同的频率分别表示四进制的码元,每个码元含有2bit的信息。
4FSK调制器原理和2FSK基本相同。4FSK解调器也分为非相干解调和相干解调两类。4FSK非相干解调器与2FSK解调器原理相同,只是不是分为两路进行,而是分为四路,有四个带通滤波器用于分离不同频率的码元。当某个码元输入时,四个带通滤波器的输出中仅有一个是信号加噪声,其他各路都是只有噪声。因为通常有信号的一路检波输出电压最大,故在判决时按照该路检波电压作判决。
2.函数说明
z = fskdemod(y,M,freq_sep,nSamp,varargin)
%FSKDEMOD Frequency shift keying demodulation
% Z = FSKDEMOD(Y,M,FREQ_SEP,NSAMP) noncoherently demodulates the complex
% envelope Y of a signal using the frequency shift keying method. M is the
% alphabet size and must be an integer power of 2. FREQ_SEP is the frequency
% separation, and must be positive. NSAMP is the required samples per symbol
% and must be an integer greater than 1. For two dimensional signals, the
% function treats each column of data as one channel.
%
% Z = FSKDEMOD(Y,M,FREQ_SEP,NSAMP,Fs) specifies the sampling frequency (Hz).
% The default sampling frequency is 1.
%
% Z = FSKDEMOD(Y,M,FREQ_SEP,NSAMP,Fs,SYMBOL_ORDER) specifies how the
% function assigns binary words to corresponding integers. If SYMBOL_ORDER
% is set to 'bin' (default), then the function uses a natural binary-coded
% ordering. If SYMBOL_ORDER is set to 'gray', then the function uses a
% Gray-coded ordering.
fskdemod函数对FSK调制的复信号进行非相干解调。
y为输入待解调序列;M为调制阶数;freq_sep为相邻频率差;nSamp为上采样倍数;varargin是可变的变量,如果只输入一个,则它代表采样率。
3.源码解读
3.1 Error checks——检查输入参数格式是否正确
主要用到了nargin函数。
nargin为"number of input arguments"的缩写。 在matlab中定义一个函数时, 在函数体内部, nargin是用来判断输入变量个数的函数。在matlab命令窗口中输入help nargin或者doc nargin即可获得该函数的帮助信息。
这部分首先检查输入参数的个数是否正确,然后检查各个参数的范围是否输入正确。
% Error checks -----------------------------------------------------------------
if (nargin < 4)
error(message('comm:fskdemod:numarg1'));
end
if (nargin > 6)
error(message('comm:fskdemod:numarg2'));
end
% Check that M is a positive integer
if (~isreal(M) || ~isscalar(M) || M<2 || (ceil(M)~=M) || ~isnumeric(M))
error(message('comm:fskdemod:Mreal'));
end
% Check that M is of the form 2^K
if(~isnumeric(M) || ceil(log2(M)) ~= log2(M))
error(message('comm:fskdemod:Mpow2'));
end
% Check that the FREQ_SEP is greater than 0
if( ~isnumeric(freq_sep) || ~isscalar(freq_sep) || freq_sep<=0 )
error(message('comm:fskdemod:freqSep'));
end
% Check that NSAMP is an integer greater than 1
if((~isnumeric(nSamp) || (ceil(nSamp) ~= nSamp)) || (nSamp <= 1))
error(message('comm:fskdemod:nSampPos'));
end
% Check Fs
if (nargin >= 5)
Fs = varargin{1};
if (isempty(Fs))
Fs = 1;
elseif (~isreal(Fs) || ~isscalar(Fs) || ~isnumeric(Fs) || Fs<=0 )
error(message('comm:fskdemod:FsReal'));
end
else
Fs = 1;
end
% Check that the maximum transmitted frequency does not exceed Fs/2
maxFreq = ((M-1)/2) * freq_sep;
if (maxFreq > Fs/2)
error(message('comm:fskdemod:maxFreq'));
end
% Check SYMBOL_ORDER
if(nargin==4 || nargin==5 )
Symbol_Ordering = 'bin'; %default
else
Symbol_Ordering = varargin{2};
if (~comm.internal.utilities.isCharOrStringScalar(Symbol_Ordering)) || (~strcmpi(Symbol_Ordering,'GRAY')) && (~strcmpi(Symbol_Ordering,'BIN'))
error(message('comm:fskdemod:SymbolOrder'));
end
end
% End of error checks ----------------------------------------------------------
3.2 参数准备
输入y为列向量输入,一列视为一串待解调序列。如果只解调一段序列,按照(:,1)输入即可。
首先对输入序列进行整理,得到码元个数nRows和待解调序列数nChan。
wid = size(y,1);
if(wid ==1)
y = y(:);
end
[nRows, nChan] = size(y);
z = zeros(nRows/nSamp, nChan);
计算四个频率freqs 。
产生本地信号tones 。
freqs = (-(M-1)/2 : (M-1)/2) * freq_sep;
t = (0 : 1/Fs : nSamp/Fs - 1/Fs)';
phase = 2*pi*t*freqs;
tones = exp(-1i*phase);
3.3 解调判决
根据上采样倍数nSamp,每nSamp个数据一组,为一个码元。
按照阶数M,分成M路,每一路乘上一个本地代表一个频率的信号tones 。这里应该就是解调算法里说的分为M路进行,然后进行判决。
对四路信号进行判决,利用intanddump函数。
输出解调序列z。
for iChan = 1 : nChan % loop for each FSK channel
for iSym = 1 : nRows/nSamp
yTemp = y( (iSym-1)*nSamp+1 : iSym*nSamp, iChan);
yTemp = yTemp(:, ones(M,1));
yTemp = yTemp .* tones;
yMag = abs(intanddump(yTemp, nSamp));
[~, maxIdx] = max(yMag, [], 2);
z(iSym,iChan) = maxIdx - 1;
end
end
if(wid == 1)
z = z';
end