Правильная фаза и смещение частоты для 16-QAM с использованием грубой и тонкой синхронизации

Компенсация значительной фазы и смещений частоты для сигнала 16-QAM в канале AWGN выполняется в два этапа. Сначала исправьте смещение грубой частоты с помощью оценки, предоставленной компенсатором грубой частоты, а затем подстройте коррекцию с помощью синхронизации несущей. Из-за грубой коррекции частоты синхронизатор несущей быстро сходится, хотя нормированная полоса частот установлена на низкое значение. Более низкие нормированные значения полосы пропускания обеспечивают лучшую коррекцию для малых остаточных смещений несущей. После применения коррекций фазы и смещения частоты к принимаемому сигналу устраните неоднозначность фазы с помощью преамбул.

Определите параметры симуляции.

fs = 10000;      % Sample rate (Hz)
sps = 4;         % Samples per symbol
M = 16;          % Modulation order
k = log2(M);     % Bits per symbol
rng(1996)        % Set seed for repeatable results
barker = comm.BarkerCode(...
    'Length',13,'SamplesPerFrame',13);  % For preamble
msgLen = 1e4;
numFrames = 10;
frameLen = msgLen/numFrames;    

Сгенерируйте полезную нагрузку данных и добавьте преамбулу к каждой системе координат. Преамбула позже используется для разрешения неоднозначности фазы.

preamble = (1+barker())/2;  % Length 13, unipolar
data = zeros(msgLen, 1);
for idx = 1 : numFrames
    payload = randi([0 M-1],frameLen-barker.Length,1);
    data((idx-1)*frameLen + (1:frameLen)) = [preamble; payload];
end

Создайте системный объект для фильтрации формы передающего импульса, фильтрации формы приемного импульса, компенсации грубой частоты QAM, синхронизации несущей и схемы созвездия.

txFilter = comm.RaisedCosineTransmitFilter( ...
    'OutputSamplesPerSymbol',sps);
rxFilter = comm.RaisedCosineReceiveFilter(...
    'InputSamplesPerSymbol',sps,'DecimationFactor',sps);
coarse = comm.CoarseFrequencyCompensator('SampleRate',fs, ...
    'FrequencyResolution',10);
fine = comm.CarrierSynchronizer( ...
    'DampingFactor',0.4,'NormalizedLoopBandwidth',0.001, ...
    'SamplesPerSymbol',1,'Modulation','QAM');
axislimits = [-6 6];
constDiagram = comm.ConstellationDiagram('ReferenceConstellation',qammod(0:M-1,M), ...
    'ChannelNames',{'Before convergence','After convergence'}, ...
    'ShowLegend',true,'XLimits',axislimits,'YLimits',axislimits);

Также создайте Системный объект для канала AWGN, и фазу и смещение частоты, чтобы добавить нарушения к сигналу. Смещение фазы, больше 90 градусов, добавляется, чтобы вызвать неоднозначность фазы, которая приводит к сдвигу квадранта созвездия.

ebn0 = 8;
freqoffset = 110;
phaseoffset = 110;
awgnChannel = comm.AWGNChannel('EbNo',ebn0, ...
    'BitsPerSymbol',k,'SamplesPerSymbol',sps);
pfo = comm.PhaseFrequencyOffset('FrequencyOffset',freqoffset, ...
    'PhaseOffset',phaseoffset,'SampleRate',fs);

Сгенерируйте символы случайных данных, примените 16-QAM модуляцию и передайте модулированный сигнал через фильтр формирования передающих импульсов.

txMod = qammod(data,M);
txSig = txFilter(txMod);

Примените смещения фазы и частоты, используя pfo Системный объект, а затем передайте сигнал через канал AWGN, чтобы добавить белый Гауссов шум.

txSigOffset = pfo(txSig);
rxSig = awgnChannel(txSigOffset);

Компенсатор Системного объекта грубой частоты обеспечивает грубую коррекцию для смещения частоты. Для условий в этом примере достаточна коррекция смещения частоты коррекции принимаемого сигнала в пределах 10 Гц переданного сигнала.

syncCoarse = coarse(rxSig);

Пропустите сигнал через фильтр формирования приемного импульса и примените точную коррекцию частоты.

rxFiltSig = fine(rxFilter(syncCoarse));

Отобразите сигнальное созвездие первого и последнего 1000 символов. Перед сходимостью цикла синхронизации спиральный характер схемы указывает, что смещение частоты не исправлено. После того, как синхронизатор поставщика услуг сходится к решению, символы выравниваются по ссылке созвездию.

constDiagram([rxFiltSig(1:1000) rxFiltSig(9001:end)])

Figure Constellation Diagram contains an axes and other objects of type uiflowcontainer, uimenu, uitoolbar. The axes contains 3 objects of type line. These objects represent Before convergence, After convergence.

Демодулируйте сигнал. Учитывайте задержку сигнала, вызванную фильтрами передачи и приема, чтобы согласовать принятые данные с передаваемыми данными. Вычислите и отобразите общие битовые ошибки и BER. При проверке битовых ошибок используйте более поздний фрагмент принятого сигнала, чтобы убедиться, что цикл синхронизации сходится.

rxData = qamdemod(rxFiltSig,M);
delay = (txFilter.FilterSpanInSymbols + rxFilter.FilterSpanInSymbols) / 2;
idxSync = 2000; % Check BER for the received signal after the synchronization loop has converged
[syncDataTtlErr,syncDataBER] = biterr(data(idxSync:end-delay),rxData(idxSync+delay:end))
syncDataTtlErr = 16116
syncDataBER = 0.5042

В зависимости от используемых случайных данных могут быть битовые ошибки, следующие из неоднозначности фазы в принимаемом сигнале после сходимости и блокировки цикла синхронизации. В этом случае можно использовать преамбулу, чтобы определить и затем удалить неоднозначность фазы из синхронизируемого сигнала, чтобы уменьшить битовые ошибки. Если неоднозначность фазы минимальна, количество битовых ошибок может быть неизменным.

idx = 9000 + (1:barker.Length);
phOffset = angle(txMod(idx) .* conj(rxFiltSig(idx+delay)));

phOffsetEst = mean(phOffset);
disp(['Phase offset = ',num2str(rad2deg(phOffsetEst)),' degrees'])
Phase offset = -90.1401 degrees
resPhzSig = exp(1i*phOffsetEst) * rxFiltSig;

Демодулируйте сигнал после разрешения неоднозначности фазы. Пересчитайте общее количество битовых ошибок и BER.

resPhzData = qamdemod(resPhzSig,M);
[resPhzTtlErr,resPhzBER] = biterr(data(idxSync:end-delay),resPhzData(idxSync+delay:end))
resPhzTtlErr = 5
resPhzBER = 1.5643e-04