Перейти к содержанию
    

acvarif

Участник
  • Постов

    998
  • Зарегистрирован

  • Посещение

Весь контент acvarif


  1. Да. Это понятно. Понимания алгоритмов ЦОС для меня это сильно громко. Я пока всего лишь BPSK+CostasLoop пытаюсь смоделировать, и то в простейшем классическом виде. Допустим я сделаю модель где все сигналы будут представлены в комплексном виде, начиная с модулятора и заканчивая петлей Костаса. Что изменится в понимании этого алгоритма? В том виде как я его сейчас делаю думаю ничего. Разве, что со временем придет более глубокое понимание и не придется раскладывать комплексную огибающую на компоненты, а работать с ней непосредственно на 0 Герц. В продолжение разговора, скажите пожалуйста как в Вашей модели bpsk_costas_2008_08_25.mdl можно посмотреть за какое время происходит стабилизация PLL?
  2. Поддерживаются. К примеру sin может быть комплексным Никак не пойму что это дает? На данный момент, для того, чтобы перейти от VCO к NCO необходимо представить все сигналы не как +-1, а как, например int (16 бит). Тоесть работать не с уровнями в прямом виде, а с их цифровым эквивалентом. Я не могу модель делать оторвано от будущего алгоритма для микроконтроллера или ПЛИС. Чем мне в достижении моей цели поможет комплексное представление сигналов никак не пойму. В реальном железе всеравно придется работать не с комплексным сигналом, а с его составляющими. Поэтому я и говорю о 4_х выборках на период, где две соседние будут представлять квадратурные составляющие сигнала, с которыми и будет вестись работа.
  3. Работа с комплексным сигналом это так? Для меня это пока сложновато. В свое время цифровая ФАПЧ с использованием NCO делалась достаточно просто. После 2_х LPF небольшой цифровой схемкой ыделялись короткие импульсы опережения либо отставания фаз НЧ биений которые инкрементировали либо декрементировали счетчик. Код счетчика управлял частотой NCO.
  4. Без нужды это да. Может и так. Но далее все должно работать в микроконтроллере. А там все будет работать только с составляющими комплексного сигнала. Хотя если рассматривать сигнал дискретно или повыборочно, то для синусоидального сигнала, например при четырех выборках на период две соседние выборки и будут определять его комплексные составляющие. В конечном итоге всеравно ничего не меняется. Разве, что программа микроконтроллера или ПЛИС немного упрощается. Хотя я так до конца и не понял про работу с комплексным сигналом и 0 Герц. Надеюсь со временем врублюсь...
  5. Понятно. Попробую. По поводу комплексных сигналов не врубаюсь. Вот квадратурный демодулятор "Таким образом, мы произвели выделение комплексной огибающей радиосигнала при помощи умножения входного сигнала на комплексную экспоненту с последующим устранением удвоенной несущей при помощи ФНЧ. Устройство выделяющее комплексную огибающую сигнала в соответствии с (4) называется квадратурным гетеродином." Ведь I и Q это и есть составляющие комплексной огибающей. Собственно так я и делаю. А значит работаю с комплексным сингналом на нулевой частоте. Разве нет?
  6. Спасибо. Немного мудрено. Попробую разобраться. В продолжение этой темы https://electronix.ru/forum/index.php?showtopic=146243 сделал симулинк модель простейшего BPSK передатчик-приемник с петлей Костаса на базе VCO которая в основных чертах (кроме фильтров, битовой посл. и пр.) повторяет крайний матлаб код упомянутой темы. Но в реальном железе (ПЛИС, микроконтроллер) дело придется иметь не с VCO, а с NCO. Как можно безболезненно перейти от VCO к NCO на примере данной симулинк модели. CostasLoopBpsk.rar
  7. Спасибо. Работает. По ходу еще вопрос по симулинк. В симулинк имеется компонент "Bernoulli Binary Generator" который генерит случайную битовую последовательность. Как в симулинк можно сгенерить конкретную битовую последовательность, например [1 1 0 1 0 1 0 1 0 1 1 1 0 0 0] ?
  8. Не врубаюсь почему после остановки симуляции выставленной на определенное время (на 2) на scope исчезает результат. Выглядит это так: 1. Во время симуляции 2. После остановки
  9. Ниже код 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('АЧХ полосового фильтра');
  10. Нашел. Да. cutoff frequency Wn определяется частотой дискретизации и частотой Найквиста filtord = 48; % Filter Order Fs = 144000; % Sampling Frequency Fn = Fs/2; % Nyquist Frequency Fc = 100; % Cutoff Frequency b = fir1(filtord, Fc/Fn); % Calculate Filter Coefficients [h,f]=freqz(b,1); plot(f*fs/(2*pi),20*log10(abs(h))) xlabel('frequency/Hz');ylabel('gain/dB');title('The gain response of lowpass filter'); Частота дискретизации понятно. Но при чем тут частота Найквиста?
  11. Подсобите пожалуйста с пониманием работы функции fir1 Например b = fir1(50, 0.1); Здесь http://194.81.104.27/~brian/DSP/FIRFilterM...gnPractical.pdf говорится что в b будут возвращены коэффициенты НЧ фильтра 50 порядка. Но вот со вторым членом функции совсем не врубаюсь. Если необходима частота среза 100 Гц то какое значение должен иметь второй член функции и как сделать plot АЧХ фильтра?
  12. Сворганил 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. Не получается. Пытаюсь сформировать синфазную и квадратурную составляющую модулирующего сигнала. %% BPSK модель % Количество бит данных N = 4; % Данные data = [1 0 1 0]; %data = randi(1,N); pData = data*2 - 1; % Несущая частота (100 кГц) fn = 100000; % Доплер fd = 100; % частота выборок fns = fn*8; % Период выборки Tns = 1/fns; % Период несущей Tn = 1/fn; % Количество периодов несущей на бит-символ M = 4; % Длина пакета данных n = M*length(data); % Текущее время tn = 0:Tns:n*Tn; % Несущая в пакете car_sin = sin(2*pi*fn*tn); car_cos = cos(2*pi*fn*tn); %% Преобразование данных в прямоугольные импульсы tpn_i = 0:Tns:Tn*M; exdata_i = []; for (i = 1:length(data)) for(j = 1:length(tpn_i) - 1) exdata_i = [exdata_i pData(i)]; end end exdata_i = [exdata_i 0]; tpn_q = 0:Tns:Tn*M; exdata_q = []; for (i = 1:length(data)) for(j = 1:length(tpn_q) - 1) % exdata_q = [exdata_q pData(i)]; if (length(tpn_q) == 17) exdata_q = [exdata_q 1]; else exdata_q = [exdata_q -1]; end end end exdata_q = [exdata_q 0]; %% Модуляция % Перенос exdata на несущую mSig_i = exdata_i.*car_cos; mSig_q = exdata_q.*car_sin; %% figure; plot(exdata_i, 'r-', 'LineWidth', 4); hold on; grid on; plot(exdata_q, 'b-', 'LineWidth', 4); hold on; plot(car_sin, 'g-'); hold on hold off; Получается ерунда. У Вас похоже это работает clear all; Br = 117.1875*10^3; Fd = Br*8; Fif = 20*10^6; Fdif = 60*10^6; Fdopl = 100; %% === TRANSMITTER === M = pngen(5); %M = 0.5; D = rand(1, 200*8) > 0.5; %D = [1 0 1 0]; CRC = zeros(1, 16); for i=1:length(D), CRC(16) = xor(CRC(16), D(i)); CRC = [CRC(2:16) CRC(1)]; end; FILL = ones(1, 200)*0.5; DATA = [dec2bin(length(D)/8, 11)=='1' D CRC]; packet = [FILL M M diff_enc([0 DATA]) FILL]*2-1; % redescr Ndkr = Fd/Br; pkt = packet(ceil(0.01:1/Ndkr:length(packet))); hch = firls(31, [0 .24 .3 .5]*2, [1 1 0 0]); pktf = filter(hch, [1], pkt); % upsample t1 = upsample4(pktf, 31); t2 = upsample4(t1, 31); pktfu = upsample4(t2, 31)'; % -> IF l = length(pktfu); s = sin(2*pi*(Fif+Fdopl)*(0:1/Fdif:l/Fdif)); c = cos(2*pi*(Fif+Fdopl)*(0:1/Fdif:l/Fdif)); pkts = pktfu.*s(1:l); pktc = pktfu.*c(1:l); %% === TRANSMIT LINE === Ir = awgn(awgn(pkts, 0.05), 0.01); Qr = awgn(awgn(pktc, 0.05), 0.01); %% === GRAPHICS === figure; plot(pkts, 'g-'); grid on; hold on plot(pktc, 'r-'); hold on figure; plot(Ir, 'g-'); grid on; hold on plot(Qr, 'r-'); hold on plot(pktfu, 'r-'); hold on figure; plot(pkt, 'g-'); grid on; hold on clc; % Переданные данные %pkt Но там слишком большое количество данных. Сложно рассмотреть подробности.
  14. Рад-бы. Но мой уровень симулинк не позволяет сходу это сделать. Ваш пример для меня сложен. А примеры имеющиеся в сети на мой взгляд бестолковые. Их даже в качестве рыбы нельзя использовать. Оторванные от реального железа. Поскольку в симулинк я вообще не умею работать то он вызывает некоторое отторжение. Петлю ФАПЧ попробую сделать в классическом матлабе. %% BPSK модель % Количество бит данных N = 4; % Данные data = [1 0 1 0]; %data = randi(1,N); pData = data*2 - 1; % Несущая частота (100 кГц) fn= 100000; % частота выборок fns = fn*10; % Период выборки Tns = 1/fns; % Период несущей Tn = 1/fn; % Количество периодов несущей на бит-символ M = 4; % Длина пакета данных n = M*length(data); % Текущее время tn = 0:Tns:n*Tn; % Несущая в пакете car = sin(2*pi*fn*tn); %% Преобразование данных в прямоугольные импульсы tpn = 0:Tns:Tn*M; exdata = []; for (i = 1:length(data)) for(j = 1:length(tpn) - 1) exdata = [exdata pData(i)]; end end exdata = [exdata 0]; %% Модуляция % Перенос exdata на несущую mSig = exdata.*car; Теория говорит, что mSig по сути комплексный сигнал. Но в демодуляторе нужно использовать только реальную его часть, которую затем в петле ФАПЧ нужно умножать на комплексную экспоненту. Какой выглядит в коде реальная часть mSig?
  15. Ok. Попробую. В простейшем виде. Сформировал BPSK сигнал Я так понимаю сигнал необходимо оцифровать для того, чтобы потом умножать на сигнал формируемый Discrete-Time VCO. Сделал примерно так Ход верный или ерунда? На FPGA я делал-бы именно так...
  16. Об этом постоянно думаю. В смысле о самонастраиваемом шаге. Что такое ПИ звено?
  17. Если посчитать за какое время сработает петля Костаса, например, при доплере 150 Гц (в воде это движение ~2 м/сек) (несущая 100 кГц) то получится, что для полной синхронизации потребуется время равное 150 символам (битам). Это если шаг изменения частоты NCO будет 1 Гц. 150 бит это ~18 байт преамбулы. Если длительность одного символа 4 периода несущей то это 40 мкс. Всего 150*40 = 6000 мкс. Тоесть полная подстройка произойдет за 6 мс. Это вполне нормально. Но в реальности наверняка шаг подстройки будет меньше чем 1 Гц, например 0.5 Гц. Ну тогда полная синхронизация наступит через 12 мс. Тоже вроде неплохо. Далее пойдет синхросимвол и данные. Для случая с несущей в 100 кГц вроде неплохо. Уже читаю. Глава 5. Думаю для начала всеравно нужно построить петлю Костаса. Приступать сразу к FeedForward наверное неправильно. Ведь так?
  18. Да. Где-то я это понимаю. В частности про малое количество отсчетов. Но тем не менее для моделирования должна сложиться четкая картинка компонентов и их соединения. Схема Костаса эту картинку дает. Как-же тогда быть? Никакой другой схемы кроме Костаса пока не встречал...
  19. Спасибо что Вы мне подсказываете. Общее понимание почти сложилось. Но непонятые детали не дают покоя. Да. Картинка немного не та. Вот та картинка Но суть вроде не меняется. Железно. Перенос на нулевую частоту это умножения входного сигнала на комплексную экспоненту. В цифровом варианте это будет FIR (LPF) Это понимается под согласованным фильтром? Если по цифровой схеме Костаса то не нужны. Там стоят LPF. Тут опять тупик. Получается что согласованный фильтр должен стоять до умножителей. Может в качестве согласованного фильтра имеется ввиду это?
  20. Запутался. Вот петля Костаса Входной сигнал m(t) sin(ωt) Далее он сразу умножается в одном плече на sin(ωt) в другом на cos(ωt) Как результат - на выходе верхнего плеча компонента I, нижнего Q. Произошел снос на нулевую частоту. Что понимается под согласованным фильтром? У нас, например, под согласованным фильтром понимается коррелятор при работе со сложным сигналом.
  21. До петли это как? На схеме разве не так? Фильтры стоят сразу после I Q умножителей. Разве можно как-то иначе поставить фильтры и так чтобы не учитывалась их задерка в петле ФАПЧ? Хотя Ваша схема ФАПЧ не похожа на привычную петлю Костаса Если не сложно, поясните пожалуйста в нескольких фразах как она работает. С этим я вообще пока не знаю что делать... В свое время когда петля ФАПЧ делалась в бинарном виде этот вопрос вообще не стоял.
  22. Спасибо. Понятно. Стало более понятно значение нескольких байт преамбулы обычно используемой в пакете данных. Попытаюсь встроить петлю Костаса в код На демодулятор поступает rx (смесь модулированного сигнала с аддит. гаусовым шумом) которую далее необходимо умножать на sin и cos поступающие с выхода VCO Очевидно что в демодуляторе необходимо будет организовать 1. Управляемый генератор sin cos (VCO). 2. Два одинаковых ФНЧ 3. Фазовый дискриминатор 4. Еще фильтр перед управляемым генератором Какова роль фильтра (loopfilter) после фазового дискриминатора?
  23. Для большего понимания для себя происходящего в BPSK сворганил простую модель. %% BPSK модель % Количество бит данных N = 4; % Данные data = [1 0 1 0]; %data = randi(1,N); pData = data*2 - 1; % Несущая частота (100 кГц) f= 100000; % частота выборок fs = f*100; % Период выборки Ts = 1/fs; % Период несущей T = 1/f; % Количество периодов несущей на бит-символ M = 4; % Длина пакета данных n = M*length(data); % Текущее время t = 0:Ts:n*T; % Несущая в пакете car = sin(2*pi*f*t); % График данных subplot(2, 1, 1); stem(pData); title('Данные'); % График несущей subplot(2, 1, 2); plot(car); title('Несущая'); %% Преобразование данных в прямоугольные импульсы tp = 0:Ts:T*M; exdata = []; for (i = 1:length(data)) for(j = 1:length(tp) - 1) exdata = [exdata pData(i)]; end end exdata = [exdata 0]; figure; plot(exdata, 'r-', 'LineWidth', 4); hold on; grid on; plot(car, 'g-'); hold on %% Модуляция % Перенос exdata на несущую mSig = exdata.*car; plot(mSig, 'h-', 'LineWidth', 2); hold off; title('Прям. импульсы + несущая + промод.несущая'); %% AWGN (аддитивный белый гауссов шум) канал передачи данных figure; % отношение сигнал/шум в децибелах SNR = 50; % мощность сигнала в децибелах SIGPOWER = 10; % смесь мод.сигнала с шумом rx = awgn( mSig, SNR, SIGPOWER); plot(mSig, 'r-', 'LineWidth', 3); hold on; plot(rx, 'g-', 'LineWidth', 1); grid on; %% Демодуляция % умножение мод.зашумленого сигн.на несущую dem = rx.*car; figure; plot(dem); grid on; %% Декодирование k = 1; rcv = []; for(i = 1:length(data)) sm = 0; for(j = 1:length(tp) - 1) sm = sm + dem(k); k = k + 1; end if(sm > 0) rcv = [rcv 1]; else rcv = [rcv 0]; end end clc; % Переданные данные data % Принятые данные rcv В данном случае это идеальный, полностью синхронизированный, вариант. Я так понимаю в реальности все далеко не так. Демодулятор может иметь свою частоту дискретизации отличную от модулятора и она не синхронна с частотой дискретизации в модуляторе. Но это не самое важное. Важно что несущая подаваемая на умножитель в демодуляторе тоже не синхронна с несущей пришедшего на него сигнала, не говоря уже о доплере если источник и приемник двигаются друг относительно друга. В этой части вопрос. Какая основная задача петли Костаса? Подстройка частоты подаваемой на умножитель, вернее на умножители демодулятора? Или задача петли Костаса это фазовая и символьная синхронизация в демодуляторе? Если это так то не врубаюсь как подстройкой частоты NCO можно добиться еще и фазовой синхронизации...
×
×
  • Создать...