acvarif 0 12 апреля, 2018 Опубликовано 12 апреля, 2018 (изменено) · Жалоба Сворганил BPSK приемо-передатчик с петлей Костаса на базе VCO. Основной код петли заимствовал на просторах сети. %% Петля Костаса на базе VCO %% Модуляция clear; % Битовая картика профиля pacman image = [ 1, 1, 1, 0, 0, 1, 1, 1; 1, 1, 0, 0, 0, 0, 1, 1; 1, 0, 0, 0, 1, 0, 0, 1; 0, 0, 0, 0, 0, 0, 1, 1; 0, 0, 0, 0, 0, 1, 1, 1; 1, 0, 0, 0, 0, 0, 0, 1; 1, 1, 0, 0, 0, 0, 1, 1; 1, 1, 1, 0, 0, 1, 1, 1 ]; % Начальный символ приема sync_symbol = [ 1 ]; % Битовый поток с начальным символом bit_stream = [ sync_symbol ]; % Генерация битового потока из матрицы профиля pacman for j = 1:8 bit_stream = [bit_stream image(j,:)]; end %bit_stream = (rand(1, 6) > 0.5); %bit_stream = [1 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0]; bit_stream = [1 1 0 1 0]; N = length(bit_stream); fprintf('bit_stream %d\n', bit_stream); % Частота семплирования 288 кГц fs = 288000; % Несущая частота относительно частоты выборок 36 кГц f = 0.125; % Частота доплера 300 Гц fdop = f/1200; % Символьная частота 100 Гц fsim = 100; % Количество выборок на период несущей 8 ns = 1/f; % Количество выборок необх. для одного символа (360*8 периодов нес. f) % Символьная скорость 100 Гц tsymbol = fs*f*ns/fsim; fprintf('tsymbol %d\n', tsymbol); % Счетчик выборок в 0 t = 0; % Количество символов переданных с нулевой фазой nDummySymbols = 4; % Общее количество выборок %ttotal = N*tsymbol + nDummySymbols * tsymbol + tsymbol*3; ttotal = N*tsymbol + nDummySymbols * tsymbol; fprintf('ttotal %d\n', ttotal); % Создать пустой сигнал BPSK_signal = zeros(ttotal,1); % Символы с нулевой фазой for i = 1:nDummySymbols for j = 1:tsymbol BPSK_signal(t+1) = cos( 2*pi*(f+fdop)*t ); BPSK_signal_nomod(t+1) = cos(2*pi*(f+fdop)*t); t = t + 1; end end fprintf('t %d\n', t); % BPSK сигнал for i = 1:length(bit_stream) phase = pi * bit_stream(i); for j = 1:tsymbol BPSK_signal(t+1) = cos(2*pi*(f+fdop)*t + phase); BPSK_signal_mod(t+1) = cos(2*pi*(f+fdop)*t + phase); BPSK_signal_nomod(t+1) = 0; t = t + 1; end end fprintf('length BPSK_signal %d\n', length(BPSK_signal)); fprintf('t %d\n', t); %% AWGN (аддитивный белый гауссов шум) канал передачи данных % отношение сигнал/шум в децибелах SNR = 20; % мощность сигнала в децибелах SIGPOWER = 10; % смесь мод.сигнала с шумом BPSK_signal = awgn( BPSK_signal, SNR, SIGPOWER); %% Демодуляция % полученная картинка в 0 rec_image = zeros(8,8); % Координаты картинки x = 1; y = 1; % начальный шаг в 0 t = 0; % Все матрицы в 0 carrier_inph = zeros(ttotal,1); mixer_inph = zeros(ttotal,1); demod_thr_inph = zeros(ttotal,1); % Фильтр демодулятора b = fir1(100, 0.1); % Память состояния демодулятора stateLowpassInph = zeros(numel(B)-1,1); % переменные для PLL осциллятора % cosine output c = 1; % delayed cosine by one timestep c_delay = 0; % sine output s = 0; % delayed sine by one timestep s_delay = 0; % Данные из VCO для целей отладки sine = zeros(ttotal,1); cosine =zeros(ttotal,1); vco = zeros(ttotal,1); % PLL loop фильтр bPLL = fir1(40, 0.1); % and the state memory zfPLLa = zeros(numel(bPLL)-1,1); zfPLLc = zeros(numel(bPLL)-1,1); zfPLLs = zeros(numel(bPLL)-1,1); % Обратный отсчет. При нулевом значении отбирается символ. % Начальный обратный отсчет учитывает задержку % fir lowpass и пропускает начальный символ sampleMoment = tsymbol/2+tsymbol; % Это время необходимое PLL для стабилизации на несущей nPLLsettle = (nDummySymbols/2) * tsymbol; % Игнорировать данные, пока не получен символ "1" ignoreData = 1; % VCO шаг VCOgain = 0.005; % VCO, которое управляет частотой. при v = 0 он точно равен f. v = 0; % Основной цикл for step = 1:ttotal % Получить значение BPSK_signal sample = BPSK_signal(step); % PLL - "voltage" управляемый осциллятор с +/- v входом % w0 частота VCO w0 = 2*pi*(f+v*VCOgain); % Cохранить предыдущее состояние c_delay = c; s_delay = s; % Подсчет нового состояния c = c_delay * cos(w0) - s_delay * sin(w0); s = s_delay * cos(w0) + c_delay * sin(w0); % Cохраним все в удобных векторах для графики sine(step) = s; cosine(step) = c; vco(step) = v; % конец VCO % Сохраняем sine/cosine. Обратите внимание, что инфазная волна % теперь является синусоидальной волной, потому что PLL с мультипликацией % в качестве фазового детектора имеет сдвиг фазы на 90 градусов между % входом и выходом carrier_inph(step) = c; % Это решает, находимся ли мы в режиме синхронизации PLL или режима замораживания % Примечание: это должно быть заменено блокировкой PLL в реальном приеме, % потому что мы не знаем, когда передача фактически % начинается. Здесь мы просто предполагаем, что она начинается с самого начала % PLL in action: изменение частоты через v % Фазовый детектор pc = sample*c; ps = sample*-s; % filtering out the 2f term % Фильтрация pc [vc,zfPLLc] = filter(bPLL,1,pc,zfPLLc); % filtering out the 2f term % Фильтрация ps [vs,zfPLLs] = filter(bPLL,1,ps,zfPLLs); [v,zfPLLa] = filter(bPLL,1,vc*vs,zfPLLa); % we sneak here a -1 in because this is ambigous % шаг на -1 mixer_inph(step) = -sample*carrier_inph(step); [lp_demod_inph(step),stateLowpassInph] = filter(b,1,mixer_inph(step),stateLowpassInph); demod_thr_inph(step) = lp_demod_inph(step); if (ignoreData) % Ждем стартового символа 1 if ( lp_demod_inph(step) > 0.25 ) % got it! % Стартовый символ прошел ignoreData = 0; end else % Ожидание середины символа для выборки демодулятора sampleMoment = sampleMoment - 1; if (sampleMoment == 0) sampleMoment = tsymbol; if ( demod_thr_inph(step) > 0.2 ) lsb = 1; else lsb = 0; end fprintf('lsb %d\n', lsb); % debug samples: add small spikes % отладка: добавка небольших пиков lp_demod_inph(step) = lp_demod_inph(step) + 0.1; % Сохранить результат в картинку if (((x<9) && (y<9)) && (ignoreData == 0)) rec_image(y,x) = lsb; x = x + 1; if (x > 8) x = 1; y = y + 1; end % if (x > 8) end % x>9 && y>9 end % sampleMoment == 0 end % ignore data % Следующий шаг в выборке t = t + 1; end %% Графика % Немодулированный сигнал figure; plot(BPSK_signal_nomod, 'b-', 'LineWidth', 2); hold on; grid on; title('Немодулированный сигнал'); % Модулированный сигнал figure; plot(BPSK_signal_mod, 'b-', 'LineWidth', 2); hold on; grid on; title('Модулированный сигнал'); % Полный BPSK_signal figure; plot(BPSK_signal, 'b-', 'LineWidth', 2); hold on; grid on; title('BPSK сигнал'); % Демодулированный сигнал figure; subplot(2,1,1); plot(lp_demod_inph,'LineWidth',2); xlabel('Samples'); ylabel('Amplitude'); title('demod / lowpass filtered'); grid on; % Картинка subplot(2,1,2); imshow(rec_image); % Напряжение VCO figure; subplot(1,1,1); plot(vco); Работает при соотнощении сигнал-шум 20 на 10 децибел, доплере 30 Гц при несущей в 36 кГц и символьной скорости 100 Гц Напрягает то, что при соотношении сигнал шум 1 приемник перестает работать. Все разваливается, даже при нулевом доплере. Все так и должно быть или нет? Получается что для нормальной работы BPSK приемника необходим хороший приемный усилитель с узкой полосой (определяется удвоенной символьной скоростью) и коэффициентом усиления достаточным, чтобы при минимально возможном сигнале на его входе он мог обеспечить необходимый уровень сигнала на входе BPSK приемника. Но с другой стороны при максимально возможном уровне сигнала на входе приемного усилителя он не должен входить в ограничение выхода. Не представляю как решается такая задачка. Изменено 13 апреля, 2018 пользователем Acvarif Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
acvarif 0 16 апреля, 2018 Опубликовано 16 апреля, 2018 (изменено) · Жалоба Ниже код BPSK модулятор-демодулятор с петлей Костаса на базе VCO для акустического модема. Просьба покритиковать. На базе данного кода предполагается писать код для ПЛИС либо микроконтроллера, только с использованием NCO. Характеристики: - Символьная скорость 100 бит в сек - Несущая частота 36 000 Гц - 8 выборок на период несущей - Устойчиво работает при соотношении сигнал-шум 1 - Максимальный Доплер 60 Гц (в воде ~ 2.5 м/сек) Есть сомнения в необходимости входного полосового фильтра поскольку наверняка некоторую селективность будет иметь аналоговый приемный тракт. %% Петля Костаса на базе VCO %% Модуляция clear; % Битовая картика профиля pacman % image = [ 1, 1, 1, 0, 0, 1, 1, 1; % 1, 1, 0, 0, 0, 0, 1, 1; % 1, 0, 0, 0, 1, 0, 0, 1; % 0, 0, 0, 0, 0, 0, 1, 1; % 0, 0, 0, 0, 0, 1, 1, 1; % 1, 0, 0, 0, 0, 0, 0, 1; % 1, 1, 0, 0, 0, 0, 1, 1; % 1, 1, 1, 0, 0, 1, 1, 1 ]; image = [ 1, 0, 1, 0, 1, 0, 1, 0; 0, 1, 0, 1, 0, 1, 0, 1; 1, 0, 1, 0, 1, 0, 1, 0; 0, 1, 0, 1, 0, 1, 0, 1; 1, 1, 1, 1, 1, 1, 1, 1; 0, 0, 0, 0, 0, 0, 0, 0; 1, 1, 1, 1, 1, 1, 1, 1; 0, 0, 0, 0, 0, 0, 0, 0 ]; % Начальный символ приема sync_symbol = [ 1 ]; % Битовый поток с начальным символом bit_stream = [ sync_symbol ]; % Генерация битового потока из матрицы профиля pacman for j = 1:8 bit_stream = [bit_stream image(j,:)]; end %bit_stream = (rand(1, 20) > 0.5); %bit_stream = [1 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0]; %bit_stream = [1 1 0 1 0 1 0 1 0]; N = length(bit_stream); fprintf('bit_stream %d\n', bit_stream); % Частота семплирования 288 кГц (8 выборок на период) fs = 288000; % Несущая частота относительно частоты выборок 36 кГц f = 0.125; % Частота доплера 60 Гц (~2.5 м.сек) fdop = f/600; % % Частота семплирования 144 кГц (4 выборки на период) % fs = 144000; % % Несущая частота относительно частоты выборок 36 кГц % f = 0.25; % % Частота доплера 60 Гц (~2.5 м/сек) % fdop = -f/600; % Частота среза НЧ фильтра в демодуляторе fc = 100; % Частота Найквиста fn = fs/2; % Порядок НЧ фильтра демодулятора lowpfiltord = 50; % Порядок loop фильтра демодулятора loopfiltord = 50; % Амплитуда A = 1.0; % Символьная скорость 100 Гц fsim = 100; % Количество выборок на период несущей ns = 1/f; % Количество выборок необх. для одного символа (360*8 периодов нес. f) % при символьной скорости fsim tsymbol = fs*f*ns/fsim; fprintf('tsymbol %d\n', tsymbol); % Счетчик выборок в 0 t = 0; % Количество символов переданных с нулевой фазой (пилот) nDummySymbols = 4; % Общее количество выборок %ttotal = N*tsymbol + nDummySymbols * tsymbol + tsymbol*3; ttotal = N*tsymbol + nDummySymbols * tsymbol; fprintf('ttotal %d\n', ttotal); % Создать пустой BPSK сигнал BPSK_signal_t = zeros(ttotal,1); % Пилот сигнал for i = 1:nDummySymbols for j = 1:tsymbol BPSK_signal_t(t+1) = A*sin( 2*pi*(f+fdop)*t ); BPSK_signal_nomod(t+1) = A*sin(2*pi*(f+fdop)*t); t = t + 1; end end fprintf('t %d\n', t); % BPSK сигнал for i = 1:length(bit_stream) phase = pi * bit_stream(i); for j = 1:tsymbol BPSK_signal_t(t+1) = A*sin(2*pi*(f+fdop)*t + phase); BPSK_signal_mod(t+1) = A*sin(2*pi*(f+fdop)*t + phase); BPSK_signal_nomod(t+1) = 0; t = t + 1; end end fprintf('length BPSK_signal %d\n', length(BPSK_signal_t)); fprintf('t %d\n', t); %% AWGN (аддитивный белый гауссов шум) + полосовая фильтрация % отношение сигнал/шум в децибелах SNR = 9; % мощность сигнала в децибелах SIGPOWER = 12; % смесь мод.сигнала с шумом BPSK_signal_awgn = awgn( BPSK_signal_t, SNR, SIGPOWER ); % Порядок полосового фильтра bandpfiltord = 50; % нижняя частота полосового фильтра 35КГц W1=35e3/(0.5*fs); % верхняя частота полосового фильтра 37КГц W2=37e3/(0.5*fs); % расчет окна Ханна k=hann(bandpfiltord+1); % расчет коэффициентов входного полосового фильтра bp=fir1(bandpfiltord, [W1 W2], k); % Память состояния фильтра stateBandpassBpsk = zeros(numel(bp)-1,1); % Полосовая фильтрация BPSK сигнала + AWGN шум [bPSK_signal_awgn_filtr,stateBandpassBpsk] = filter(bp,1,BPSK_signal_awgn,stateBandpassBpsk); % BPSK_signal_awgn_filtr = filter(bp, 1, BPSK_signal_awgn); % BPSK_signal %BPSK_signal = BPSK_signal_awgn; BPSK_signal = BPSK_signal_awgn_filtr; %% Демодуляция % полученная картинка в 0 rec_image = zeros(8,8); % Координаты картинки x = 1; y = 1; % начальный шаг в 0 t = 0; % Все матрицы в 0 carrier_inph = zeros(ttotal,1); mixer_inph = zeros(ttotal,1); demod_thr_inph = zeros(ttotal,1); %расчет окна Кайзера kb=kaiser(lowpfiltord+1); % Коэффициенты НЧ фильтра демодулятора порядок lowpfiltord b = fir1(lowpfiltord, fc/fn, kb); % Память состояния для НЧ фильтра демодул. stateLowpassInph = zeros(numel(B)-1,1); % переменные для PLL осциллятора % cosine output c = 1; % delayed cosine by one timestep c_delay = 0; % sine output s = 0; % delayed sine by one timestep s_delay = 0; % Данные из VCO для целей отладки sine = zeros(ttotal,1); cosine =zeros(ttotal,1); vco = zeros(ttotal,1); %расчет окна Ханна kp=hann(loopfiltord+1); % Коэффициенты PLL loop фильтра bPLL = fir1(loopfiltord, fc/fn, kp); % Обнулить память zfPLLa = zeros(numel(bPLL)-1,1); zfPLLc = zeros(numel(bPLL)-1,1); zfPLLs = zeros(numel(bPLL)-1,1); % Обратный отсчет. При нулевом значении отбирается символ. % Начальный обратный отсчет учитывает задержку % fir lowpass и пропускает начальный символ sampleMoment = tsymbol/2+tsymbol; % Это время необходимое PLL для стабилизации на несущей nPLLsettle = (nDummySymbols/2) * tsymbol; % Игнорировать данные, пока не получен символ "1" (синхробит) ignoreData = 1; % VCO шаг VCOgain = 0.005; % VCO, которое управляет частотой. при v = 0 он точно равен f. v = 0; % Основной цикл for step = 1:ttotal % Полосовая фильтрация BPSK сигнала + AWGN шум % [bPSK_signal(step),stateBandpassBpsk] = filter(bp,1,BPSK_signal_awgn(step),stateBandpassBpsk); % Получить значение BPSK_signal в sample sample = BPSK_signal(step); % PLL - управляемый осциллятор с +/- v входом % w0 частота VCO w0 = 2*pi*(f+v*VCOgain); % Cохранить предыдущее состояние c_delay = c; s_delay = s; % Подсчет нового состояния c = c_delay * cos(w0) - s_delay * sin(w0); s = s_delay * cos(w0) + c_delay * sin(w0); % Cохраним все в удобных векторах для графики sine(step) = s; cosine(step) = c; vco(step) = v; % конец VCO % Сохраняем sine/cosine. Обратите внимание, что инфазная волна % теперь является синусоидальной волной, потому что PLL с мультипликацией % в качестве фазового детектора имеет сдвиг фазы на 90 градусов между % входом и выходом carrier_inph(step) = c; % Это решает, находимся ли мы в режиме синхронизации PLL или режиме замораживания % Примечание: это должно быть заменено блокировкой PLL в реальном приеме, % потому что мы не знаем, когда передача фактически % начинается. Здесь мы просто предполагаем, что она начинается с самого начала % PLL изменение частоты через v % Фазовый детектор pc = sample*c; ps = sample*-s; % Фильтрация pc [vc,zfPLLc] = filter(bPLL,1,pc,zfPLLc); % Фильтрация ps [vs,zfPLLs] = filter(bPLL,1,ps,zfPLLs); [v,zfPLLa] = filter(bPLL,1,vc*vs,zfPLLa); % шаг на -1 mixer_inph(step) = sample*carrier_inph(step); [lp_demod_inph(step),stateLowpassInph] = filter(b,1,mixer_inph(step),stateLowpassInph); demod_thr_inph(step) = lp_demod_inph(step); if (ignoreData) % Ждем стартового символа 1 if ( lp_demod_inph(step) > 0.25 ) % Стартовый символ прошел ignoreData = 0; end else % Ожидание середины символа для выборки демодулятора sampleMoment = sampleMoment - 1; if (sampleMoment == 0) sampleMoment = tsymbol; if ( demod_thr_inph(step) > 0.1 ) lsb = 1; else lsb = 0; end fprintf('lsb %d\n', lsb); % отладка: добавка небольших пиков lp_demod_inph(step) = lp_demod_inph(step) + 0.1; % Сохранить результат в картинку 8:8 if (((x<9) && (y<9)) && (ignoreData == 0)) rec_image(y,x) = lsb; x = x + 1; if (x > 8) x = 1; y = y + 1; end % if (x > 8) end % x>9 && y>9 end % sampleMoment == 0 end % ignoreData % Следующий шаг в выборке t = t + 1; end %% Графика % % Немодулированный сигнал % figure; % subplot(2,1,1); % plot(BPSK_signal_nomod, 'b-', 'LineWidth', 2); % hold on; % grid on; % title('Немодулированный сигнал (пилот)'); % % % Модулированный сигнал % %figure; % subplot(2,1,2); % plot(BPSK_signal_mod, 'r-', 'LineWidth', 2); % hold on; % grid on; % title('Модулированный сигнал (данные)'); % Полный BPSK_signal figure; subplot(2,1,1); plot(BPSK_signal_awgn, 'b-', 'LineWidth', 2); xlabel('Выборки'); hold on; grid on; title('Полный BPSK сигнал + шум AWGN'); subplot(2,1,2); plot(BPSK_signal, 'r-', 'LineWidth', 2); xlabel('Выборки'); hold on; grid on; title('Полный BPSK сигнал + шум AWGN + Фильтр'); % Демодулированный сигнал figure; subplot(2,1,1); plot(lp_demod_inph,'LineWidth',2); xlabel('Выборки'); ylabel('Амплитуда'); title('Демодулированный сигнал / НЧ фильтрация'); grid on; % Картинка subplot(2,1,2); imshow(rec_image); title('Битовая картинка 8:8 квадратиков 1-белый, 0-черный кв. ' ); % Напряжение VCO % figure % plot(vco); % title('Напряжение VCO'); % % % Фильтр демодулятора % figure % % АЧХ НЧ фильтра % [h,f]=freqz(b,1); % % Параметры являются соответственно частотой и амплитудой % plot(f*fs/(2*pi),20*log10(abs(h))) % xlabel('частота/Hz');ylabel('амплитуда/dB');title('АЧХ НЧ фильтра демодулятора'); % % % Фильтр полосовой на 36 кГц % figure % [h,fp]=freqz(bp,1);%amplitude-frequency characteristic graph % plot(fp*fs/(2*pi),20*log10(abs(h)))%parameters are respectively frequency and amplitude % xlabel('частота/Hz');ylabel('амплитуда/dB');title('АЧХ полосового фильтра'); Изменено 16 апреля, 2018 пользователем Acvarif Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться