CPFSK (Continuous phase modulation) - один из видов частотной модуляции. Отличается от FSK тем, что имеет непрерывную фазу, что помогает уменьшить размер спектра и занимаемую ширину канала. CPFSK имеет набор преимуществ перед FSK, которые будут рассмотрены после изучения внутренней работы CPFSK.
Перед переходом к CPFSK рекомендуется изучить статью про обычный FSK, которую можно найти на главной странице моего сайта. В целом, главное отличие FSK и CPFSK в том, что CPFSK не меняет фазу сиганала при переключении между частотами. То есть фаза на протяжении всего сигнала и переключений остается одна. Это позволяет передавать сигнал в ограниченной полосе пропускания, так как исключены разрывы в фазе, которые создают дополнительные частотные компоненты в спектре.
Чтобы лучше понять для чего нужна CPFSK рассмотрим следующие примеры.

Источник: https://www.slideshare.net/slideshow/continuos-phase-frequency-shift-keyingcpfsk/54978534
Как видно на рисунке, при переключении между генераторами в сигнале возникает разрывы фаз, при CPFSK этот разрыв убирается, это хорошо видно на следующем слайде.

Источник: https://www.slideshare.net/slideshow/continuos-phase-frequency-shift-keyingcpfsk/54978534
Рассмотрим примеры и разберем математику CPFSK в Octave. Для этого используем исходные данные из статьи про FSK. Определим сигнал, который будет передаваться. У сигнала будет какая-то битовая скорость, которая будет обозначаться как BPS.
10 1 0 0 1 0 0 0 0 1 1 0 0 1
В FSK при модуляции мы использовали следующие параметры в Octave.
x1Fs = 1000; 2Tb = 1; 3t = 0:1/Fs:Tb-1/Fs; 4
5% Частота девиации6
7fsk_index = 5;8w_deviation = pi * (1/Tb) * fsk_index;9w_base = 2 * pi * 10;10
11
12w0 = w_base - w_deviation;13w1 = w_base + w_deviation;14
15bits = [0 1 0 0 1 0 0 0 0 1 1 0 0 1];16
17FSK_signal = [];Частота семплирования - 1000 Герц, длительность бита - 1 секунда. Также в коде есть расчет частоты девиации, которая для CPFSK рассчитывается так же как и для FSK. Сгенерируем два сигнала, один с CPFSK, а второй с FSK, чтобы лучше понять в чем разница между двумя модуляциями. Заполним массив FSK_signal.
xxxxxxxxxx71for i = 1:length(bits)2 if bits(i) == 03 FSK_signal = [FSK_signal cos(w0*t)];4 else5 FSK_signal = [FSK_signal cos(w1*t)];6 end7endТеперь передем непосредственно к CPFSK. Для создания непрерывного сигнала нам нужно контролировать фазу, самый простой способ - пересчитывать фазу при добавлении бита. Разберем формулы для реализации. В непрерывном времени изменение фазы в течении маленького интеравала времени dt определяется следующим образом.
Теперь при дискретизации с частотой дискретизации Fs (задана в начале статьи и равна 1000 отсчетов в секунду) формула превращается в следующий вариант.
Следовательно обновление фазы будет выглядить так.
Следовательно конечная формула.
Теперь попробуем применить ее на практике и посмотреть моменты переключения на графиках, которые сгенерирует Octave.
xxxxxxxxxx131phase = 0;2CPFSK_signal = [];3for i = 1:length(bits)4 if bits(i) == 05 freq = w0;6 else7 freq = w1;8 end9 for j = 1:length(t)10 phase = phase + freq / Fs;11 CPFSK_signal = [CPFSK_signal cos(phase)];12 end13endСуть остается прежней, просто меняем фазу. Теперь можно сравнить что у нас получилось. Для этого отрисуем графики сигналов и изучим переходы между частотами.
xxxxxxxxxx271figure;2
3subplot(4,1,1);4plot(t, cos(w0*t));5title('FSK Frequency for bit 0');6xlabel('Time (s)');7ylabel('Amplitude');8
9subplot(4,1,2);10plot(t, cos(w1*t));11title('FSK Frequency for bit 1');12xlabel('Time (s)');13ylabel('Amplitude');14
15subplot(4,1,3);16plot(0:1/Fs:(length(FSK_signal)-1)/Fs, FSK_signal);17title('FSK Modulated Signal');18xlabel('Time (s)');19ylabel('Amplitude');20xlim([0 2]);21
22subplot(4,1,4);23plot(0:1/Fs:(length(CPFSK_signal)-1)/Fs, CPFSK_signal);24title('CPFSK Modulated Signal');25xlabel('Time (s)');26ylabel('Amplitude');27xlim([0 2]);Время в графиках ограничено до 2 секунд, чтобы можно было четко найти переход от 0 на 1.

Также изучим спектральные различия между двумя модуляциями.
xxxxxxxxxx241N = length(CPFSK_signal);2f = (-N/2:N/2-1)*(Fs/N);3
4Y_FSK = fftshift(fft(FSK_signal, N));5Y_CPFSK = fftshift(fft(CPFSK_signal, N));6
7P_FSK = abs(Y_FSK/N);8P_CPFSK = abs(Y_CPFSK/N);9
10figure;11
12subplot(2,1,1);13plot(f, P_FSK);14title('Spectrum of FSK Modulated Signal');15xlabel('Frequency (Hz)');16ylabel('|P(f)|');17xlim([-100 100]); 18
19subplot(2,1,2);20plot(f, P_CPFSK);21title('Spectrum of CPFSK Modulated Signal');22xlabel('Frequency (Hz)');23ylabel('|P(f)|');24xlim([-100 100]);Получаем следующие графики.

Как видно на графиках, различия значительны. CPFSK не создает боковых частотных компонентов в спектре из-за плавного перехода, за счет этого его спектр получается намного уже, что позволяет экономить место в пропускной полосе, при этом сохраняя скорость передачи данных.
https://astro.tsu.ru/TGP/text/6_1_2.htm https://en.wikipedia.org/wiki/Phase_(waves) https://en.wikipedia.org/wiki/Continuous_phase_modulation https://signals.radioscanner.ru/info/item68/ http://www.radioscanner.ru/info/article345/