目录
调制
comm.OQPSKModulator
% PhaseOffset - Phase of zeroth point of constellation
% BitInput - Assume bit inputs
% SymbolMapping - Constellation encoding
% PulseShape - Pulse shape type
% RolloffFactor - Rolloff factor for raised cosine pulse shapes
% FilterSpanInSymbols - Filter span (in symbols) for raised cosine pulse shapes
% FilterNumerator - Custom FIR filter coefficients
% SamplesPerSymbol - Samples per symbol
% OutputDataType - Data type of output
O-QPSK modulation (part 1)
Gray、OQPSK
% mapping:
% 1 | 0 01 | 00
% ---+--- => ----+----
% 3 | 2 11 | 10
symbols = bits*2 - 1;
re = -symbols(2:2:end);
im = -symbols(1:2:end);
Filtering:Root raised cosine
obj.pFilter = comm.RaisedCosineTransmitFilter('Shape', 'Square root', ...
'RolloffFactor', obj.RolloffFactor, 'FilterSpanInSymbols', obj.FilterSpanInSymbols, ...
'OutputSamplesPerSymbol', sps, 'Gain', sqrt(sps/2));
filtered = obj.pFilter([re im]);
filteredRe = filtered(:, 1);
filteredIm = filtered(:, 2);
O-QPSK modulation (part 2)
初始化,半个周期的码元
obj.pPrevHalfSymbol = zeros(obj.SamplesPerSymbol/2, 1, obj.OutputDataType);
delay Q component
filteredAligned = [obj.pPrevHalfSymbol; filteredIm(1:end-obj.SamplesPerSymbol/2)];
obj.pPrevHalfSymbol = filteredIm(end-obj.SamplesPerSymbol/2+1 : end);
oqpskWaveform = complex(filteredRe, filteredAligned);
输出波形,移相
oqpskWaveform = oqpskWaveform * exp(1i*obj.PhaseOffset);
解调
comm.OQPSKModulator
% PhaseOffset - Phase of zeroth point of constellation from pi/4
% BitOutput - Output data as bits
% SymbolMapping - Constellation encoding
% PulseShape - Pulse shape type
% RolloffFactor - Rolloff factor for raised cosine pulse shapes
% FilterSpanInSymbols - Filter span (in symbols) for raised cosine pulse shapes
% FilterNumerator - Custom FIR filter coefficients
% SamplesPerSymbol - Samples per symbol
% OutputDataType - Data type of output
初始化
obj.pPrevHalfSymbol = zeros(sps/2, 1);
obj.pMapping = [1 3 0 2];
滤波器
case 'Normal raised cosine'
obj.pFilter = comm.RaisedCosineReceiveFilter('Shape', 'Normal', ...
'RolloffFactor', obj.RolloffFactor, 'FilterSpanInSymbols', obj.FilterSpanInSymbols, ...
'InputSamplesPerSymbol', sps, 'DecimationFactor', sps, 'DecimationOffset', sps/2, 'Gain', sqrt(sps/2));
case 'Root raised cosine'
obj.pFilter = comm.RaisedCosineReceiveFilter('Shape', 'Square root', ...
'RolloffFactor', obj.RolloffFactor, 'FilterSpanInSymbols', obj.FilterSpanInSymbols, ...
'InputSamplesPerSymbol', sps, 'DecimationFactor', sps, 'DecimationOffset', sps/2, 'Gain', sqrt(sps/2));
去除移相
oqpskWaveform = double(input);
oqpskWaveform = oqpskWaveform * exp(-1i*obj.PhaseOffset);
对齐IQ
aligned = complex(...
[obj.pPrevHalfSymbol; real(oqpskWaveform(1:end-obj.SamplesPerSymbol/2))], ...
imag(oqpskWaveform)...
);
obj.pPrevHalfSymbol = real(oqpskWaveform(end-obj.SamplesPerSymbol/2+1 : end));
滤波器,下采样1
% Filter and decimate to 1 (QPSK) sample per symbol
filtered = obj.pFilter(aligned);
QPSK解调
demodulated = qamdemod(filtered, 4, obj.pMapping);
系统仿真
sps = 4; % samples per symbol
modulator = comm.OQPSKModulator( ...
'BitInput',true, ...
'SymbolMapping','Gray',...
'SamplesPerSymbol',sps, ...
'PulseShape','Root raised cosine',...
'RolloffFactor',0.5);
demodulator = comm.OQPSKDemodulator(modulator);
bits = randi([0, 1], 224*8, 1); % 1792
oqpskWaveform = modulator(bits); % 3584 : 1792/log2(M) * sps
snr = 7;
rxWaveform = awgn(oqpskWaveform,snr);
demodData = demodulator(rxWaveform);
delay = (1+modulator.BitInput)*modulator.FilterSpanInSymbols; % 20
[~, ber] = biterr(bits(1:end-delay), demodData(delay+1:end))
% 绘制相位图
plot(unwrap(angle(oqpskWaveform)))
% 绘制IQ图
plot(1:length(oqpskWaveform),real(oqpskWaveform),1:length(oqpskWaveform),imag(oqpskWaveform))
plot(abs(fftshift(fft(oqpskWaveform))))