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

    

BPSK матлаб модулятор демодулятор

Имеется код BPSK модема, передатчик и приемник.

clear all;
Br = 117.1875*10^3;
Fd = Br*8;

Fif = 20*10^6;
Fdif = 60*10^6;
Fdopl = 100;

%% === TRANSMITTER ===
M = pngen(5);
D = rand(1, 200*8) > 0.5;
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);

%% === RECEIVER ===
% -> 0
l = length(Ir);
s = sin(2*pi*Fif*(0:1/Fdif:l/Fdif));
c = cos(2*pi*Fif*(0:1/Fdif:l/Fdif));

Rreu = Ir.*s(1:l) + Qr.*c(1:l);
Rimu = Qr.*s(1:l) - Ir.*c(1:l);

tr00 = downsample4(Rreu);
tr01 = downsample4(tr00);
Rre_ = downsample4(tr01);
Rre = filter(hch, [1], Rre_);

tr10 = downsample4(Rimu);
tr11 = downsample4(tr10);
Rim_ = downsample4(tr11);
Rim = filter(hch, [1], Rim_);

%figure; hold on; plot(Rre); plot(Rim, 'r');

% detection
Ms = M(ceil(0.01:1/Ndkr:length(M)));
cfh = Ms(length(Ms):-1:1);
cre = filter(cfh, [1], Rre)/length(cfh);
cim = filter(cfh, [1], Rim)/length(cfh);
%cr = sqrt(cre.^2 + cim.^2);
cr = (7/8)*max(abs(cre), abs(cim)) + (1/8)*min(abs(cre), abs(cim));

%figure; hold on; plot(cre); plot(cim); plot(cr, 'r');

env(length(cr)) = 0;
for j=1:length(cr),
f = max(1, j-Ndkr*length(M)+2*Ndkr);
t = min(length(cr), max(2, j-Ndkr));
env(j) = sum(cr(f:t))/(t-f);
end;

%figure; hold on; plot(cr, 'r'); plot(env, 'g'); plot(env*5);

%
for i=length(M)*Ndkr+1:length(cr)-1,
c1 = cr(i) > env(i)*5;
%	c2 = (cr(i) > cr(i-1)) && (cr(i) > cr(i+1));
c2 = (cr(i-1) > cr(i-2)) && (cr(i-1) > cr(i));
c3 = abs(cr(i)-cr(i-length(M)*Ndkr)) < 4*env(i);
c4 = cr(i-length(M)*Ndkr) > env(i-length(M)*Ndkr)*5;

if c1 && c2 && c3 && c4,
	break;
end;
end;
i
re = Rre(i:length(Rre));
im = Rim(i:length(Rim));

%figure; hold on; plot(re); plot(im, 'r');
figure; hold on; plot(cr, 'r'); plot(env, 'g'); plot(env*5); plot((c1&c2&c3&c4)*1.3, 'k');

%
l = length(re);
lb = length(packet);
Yre(lb) = 0;
Yim(lb) = 0;
fre(lb) = 0;
fim(lb) = 0;
are(lb) = 0;
aim(lb) = 0;
mark(l) = 0;
bit(lb) = 0;

k = 1;
gamma = 0.1;
Yre(1) = re(1);
Yim(1) = im(1);

for i = 8:8:length(re)-10,
mark(i) = 1;
are(k) = sum(re(i-6:i-1));
aim(k) = sum(im(i-6:i-1));

%	okre(k) = are(k)*Yim(k) - aim(k)*Yre(k);
okim(k) = aim(k)*Yim(k) + are(k)*Yre(k);

bit(k) = sign(okim(k));

fre(k) = are(k)*bit(k);
fim(k) = aim(k)*bit(k);

Yre(k+1) = (1-gamma)*Yre(k) + gamma*fre(k);
Yim(k+1) = (1-gamma)*Yim(k) + gamma*fim(k);

k = k + 1;
end;

bit_dec = diff_dec(sign(bit+1));
bits = bit_dec(2:length(bit_dec));

%figure; hold on; plot(okim); plot(okre, 'r');
%figure; hold on; plot(re); plot(Yre(ceil(0.01:1/Ndkr:length(bit))), 'r');
%figure; hold on; plot(im); plot(Yim(ceil(0.01:1/Ndkr:length(bit))), 'r');

figure; hold on; plot(im); plot(mark, 'k');

%
len = bin2dec(int2str(bits(1:11)));
data = bits(12:12+len*8-1);
rcrc = bits(12+len*8:12+len*8+15);
crc = zeros(1, 16);
for i=1:length(D),
crc(16) = xor(crc(16), data(i));
crc = [crc(2:16) crc(1)];
end;

disp('---');
disp(sprintf('Received packet length: %d bytes', len));
disp(sprintf('Data ok: %d', sum(abs(data-D))==0));
disp(sprintf('CRC ok: %d', sum(abs(crc-rcrc))==0));

 

При компиляции возникает ошибка:

Undefined function 'pngen' for input arguments of type 'double'.

 

Error in Modem (line 10)

M = pngen(5);

Я так понимаю, что функция pngen должна быть где-то описана. Или такая функция уже встроена в Матлаб последних версий.

Использую R2014a.

Подскажите пожалуйста в чем проблема.

Если кто сталкивался, подсобите пожалуйста простейшим рабочим кодом BPSK модема (передатчик + приемник).

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, это не встроенная функция. Ее написал автор этого кода. Надо искать реализацию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Нет, это не встроенная функция. Ее написал автор этого кода. Надо искать реализацию.

Спасибо. Понятно.

clear
% несущаЯ
Fc = 2400;
% частота выборки бит из вектора Х
Fd = 2400;
% частота выборки выходного модулированного сигнала
Fs = 19200;
% количество сэмплов на 1 бит
Sb = Fs/Fd;
% количество 0 сэмплов перед сигналом
ZeroS = 10;%round(Sb/0.8);
% количество 0 сэмплов перед сигналом
NoiseLev = 0.2;
% ограничение тракта
Amax = 5;
% Количество наборов фаз на символ
M = 2;
% МодулирующаЯ последовательность
x = repmat([0 1 0 0 0 0 0 1 1 1 1 1 0 1 0 1 0 1 0 0 1 0 0 0],1,1); x=x(:);
% Modulate, keeping track of time.
[y,t] = dmod(x,Fc,Fd,[Fs pi/2],'psk',M);
% Всего выборок в выходом сигнале
samples_total  = length(y);

if ZeroS > 0
   y(ZeroS + 1: samples_total) = y (1 : samples_total - ZeroS);
   y(1 : ZeroS) = 0;
end

noise = NoiseLev*randn(size(y));

% yn сигнал на входе демодулЯтора
yn = y + noise;

% Смоделировать выход за динамический диапазон по входу
for sn = 1 : samples_total
   if yn(sn) > Amax
       yn(sn) = Amax;
   elseif yn(sn) < -Amax
       yn(sn) = -Amax;
   end
end

% ДемодулЯциЯ
% Вектор номеров выборок
samples_vector = 1 : samples_total;
%ГенерациЯ векторов sin и cos локальной несущей длЯ коррелЯции c Y
dFs = 2*pi*Fc/Fs;
% sin и cos на длине одного периода
sinFc = sin(0:dFs:2*pi-dFs)';
cosFc = cos(0:dFs:2*pi-dFs)';
samples_sin = length(sinFc);
% sin и cos на длине вектора входного сигнала
sinY = repmat(sinFc, samples_total/samples_sin, 1);
cosY = repmat(cosFc, samples_total/samples_sin, 1);

% ДвигаЯсь по выборкам скользЯщим окном, равным длине битового интервала, вычислЯем коррелЯцию с несущей
demod_y(1:samples_total) = 0;
demod_I(1:samples_total) = yn.*cosY;
demod_Q(1:samples_total) = yn.*sinY;
demod_y = demod_I + demod_Q*j;

% Усреднение I и Q на длине битового интервала
demod_avr_I(1:samples_total) = 0;
demod_avr_Q(1:samples_total) = 0;
avr_interval = samples_sin;

for sn = avr_interval : samples_total
   demod_avr_I(sn) = sum(demod_I( sn - avr_interval + 1: sn ))/avr_interval*2;
   demod_avr_Q(sn) = sum(demod_Q( sn - avr_interval + 1: sn ))/avr_interval*2;
end

% Перемножение усредненных I и Q с задержанной на 1 бит версией
demod_dly_I(1:samples_total) = 0;
demod_dly_Q(1:samples_total) = 0;
demod_dly_I(1+Sb:samples_total) = demod_avr_I(1:samples_total - Sb).* demod_avr_I(1+Sb:samples_total);
demod_dly_Q(1+Sb:samples_total) = demod_avr_Q(1:samples_total - Sb).* demod_avr_Q(1+Sb:samples_total);
demod_dly = demod_dly_I + demod_dly_Q;

% ФильтрациЯ демодулированного сигнала
[demod_b,demod_a]=butter(2,(Fd/Fs));
demod_filt = filter(demod_b,demod_a,sign(demod_dly));


subplot(5,1,1), plot (samples_vector, y, 'b', samples_vector, y, 'r'), grid on;
set (gca, 'XLimMode', 'manual',...
         'XLim', [1,samples_total]',...
         'XTickMode', 'manual',...
         'XTick', [sb:Sb:samples_total]');
subplot(5,1,2), plot (samples_vector, yn), grid on;
set (gca, 'XLimMode', 'manual',...
         'XLim', [1,samples_total]',...
         'XTickMode', 'manual',...
         'XTick', [sb:Sb:samples_total]');
subplot(5,1,3), plot (samples_vector, demod_I, samples_vector, demod_Q, samples_vector, abs(demod_y)), grid on;
set (gca, 'XLimMode', 'manual',...
         'XLim', [1,samples_total]',...
         'XTickMode', 'manual',...
         'XTick', [sb:Sb:samples_total]');
subplot(5,1,4), plot (samples_vector, demod_dly_I, samples_vector, demod_dly_Q, samples_vector, demod_dly), grid on;
set (gca, 'XLimMode', 'manual',...
         'XLim', [1,samples_total]',...
         'XTickMode', 'manual',...
         'XTick', [sb:Sb:samples_total]');
subplot(5,1,5), plot (samples_vector, demod_dly, samples_vector, sign(demod_dly), samples_vector, sign(demod_filt)), grid on;
set (gca, 'XLimMode', 'manual',...
         'XLim', [1,samples_total]',...
         'XTickMode', 'manual',...
         'XTick', [sb:Sb:samples_total]',...
         'YLimMode', 'manual',...
         'YLim', [-1.5, 1.5]',...
         'YTickMode', 'manual',...
         'YTick', [-1.5:0.5:1.5]');

Очевидно в этом коде функция dmod тоже принадлежит автору?

https://www.gaussianwaves.com/digital-modul...s-from-scratch/

Я так понимаю это за деньги. Можно-ли найти подобную литературу не за деньги?

 

Хотя dmod вроде существует http://matlab.exponenta.ru/communication/book2/6/dmod.php

Но начиная с какой версии Матлаб?

Даже код кое-какой имеется http://read.pudn.com/downloads40/sourcecod...MM/DMOD.M__.htm

Изменено пользователем Acvarif

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ух ты. Я написал этот код много лет назад и все эти функции есть у меня на домашнем компе.

 

Я так предполагаю это из РТИ? Или это код дальше разошелся?

 

pngen() генерирует М-последовательность длинны 2^n, где n - это параметр функции. Можно просто найти любую М-последовательность длинны 32 и подставить напрямую.

Изменено пользователем ataradov

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот исходник этой pngen():

function x=pngen(p);
% x=pnegn(p) - Generate pseudo-random sequence
% p = either a scaler (2..12) to generate a PN sequence
% using a predefined polynomial of length p, or
% a binary generating polynomial.
% x = sequence, of length 2^length(p) - 1.

% Predefined seqence polynomials:
pl{2} = [1 1];
pl{3} = [1 1 0];
pl{4} = [1 0 0 1];
pl{5} = [1 0 1 1 1];
pl{6} = [1 1 1 0 0 1];
pl{7} = [1 1 0 0 1 0 1];
pl{8} = [1 0 1 0 1 1 1 1];
pl{9} = [1 0 1 0 1 1 0 1 1];
pl{10} = [1 0 1 0 1 0 1 0 1 1];
pl{11} = [1 0 1 0 1 0 1 0 1 0 1];
pl{12} = [1 1 0 1 0 0 0 0 1 1 0 1];
if length(p) == 1
p = pl{p};
end

L=length(p);
N=2^L-1;

s=ones(1,length(p));
x=zeros(1,N);
for i=1:N
snew = mod(sum(and(p,s)),2);
x(i) = snew;
s=[s(2:end),snew];
end

 

Если нужна помощь с остальным - обращайтесь, помогу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Если нужна помощь с остальным - обращайтесь, помогу.

Большое спасибо. Помощь конечно-же нужна.

Для начала немного осмыслю как все работает...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какая-то из версий этой модели была на Verilog-е реализована, но исходников этого мне сейчас уже точно не найти.

 

Ну и не стоит эту модель воспринимать как полную истину. Это моя первая модель модема созданная по следам чтения Скляра и экспериментов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Какая-то из версий этой модели была на Verilog-е реализована, но исходников этого мне сейчас уже точно не найти.

 

Ну и не стоит эту модель воспринимать как полную истину. Это моя первая модель модема созданная по следам чтения Скляра и экспериментов.

Да, я понимаю.

У меня пока совсем никакого представления. Только в общих чертах. Как работает ФАПЧ мне известно. На практике приходилось это делать, но только в бинарном варианте.

Но сейчас это все реализовывается в дискретном варианте на микроконтроллерах http://www.ti.com/lit/an/slaa681a/slaa681a.pdf, ПЛИС. Для начала пытаюсь хоть как-то понять это дело через Матлаб. Конечно Verilog (VHDL) код очень бы не помешал. Поскольку больше работаю с ПЛИС.

 

В коде появилась еще ошибка Undefined function 'diff_enc' for input arguments of type 'double'.

Похоже должна быть определена еще и функция diff_enc.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Похоже должна быть определена еще и функция diff_enc.

 

function enc=diff_enc(data, start);
    if ~(exist('start'))
        start = 0;

    de(1)=xor(data(1), start);
    for i=2:length(data), de(i)=xor(de(i-1), data(i)); end;
    enc = de;
end

 

Этот модем скорее всего перебор по сравнению с той программной реализацией на МК.

Изменено пользователем ataradov

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Этот модем скорее всего перебор по сравнению с той программной реализацией на МК.

Спасибо. Дело продвинулось.

Далее Undefined function 'upsample4' for input arguments of type 'double'.

Похоже дальше есть еще неопределенные функции...

 

Перебор это в смысле..?

Изменено пользователем Acvarif

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Для начала пытаюсь хоть как-то понять это дело через Матлаб. Конечно Verilog (VHDL) код очень бы не помешал. Поскольку больше работаю с ПЛИС.

 

Лучше сразу смотреть в строну симулинка, облегчает понимание и постепенно модель можно конретизировать до полноценного рабочего HDL кода не прибегая к внешним HDL симуляторам.

 

Поделиться сообщением


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

 

Перебор это в смысле..?
Я возможно не совсем понял статью, но они там похоже уже ожидают прямоугольный сигнал и только восстанавливают битовый клок.

 

Этот модем еще борется с несовпадением частоты дискретизации на приемнике и передатчике (или эффектом Допплера). Плюс тут много всяких заморочек с конкретным железом. Для модема на 100 Кбод не нужна дискретизация на 60 МГц.

functions.zip

Изменено пользователем ataradov

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Лучше сразу смотреть в строну симулинка, облегчает понимание и постепенно модель можно конретизировать до полноценного рабочего HDL кода не прибегая к внешним HDL симуляторам.

Да. Согласен. Но в симуленке я сильно плаваю.

Вот все функции какие у меня есть.

Архив не скачивается. Выскакивает на пустую страницу.

Я возможно не совсем понял статью, но они там похоже уже ожидают прямоугольный сигнал и только восстанавливают битовый клок.

Насколько я понял там задействован внутренний АЦП микроконтроллера. Далее цифровые библиотеки FIR и т. п.

Этот модем еще борется с несовпадением частоты дискретизации на приемнике и передатчике (или эффектом Допплера). Плюс тут много всяких заморочек с конкретным железом. Для модема на 100 Кбод не нужна дискретизация на 60 МГц.

Доплер, это мне какраз и нужно.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Да. Согласен. Но в симуленке я сильно плаваю.
Может быть проще найти время и разобраться. Будет гораздо проще в итоге.

 

Архив не скачивается. Выскакивает на пустую страницу.
Добавил снова.

 

Насколько я понял там задействован внутренний АЦП микроконтроллера. Далее цифровые библиотеки FIR и т. п.
Одного АЦП в общем случае не достаточно нужно 2 квадратуры цифровать.

functions.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Может быть проще найти время и разобраться. Будет гораздо проще в итоге.

Согласен. Придется разбираться.

Спасибо за функции. Главный код заработал. Попытаюсь разобраться.

Одного АЦП в общем случае не достаточно нужно 2 квадратуры цифровать.

Микроконтроллер имеет на борту многоканальный АЦП. Ну а если даже использовать один канал то при 4_х выборках на период можно использовать соседние выборки как синус и косинус.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти