Фазовая модуляция радиосигнала в ПЛИС

в 18:07, , рубрики: fpga, PLL, Разработка систем связи, фазовая модуляция, частотная модуляция, эксперимент

Фазовая модуляция радиосигнала в ПЛИС - 1

Так иногда бывает, что занимаешься одной технической проблемой, но, по мере погружения в задачу и во время поиска ее решения, появляются «побочные продукты». Так случилось и в этот раз. Я исследовал различные методы измерения временных интервалов с помощью ПЛИС. В одном из предложенных методов измерений был использован динамический сдвиг фазы тактовой частоты с PLL. Позже пришла идея: используя свойства PLL можно попробовать сделать в ПЛИС простейший радиопередатчик с фазовой модуляцией.

И кое-что получилось!

Пожалуй нужно немного рассказать, что такое PLL. PLL (Phase Locked Loop) — это устройство фазовой автоподстройки частоты генератора. Выглядит примерно вот так:

Фазовая модуляция радиосигнала в ПЛИС - 2

Здесь есть ГУН — Генератор, Управляемый Напряжением. Он выдает желаемую частоту, которая через обратную связь идет на фазовый детектор. Фазовый детектор определяет разность фаз между опорной частотой F0 и получившейся частотой F1, разность фаз — это сигнал ошибки, который отфильтровывается и воздействует на ГУН, заставляя его колебаться чуть быстрее или чуть медленнее. Так, на выходе ФАПЧ получается частота, синхронная с опорной.

В микросхемах ПЛИС, например, от компании Интел (эх… когда-то была Альтера) серии MAX10 есть встроенный PLL, который выглядит вот так:

Фазовая модуляция радиосигнала в ПЛИС - 3

Кажется, что это что-то гораздо более сложное, чем то, что изображено выше. Но нет, если присмотреться внимательно, то видны общие черты: ГУН, Генератор Управляемый Напряжением — это VCO, Voltage Controlled Oscilator. PFD — это фазовый детектор, LF — Loop Filter, фильтр фазовой ошибки.

Кроме всего прочего, PLL внутри ПЛИС имеет набор счетчиков делителей. Например, делитель частоты M в цепи обратной связи позволяет получить на выходе PLL частоту в несколько раз выше, чем опорная. Так же имеются выходные счетчики C0-C4, которые позволяют на пяти выходах PLL получить сетку частот с разными делителями.

Есть внутри PLL еще компоненты, которые почему-то обычно не изображаются на структурных схемах в документации Altera/Intel — это схемы управляющие перезагрузкой и перенастройкой PLL. Логические схемы в ПЛИС могут на лету перезагружать коэффициенты счетчиков делителей в PLL и еще они позволяют сдвигать фазу выходных частот PLL. Конечно, перезагрузить на лету параметры PLL — это не очень простая операция, которая к тому же занимает определенное время. А вот сдвигать фазу выходной частоты PLL можно довольно просто и быстро. Причем, разрешающая способность по фазе напрямую зависит от частоты Fvco. Сдвигать фронт тактовой частоты можно на 1/8 периода Fvco. Например, входная частота на PLL Fin=100МГц, а делитель M в цепи обратной связи к фазовому детектору равен 13-ти. Тогда Fvco=1300МГц, а разрешение по фазе для выходной частоты PLL Fout=100МГц будет составлять всего 3,46 градуса.

Для разработки проекта для ПЛИС Altera/Intel используется среда САПР Quartus Prime и в ней есть средства настройки экземпляров PLL: Megawizard Plug-In Manager. С его помощью можно устанавливать нужные свойства PLL:

Фазовая модуляция радиосигнала в ПЛИС - 4

Здесь как раз и видно какие получаются Fvco и разрешение по фазе для выходных частот.

Для управления фазой выходных частот у компонента PLL есть дополнительные сигналы: SCANCLK, PHASESTEP, PHASEUPDOWN, PHASECOUNTERSELECT, PHASEDONE.

В документации Altera/Intel написано, как управлять этими сигналами, чтобы получить единичный сдвиг фазы на избранной выходной частоте.

Фазовая модуляция радиосигнала в ПЛИС - 5

Получается так: сигнал PHASEUPDOWN определяет в какую сторону нужно двигать фазу. PHASECOUNTERSELECT определяет сигнал какой именно тактовой частоты PLL будет сдвинут (например, если нужно сдвинуть частоту c1, то PHASECOUNTERSELECT=3'b011 — это есть в документации). Цикл сдвига фазы начинается с установки сигнала PHASESTEP и заканчивается, когда PLL выставит в ноль PHASEDONE. Если нужно сдвинуть фазу значительно, то придется выполнить несколько таких циклов. Все это при желании можно даже просимулировать в ModelSim, как это делается я писал вот здесь.

Теперь, дальше — интереснее. Плавно перехожу к моему «радиопередатчику»:

Фазовая модуляция радиосигнала в ПЛИС - 6

Я использую плату Марсоход3bis на чипе ПЛИС Altera/Intel MAX10. Плата имеет встроенный программатор на базе двухканального чипа FTDI. Причем один канал FT2232HL используется под JTAG (загрузка ПЛИС, отладка в SignalTap), а второй канал используется для передачи данных в плату, как последовательный порт.

К плате, прямо к двум цифровым пинам-выходам подключены два куска провода по 0,75 метра. Это антенна, «полуволновый вибратор». Без выходного аналогового фильтра на излучаемый диапазон, конечно, не хорошо, но сама антенна уже какой-то фильтр, да и мощность передатчика невелика…

Проект написан на языке Verilog HDL — всего-то пара десятков строк кода:

module top(
	input wire CLK100MHZ,
	input wire key0,
	input wire key1,
	input wire FTDI_BD0, //serial RX line 
	output wire [19:0]io
);

wire wc0;
wire wc1;
wire wlocked;
wire wpdone;
wire up_down; 
reg pstep;
wire scanclk; assign scanclk = wc0;
	
reg [7:0]cnt8;
always @( posedge scanclk )
	cnt8 <= cnt8 + 8'h01;

mypll mypll_ (
	.areset( ~key0 ),
	.inclk0(CLK100MHZ),
	.phasecounterselect( 3'b011 ),
	.phasestep( pstep ),
	.phaseupdown( up_down ),
	.scanclk(scanclk),
	.c0(wc0),
	.c1(wc1),
	.locked(wlocked),
	.phasedone( wpdone )
	);

wire [7:0]w_rx_byte;
wire w_byte_ready;
reg [1:0]byte_rdy;
always @( posedge wc0 )
	byte_rdy <= {byte_rdy[0],w_byte_ready};
	
serial receiver(
	.reset( ~wlocked ),
	.clk100( wc0 ),	//100MHz
	.rx( FTDI_BD0 ),
	.sbyte( 8'h00 ),
	.send( 1'b0 ),
	.rx_byte( w_rx_byte ),
	.rbyte_ready( w_byte_ready ),
	.tx(),
	.busy(), 
	.rb()
	);

reg  [7:0]current_pll_phase = 0;
wire [7:0]signal; assign signal = w_rx_byte[7:0];
assign up_down = signal>current_pll_phase;

reg [3:0]state = 0;
always @( negedge scanclk )
begin
	case(state)
	0: begin 
			//wait recv byte
			if( byte_rdy ) state <= 1;
		end
	1: begin 
			//do we really need to change phase?
			if( current_pll_phase==signal ) state <= 0;
			else state <= 2;
		end	
	2: begin 
			//wait phase done
			if( ~wpdone ) state <= 3;
	        end
	3: begin 
			state <= 4;
		end
	4: begin 
			state <= 1;
		end
	endcase
	
	if( pstep && (~wpdone) )
		if( up_down )
			current_pll_phase <= current_pll_phase + 6'h1;
		else
			current_pll_phase <= current_pll_phase - 6'h1;
			
	if( ~wpdone )
		pstep <= 1'b0;
	else
	if( state==2 )
		pstep <= 1'b1;
end

assign io[17:0] = 0;
assign io[18] =  wc1;
assign io[19] = ~wc1;

endmodule

Весь проект для САПР Intel Quartus Prime можно взять на GitHub: github.com/marsohod4you/Fpga-PM-Radio.

В проекте есть PLL с двумя выходами c0 и c1, на каждом из них 100МГц. Выход c0 используется для тактирования всей схемы, а вот выход c1 — это и есть несущая 100МГц, частота моего «радиопередатчика» (FM-диапазон). Ее я и собираюсь модулировать по фазе.

Я собираюсь посылать сырой аудиофайл с компьютера в плату через последовательный порт. При формате данных 8 бит на одну аудиовыборку, моно, 22050Гц, наиболее удобна скорость последовательного порта 230400 бод. В самом деле, каждый байт при последовательной передаче имеет старт бит и один или два стоп бита. Если два стоп бита, то получается 11 передаваемых бит на байт данных. Значит 230400/11=20945 выборок в секунду. Это конечно не идеал, не 22050, но чуть-чуть похоже. Ну получится у меня звук немного ниже, чем нужно, мне для моих экспериментов не важно… Итак в проекте есть приемник последовательных данных.

Полученный из последовательного порта байт w_rx_byte внутри ПЛИС сравнивается с внутренней переменной (регистром) current_pll_phase. Разница меж ними — это и есть количество шагов по сдвигу фазы, которые нужно сделать в одну или другую сторону. Таким образом выполняется фазовая модуляция на выходе c1 у PLL.

Теперь второй вопрос. Предположим, что передатчик с фазовой модуляцией работает, а чем слушать?

Я исхожу из того, что ФМ и ЧМ непосредственно связаны друг с другом интегральным/дифференциальным законом. Мгновенная частота радиосигнала — это производная от его фазы. Производная синуса — это косинус. Вряд ли слушатель радиопередачи отличит их на слух (шутка). В общем, я решил попробовать передавать аудио файл моим «радиопередатчиком» с фазовой модуляцией, а слушать мою «радиопередачу» обычным FM-приемником. Я использую мобильный телефон с гарнитурой в качестве FM приемника.

Вот как это выглядит:

Удивительно, но передаваемая мной музыка устойчиво слышна в FM радиоприемнике мобильного телефона на расстоянии до 10-15 метров.

PS: В России 7 мая отмечается День радио. В 1895 году выдающийся русский физик и изобретатель Александр Попов в Санкт-Петербургском университете продемонстрировал созданную им первую в мире искровую беспроводную приемо-передающую радиосистему. В России этот факт был принят за точку отсчета начала радиосвязи.

Автор: Николай

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js