NBIOT NPSS主同步信号检测分为粗同步和精同步,粗同步收11ms数据采用1.92m/8的采样率,精同步采用1.92M的采样率,只收1ms的数据,这样做的原因是既可以减少收数的buffer的大小又可以减少自相关运算量的大小,11ms的数据可以减少8倍buffer的大小,精同步虽然是1.92M的采样率,但是实际只收1ms数据。
- 定时估计
粗同步保证定时偏差+-48Ts(1.92M采样率下的),精同步在粗同步的基础上左右移动48个采样点做互相关,找到最大峰的位置,这个位置偏差预计5个点左右。
- 频偏估计
精同步的过程估计的频偏分为整数倍频偏和小数倍的频偏,这里小数倍的频偏是在粗同步估计补偿后的残留的小数倍频偏,估计范围为[-7k 7k],整数倍的频偏估计范围为[-30k:15k:30k],整数倍频偏估计的思想是先用整数倍列表[-30k:15k:30k]里面的频偏补偿数据后,再去做互相关,最后对所有的整数倍频偏相关的最大功率排序,最大的那个对应的就是估计的整数倍频偏。
NPSS信号生成公式如下:
clc,clear,close all;
% coding time 2024.08.20
% data source
rxSig = load('npss.txt');
% refere 3GPP 36.211 10.2.7 10.2.8
% Integer freqOffset range -30~30kHz
interFreqOffset = [-256/137, -128/137,-16/137, 0,17/137 ,128/137, 256/137]*15e3;
% sl generate
Sl_Code = [1,1,1,1,-1,-1,1,1,1,-1,1];
% combine number of fine syne combine
combine_num = 2;
% zc sequen generate
root_index_u = 5;
zc_seq = exp(-1i*pi*root_index_u*(0:10).*(1:11)/11);
zc_seq_add0 = [zeros(1,58), zc_seq, zeros(1,59)];
zc_seq_add0_shift = fftshift(zc_seq_add0);
zc_seq_add0_shift_ifft = ifft(zc_seq_add0_shift)*sqrt(128)*2;
pss_signal_cp9 = [zc_seq_add0_shift_ifft(end-8:end), zc_seq_add0_shift_ifft];
pss_signal_cp9 = pss_signal_cp9 .* exp(1i*2*pi*(7.5e3)*(-9:127)/1.92e6); % according to 3gpp shift 7.5k
npssPosFromCoarseSync = 1; % this pos from npss corse sync ,this assume is 1
% npss corse sync can make sure the timing error (+/- 48Ts)
npssPos = (npssPosFromCoarseSync-1)*16+1;
npssPosStart = npssPos - 16*3;
npssPosEnd = npssPos + 16*3;
if npssPosStart <= 0
npssPosStart = npssPosStart + 19200;
npssPosEnd = npssPosEnd + 19200;
end
freqOffsetLen = length(interFreqOffset);
% npss cross corrleation cal
absCrossCorrBuffer = zeros(foLen,npssPosEnd-npssPosStart+1); %cross corrleation abs value buffer
cplxCrossCorrBuffer = zeros(foLen,npssPosEnd-npssPosStart+1); % cross corrleation complex value buffer
rxSigPwrBuffer = zeros(1,npssPosEnd-npssPosStart+1); % Rx signal power buffer
for combineIdx = 0:combine_num-1
for cfoIntIdx = 1:freqOffsetLen
% buffer 1ms data in a small window and do integer freqoffset try
rxSigBuffer = rxSig(combineIdx*19200+(npssPosStart:npssPosEnd+1508));
rxSigBuffer = reshape(rxSigBuffer,1,[]);
rxSigBuffer = rxSigBuffer .* exp(-1i*2*pi*interFreqOffset(cfoIntIdx)*(1:length(rxSigBuffer))/1.92e6);
% cross correlation
for startPos = npssPosStart:npssPosEnd
rxSigTemp = rxSigBuffer(startPos-npssPosStart+(1:1508));
% cal rx signal power for one freqoffset try is enough
if cfoIntIdx == 1
rxSigPwrBuffer(1,startPos-npssPosStart+1) = rxSigTemp*rxSigTemp';
end
crossCorr = zeros(1,11);
for symb = 0:10
if symb < 4
crossCorr(symb+1) = sum(rxSigTemp(symb*137+(1:137))*Sl_Code(symb+1).*conj(pss_signal_cp9));
else
crossCorr(symb+1) = sum(rxSigTemp(symb*137+1+(1:137))*Sl_Code(symb+1).*conj(pss_signal_cp9));
end
end
absCrossCorr = sum(abs(crossCorr));
cplxCrossCorr = sum(conj(crossCorr(1:10)).*crossCorr(2:11))/2^7;
absCrossCorrBuffer(cfoIntIdx, startPos-npssPosStart+1) = absCrossCorrBuffer(cfoIntIdx, startPos-npssPosStart+1) + absCrossCorr/NB_param.cs.npss.fineSyncFrame;
cplxCrossCorrBuffer(cfoIntIdx,startPos-npssPosStart+1) = cplxCrossCorrBuffer(cfoIntIdx,startPos-npssPosStart+1) + cplxCrossCorr/NB_param.cs.npss.fineSyncFrame;
end
end
end
figure;
plot(abs(absCrossCorrBuffer'),'.-');
grid on;
title('npss: cross corrleation fine sync');
legend('-30kHz', '-15kHz', '0kHz', '15kHz', '30kHz');
% npss fine timing and integer freqoffset estimation
maxVal = max(max(abs(absCrossCorrBuffer)));
[cfoIntIdx, posIntIdx] = find(abs(absCrossCorrBuffer)==maxVal,1);
npssPos = npssPosStart+posIntIdx-1;
intFreqOffsetHz = interFreqOffset(cfoIntIdx);
%fractional freqoffset
corrVal = cplxCrossCorrBuffer(cfoIntIdx,posIntIdx);
% fractional ferq offset
fineFrqOffset = angle(corrVal)*14*1e3/2/pi;
% last total ferq offset
fineCfoTotal = fineFrqOffset + intFreqOffsetHz;
% Calculate frame start time
frameTStartime = npssPos - (1920*5+138+137*2);
if frameTStartime < 0
frameTStartime = frameTStartime + 19200;
end
请关注微信号订阅号:nb_lte_5g ,老牛nb5g老牛每天带你学通信同步更新
努力只能及格,拼命才能优秀。
学通信任道重远,老牛带你走最捷径的路