Jump to content

    

Цифровой частотно-фазовый детектор

Задача тривиальная - стабилизировать скорость вращения электродвигателя с помощью ФАПЧ. В качестве генератора опорного сигнала выступает таймер (потом будет NCO, но это сути не меняет), импульсы с таходатчика производят захват мгновенного значения таймера, эта величина сразу дает текущую ошибку фазы. Проблема состоит в том, что у такого фазового детектора передаточная характеристика пилообразная. Будут захватываться сигналы кратной частоты, чего допустить нельзя. Нужен частотно-фазовый детектор, у которого при больших ошибках передаточная характеристика должна быть горизонтальной. Вроде, это называется phase unwrapping. Как ни странно, не удалось найти вменяемых примеров, как это красиво делается. Придумывается только какая-то громоздкая машина состояний, состояния которой должны меняться в прерываниях по захвату и переполнению, и решение принимается на основе анализа нескольких периодов. Как это обычно делают?

Phd.gif

Share this post


Link to post
Share on other sites

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

есть комбинированные схемы чапч-фапч: большие уходы по частоте фиксируются чд и в этом случае работает грубая и быстрая чапч, а когда ошибка на выходе чд мала, то петля чапч размыкается, и работает фапч. 

эти переходы надо аккуратно моделировать. 

чд в вашем случае - разность двух последовательных значений таймера, которые вы захватываете.

Share this post


Link to post
Share on other sites

Если скорость двигателя выше номинальной, частотно-фазовый детектор должен выдавать максимальное положительное значение ошибки. Если ниже - максимальное отрицательное.

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

Не хотелось бы детектор разбивать отдельно на частотный и фазовый. Лучше, если фазовый детектор будет иметь зоны насыщения при больших ошибках. Аналогично детекторам микросхем синтезаторов частоты.

Share this post


Link to post
Share on other sites
1 час назад, Леонид Иванович сказал:

Лучше, если фазовый детектор будет иметь зоны насыщения при больших ошибках. Аналогично детекторам микросхем синтезаторов частоты.

почему не подходит ЧФД на двух триггерах с выходом типа "зарядовый насос"  ?

700214803_PFD0.3-3kforLeonid.png.c04721fea6432767c3fc7bdd6025a5ea.png

Share this post


Link to post
Share on other sites

копите абсолютную фазу (ну или отдельно ещё количество полных оборотов) без переполнения через 180 градусов, и её и стабилизируйте.

phase += enc - enc_prev;

if (enc - enc_prev < 0) phase +=360;

ну а чтобы убрать перерегулирование (накопленную ошибку за время разгона например), целое количество оборотов из фазы можно периодически вычитать, если частота стала близкой к заданной.

Share this post


Link to post
Share on other sites

> почему не подходит ЧФД на двух триггерах с выходом типа "зарядовый насос"  ?

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

> копите абсолютную фазу

По сравнению с этим мои костыли выглядят менее страшными:

//Состояния частотно-фазового детектора:

//NCO OVF: _|_____|_____|_____|_____|_____|_
//SENSOR: _____|_____|_____|_____|_____|____
//FDET:     0  1  0  1  0  1  0  1  0  1  0
//FREQ OK               OK (1->0)

//NCO OVF: _|_____|_____|_____|_____|_____|_
//SENSOR:  _____|____|_|___|||____|_____|____
//FDET:     0  1  0 1 2 0 123 0  1  0  1  0
//FREQ HI               H     H(2->0, 3->0, etc)

//NCO OVF: _|_____|_____|_____|_____|_____|_
//SENSOR:  _____|___________|_____|_____|____
//FDET:     0  1  0     0  1  0  1  0  1  0
//FREQ LO               L (0->0)

Самое близкое, что находил по теме, это реализация частотно-фазового детектора на FPGA, но и там нет "честного" насыщения, коды при отклонении частоты дергаются.

 

A FPGA Implementation of a PLL.pdf

Share this post


Link to post
Share on other sites

Файл нашелся чуть по другой ссылке: http://homepages.cae.wisc.edu/~brodskye/mr/phaseunwrap/unwrap.c

Только в данном случае не вижу от него пользы. Хотелось бы увидеть пример, как реализуют управление электродвигателями на микроконтроллере не спомощью PID, а с помощью PLL. Вроде, распространенная задача, а ничего найти почему-то не удалось.

Share this post


Link to post
Share on other sites

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

успехов

Share this post


Link to post
Share on other sites
25 минут назад, Леонид Иванович сказал:

При чем тут разрядность таймера? Она влияет только на точность измерения ошибки фазы.

 

Имелось в виду, что период счета таймера должен быть больше максимального периода импульсов с таходатчика !

По каждому прерыванию (по импульсу с таходатчика) берете текущий отсчет таймера, вычитаете из него значение отсчета таймера из предыдущего прерывания (по модулю равному периоду счета таймера), и получаете период оборотов вашего двигателя. Вычитая из него требуемое значение периода, получаете величину отклонения, которую подаете на петлевой фильтр.

Share this post


Link to post
Share on other sites

Период таймера - это опорный сигнал, он всегда равен номинальному периоду сигнала таходатчика. То, что Вы описали дальше, это АПЧ, а не ФАПЧ.

 

Share this post


Link to post
Share on other sites
19 hours ago, Леонид Иванович said:

Как это обычно делают?

Очень просто.

У Вас два прерывания - по захвату (Capture) и по сбросу опорного таймера (Compare)

	uint cnt;
	uint result;
	void Compare(void)
	{
	 cnt--;
	 if (cnt==0)
	 {
	  result=CaptureVal;
	 }
	 else
	 {
	  if (cnt>0) result=180; else result=-180;
	  cnt=0;
	 }
	}
	 
	void Capture(void)
	{
	 cnt++;
	}
	

Вот и все. Какие тут сложности?

 

Share this post


Link to post
Share on other sites
3 hours ago, Леонид Иванович said:

При чем тут разрядность таймера? Она влияет только на точность измерения ошибки фазы.

 

разрядность нужно увеличивать со стороны msb, чтобы убрать неопределенность в оценке периода или частоты вращения, и, как следствие, иметь возможность определять и регулировать частоту во всем диапазоне  возможных значений

я так понимаю, пока у вас вопросы из категории 'как запрограммировать', но, поверьте, работоспособная фапч с широкой полосой захвата - это трудная штука, требующая большого объема моделирования. тем более, если речь идет о каком-то силовом устройстве с двигателем.

Share this post


Link to post
Share on other sites

Делал примерно так же. Несколькими постами выше я приводил диаграммы состояний частотно-фазового детектора, значения FDET там - это и есть значения cnt. Только у меня не было cnt-- и сравнение делал с 1. Получается, что именно так и делают, вопрос можно считать закрытым. А не попадался ли какой-нибудь готовый проект или appnote на тему ФАПЧ управления двигателями?

 

Quote

разрядность нужно увеличивать со стороны msb, чтобы убрать неопределенность в оценке периода или частоты вращения, и, как следствие, иметь возможность определять и регулировать частоту во всем диапазоне  возможных значений

Еще раз - разрядность таймера влияет только на точность представления фазы. Полный диапазон кодов таймера - это угол от 0 до 360 градусов. На каждый импульс таходатчика всегда приходится одно переполнение таймера. Меняется частота вращения - меняется и частота переполнений таймера (фактически там будет NCO, а не таймер, я об этом писал).

 

Edited by Леонид Иванович

Share this post


Link to post
Share on other sites
1 hour ago, Леонид Иванович said:

Только у меня не было cnt-- и сравнение делал с 1.

Да, это можно опустить. Сделано исключительно для удобства понимания. Более того, обычно в Capture есть как флаг того, что он сработал, так и флаг того, что произошло переполнение (сработал несколько раз, а значение не вычитано из регистров). Тогда вообще все еще проще:

	void Compare(void)
	{
	 if (CaptureFlag)
	 {
	  if (CaptureOvf) result=180; else result=CaptureVal;
	 }
	 else
	  result=-180;
	}
	

Прерывание Capture не используется вообще.

Но, понятное дело в такой простоте есть тонкости. Связаны они с тем, что импульс может прийти ровно в момент Compare и немного дрожать, и там возможны варианты типа дребезга +180..-180. За этим надо следить. Более точно поведение надо обсуждать с учетом выбранного микроконтроллера и его периферии.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now