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

Измерение разности фаз

Частота известна 10кгц +-50гц. Знаний у меня немного по этой теме поэтому вся надежда на Вас )   Сейчас переделаю плату из макета потом оцифрую сигнал и выложу 5 периодов  250 выборок на частоте 500Кгц. Так как это датчик расстояния то нужно измерять непрерывно алгоритм нужен непрерывный.  АЦП ad8681 в нем есть встроенный фнч он немного меняет   фазу(45) но так как частота постоянная то и изменение фазы тоже должно быть постоянным.  

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


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

4 hours ago, SergeyVas said:

Частота известна 10кгц +-50гц.

Для алгоритма Герцеля (он проще в понимании и реализации) важно не только ее примерное значение, а тот факт, что АЦП будет синхронно с источником этой частоты работать.

 

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

Если под непрерывностью измерений вам достаточно каждую миллисекунду знать на сколько фазы разбежались, то это как раз возможно. Если еще в 10 раз чаще, то тоже можно, но немного сложнее.

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


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

А для плис есть алгоритмы про cordic читаю нашел в сети. у меня есть платы с cyclon2 -3  такой вариант тоже думаю сигнал с ацп завести на плис что бы процессор не грузить а рассчитанную фазу в плис слать по spi в мк. 

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


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

36 minutes ago, SergeyVas said:

А для плис есть алгоритмы про cordic читаю нашел в сети. у меня есть платы с cyclon2 -3  такой вариант тоже думаю сигнал с ацп завести на плис что бы процессор не грузить а рассчитанную фазу в плис слать по spi в мк. 

вы прежде скажите на сколько синхронны ваша частота и частота оцифровки: 1. всегда имеют фиксированный коэффициент, 2. плывет во времени, 3. не знаю, так как это из разных клоковых домейнов - (нужное подчеркнуть).

 

Если сонхронна, то на каждую пару оцифрованных данных вам надо будет 12 умножений и с десяток сложений + примерно на каждый сотый раз прихода оцифрованных данных одно дополнительное вычисление квадратного корня, и в момент, когда вы хотите посчитать фазу, один раз вычисление арктангенса, который atan2(x,y). Вспомогательной памяти с десяток чисел. Любой самый дохлый М0 кортекс справится, даже в атмегу могу на спор засунуть, если она сама оцифровывать будет 🙂 Использовать плисину на такую задачу - реально очень жирно и бессмысленно.

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


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

On 8/22/2024 at 1:56 PM, SergeyVas said:

Нужно измерять только разницу фаз, частота стабильная +-10гц.

1000 ppm это "стабильная частота"??? "Куда катится этот мир?".. :biggrin:

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


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

10 часов назад, SergeyVas сказал:

Частота известна 10кгц +-50гц

Здесь всем интересно, откуда возникает такой разброс, потому что синус обычно ПЦС делают, т.е. от своего же кварца.

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


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

Понятно я просто для общего развития ). Не встречались примеры или исходники на верелоги или hdl посмотреть как это реализованно?  Сигнал синхронный от одного клока. Будет заведен  на вход старта ацп.  Точность я пока не измерял поэтому сказал максимум, что может быть.

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


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

18 минут назад, SergeyVas сказал:

как это реализовано?

Вот это новость — т.е. у Вас ещё и измерителя как такового нет.

https://www.google.ru/search?q=dds+verilog+example

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


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

17 hours ago, SergeyVas said:

Сигнал синхронный от одного клока. Будет заведен  на вход старта ацп.

тогда все просто! Я нарисовал аналог Герцеля с вычислением фазы и добавил тестовый пример, фаза вычисляется довольно точно. Может не только Вам на форуме это будет полезно.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


class sPhase
{ float c, s;           // это все вспомогательные
  float c1, s1, c2, s2; // переменные,
  float c_ini, s_ini;   // их не надо
  int   CurCount, Len;  // трогать

public:
  float Angle;          // уже после полного первого периода тут будет сохраняться разность фаз сигналов в радианах

  void Ini(int PLen)
// PLen - длина периода в количестве отсчетов АЦП, то есть, например, если АЦП работает на 500кГц, период сигнала 10кГц, то PLen = 500/10=50
  { if(PLen<4) { printf("Ini: incorrect argument\nTerminated\n"); exit(1); }
    sincosf(2.*M_PI/(float)(Len=PLen), &s_ini, &c_ini);
    CurCount=0;
    c1=s1=c2=s2=s=Angle=0.; c=1.;
  };


  void InputData(float v1, float v2)
  { c1+=c*v1;
    c2+=c*v2;

    s1+=s*v1;
    s2+=s*v2;
    
    if(CurCount==Len-1)
    { CurCount=0;
      Angle=atan2f(c1*s2 - c2*s1, c1*c2 + s1*s2);
      c=1.;
      c1=s1=c2=s2=s=0.;
    } else
    { CurCount++;
      float new_c=c*c_ini-s*s_ini;
      float new_s=s*c_ini+c*s_ini;
      c=new_c;
      s=new_s;
    }
  };


  sPhase(int PLen) { Ini(PLen); }; // фиктивный конструктор, чтобы не повадно было не инициализировать этот класс

};


inline float my_rand() { return (float)(2.*((float)rand()/(float)RAND_MAX-0.5)); } // функция генерации случайного числа в диапазоне от -1. до 1.


int main() // тестовый пример
{ const float Alpha1=0.1, Alpha2=2.;     // две фазы для первого и второго сигналов в радианах
  const int   PLen  = 50;                // длина одного периода в количестве отсчетов АЦП
  const float Amp1  = 9.4, Amp2  =  2.1; // амплитуды сигналов, возьмем разные, от балды
  const float Bias1 = 2.6, Bias2 = -3.5; // сдвиг нуля сигналов, тоже возьмем два разных от балды
  const float NoiseLevel=0.5;            // уровень шума

  sPhase sP(PLen); // вызовем конструктор с аргументом в виде длины периода сигнала

  for(int i=0; i<1000; i++)
  { float v1 = Bias1 + Amp1*sinf(((float)i)*2.*M_PI/(float)PLen + Alpha1) + NoiseLevel*my_rand();
    float v2 = Bias2 + Amp2*sinf(((float)i)*2.*M_PI/(float)PLen + Alpha2) + NoiseLevel*my_rand();

    sP.InputData(v1, v2); // подавать сюда два измеренных сигнала
    printf("%f %f %f\n", v1, v2, sP.Angle); // и радоваться получению разности фаз в sP.Angle
  }
  printf("We are expecting the angle as %f, and it was computed as %f\n", Alpha1-Alpha2, sP.Angle);
  return 0;
} 

код на минималистическом С++ с тестовым примером под gnu-linux компилятор. На каждый приход пары данных из АЦП надо вычислять всего-то 8 умножений и 7 сложений, и на каждый период дополнительно вычислять один арктангенс. Если что-то не понятно - спрашивайте.

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


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

Спасибо за код. Извините долго не писал эту схемку после работы собираю в свободное время. Сравню результат измерения с АЦП и меандр. Что получиться точнее напишу. Микроконтроллер подобрал на мой взгляд как раз для этой цели подходит (поправьте если ошибаюсь) stm32g474  у него есть 5 АЦП и 1-2 3-4 могут работать в паре одновременно получать значение. Дока большая читаю я с ними не работал еще. Привезли макетку буду пробовать настраивать. Если у кого есть опыт может поможете  настроить?  На вход заведу дискретный сигнал фронт примерно 100нс  частота 10кгц он синхронизирован с аналоговыми сигналами. По переднему фронту нужно запустить АЦП 1 и 2 в одновременном режиме  дальше игнорировать приходящие сигналы 10кгц.  При этом АЦП должно преобразовывать каждые 2мкс и через ДМА писать в память данные  500 выборок после записи 500 вызвать прерывание.  АЦП тактируется 16мгц от внутреннего генератора, на плате есть задающий генератор 50мгц может лучше взять клок для АЦП?

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


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

8 часов назад, SergeyVas сказал:

10кгц он синхронизирован с аналоговыми сигналами

Тогда требуется из этих 10 кГц делать на ФАПЧ тактовый сигнал для МК — Вы же спрашивали про ПЦС, почему тогда продолжаете говорить о несинхронных с МК аналоговых сигналах?

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


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

На плате есть кварцевый генератор  50мгц от него происходят все  сигналы и 10кгц аналоговый тоже. Буду его использовать

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


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

On 8/30/2024 at 7:26 PM, SergeyVas said:

При этом АЦП должно преобразовывать каждые 2мкс и через ДМА писать в память данные  500 выборок после записи 500 вызвать прерывание.

если к концу этой записи из 500 выборок ваш сигнал не сделает точно 10 периодов, то мой алгоритм, что я привел выше, покажет лажу. Как правильно заметил выше уважаемый Plain - надо о синхронизации подумать.

 

Более точное значение лажи: если у вас клок убежит на n отсчетов, то при ваших 50 отсчетов на период, вы поимеете ошибку в фазе порядка 360*n/25 градусов, может чуть меньше. Много или нет - Вам судить.

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


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

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...