реклама на сайте
подробности

 
 
4 страниц V  « < 2 3 4  
Reply to this topicStart new topic
> Как реализовать генератор квадратуры, Надо генерировать cos/sin одинаковой чатоты в DSP
_pv
сообщение Dec 16 2014, 11:55
Сообщение #46


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(thermit @ Dec 16 2014, 17:36) *
а он и развалился. сразу. результат никак не гармоника.

а что же это тогда?
возьмите калькулятор и разницу меджу {0, 100, 173, 200, 173, 100, 0} и 200*sin(2*PI*i/12) посчитайте.

Цитата(amaora @ Dec 16 2014, 17:33) *
Компоненты вектора на единичной окружности дают всегда согласованные sin/cos, как они могут расползтись по фазе между собой? Удержание на единичной окружности обеспечивает нормирование. Итого дрейф может быть только по общей фазе/частоте, ну и амплитуда может стабилизироваться с небольшим смещением нормы от единицы.

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

это я погорячился синус/косинус конечно будет нормальный, но общая фаза(соответственно частота) поползёт
Go to the top of the page
 
+Quote Post
Fat Robot
сообщение Dec 16 2014, 11:55
Сообщение #47


ʕʘ̅͜ʘ̅ʔ
*****

Группа: Свой
Сообщений: 1 008
Регистрация: 3-05-05
Пользователь №: 4 691



Конечно. Даже в вашем простом примере в диапазоне частот (К=1..511) амплитуда на выходе меняется на 4 разряда или в 16 раз.
Если отсчеты и коэффициенты принять 16 разрядными, то изменение амплитуды в зависимости от частоты будет уже в пределах 8 разрядов. Попытки как-то ограничить разрядность умножителя будут приводить к описываемым эффектам. То, что при полной разрядности арифметических блоков генератор будет стабилен, мы обсудили.

Зависимость амплитуды от частоты я уже даже за недостаток не считаю.

Цитата(_pv @ Dec 16 2014, 10:49) *
давайте поможем друг другу, Вы мне расскажете как правильно printf пользоваться, а я Вам - чем арфиметика с плавающей запятой от целочисленной отличается.
а потом вернёмся к вопросам устойчивости.
Go to the top of the page
 
+Quote Post
_pv
сообщение Dec 16 2014, 12:13
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(Fat Robot @ Dec 16 2014, 17:55) *
Конечно. Даже в вашем простом примере в диапазоне частот (К=1..511) амплитуда на выходе меняется на 4 разряда или в 16 раз.
Если отсчеты и коэффициенты принять 16 разрядными, то изменение амплитуды в зависимости от частоты будет уже в пределах 8 разрядов. Попытки как-то ограничить разрядность умножителя будут приводить к описываемым эффектам. То, что при полной разрядности арифметических блоков генератор будет стабилен, мы обсудили.

Амплитуда определяется начальными значениями a1 и a2, а не только K который задаёт частоту. и соответственно амплитуду можно сделать какой угодно, так что замечание вообще мимо.
что такое полная разрядность? вот выше пример при 9х9->(18 с округлением до 10) разряном умножении, он как, нестабилен?
давайте до 4х разрядов ограничим
int a0, a1 = 0, a2 = 10, K=12;
...
a0 = (K*a1)/16 - a2;
работать он от этого не перестанет.

зы с printfом то что не так?
Go to the top of the page
 
+Quote Post
Russky
сообщение Dec 16 2014, 12:22
Сообщение #49


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 17-11-11
Пользователь №: 68 371



Цитата(_pv @ Dec 16 2014, 15:25) *
генератор путём умножениея на матрицу поворота нестабилен, а если реинициализировать его каждые 128 шагов, то синус/косинус всё равно придётся честно вычислять для текущего значения фазы при реинициализации.


Нет. Не придется вычислять каждый раз.
Вы немного не поняли принцып.

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

Т.е. я считаю приращение по таблице для каждых 128 отсчетов, и матрицу поворота для каждого отсчета.
В итоге все работает вот как:
Когда я запускаю обработку 128 отсчетов, я загружаю начальные значения из таблицы (это константа), загружаю приращения синуса и косинуса (то-же константы расчитанные один раз при задании частоты) и потом считаю 128 раз поворот. После этого я делаю щаг по таблице, и сохраняю состояние указателя таблицы. В следующий раз повторяется все то-же самое.
В итоге, для таблицы в 1024 отсчета, и пакета 128 отсчетов, я могу генерировать синус с частотой кратной 128*1024 ( = 131072). Если нужно, то я могу переинициализировать не каждые 128 отсчетов, а каждые 1024, и получим мы кратность частоты 1024*1024, что в общем афигенно! sm.gif
Соотношением сигнал/шум мы конечно жертвуем в некоторой степени, но "за все надо платить". sm.gif
Go to the top of the page
 
+Quote Post
thermit
сообщение Dec 16 2014, 13:05
Сообщение #50


Знающий
****

Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730



Цитата(_pv @ Dec 16 2014, 15:55) *
а что же это тогда?
возьмите калькулятор и разницу меджу {0, 100, 173, 200, 173, 100, 0} и 200*sin(2*PI*i/12) посчитайте.


Да. у вас крутой генератор.
Снимаю чепчик...
Go to the top of the page
 
+Quote Post
_pv
сообщение Dec 16 2014, 13:20
Сообщение #51


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(thermit @ Dec 16 2014, 19:05) *
Да. у вас крутой генератор.
Снимаю чепчик...

и как же тогда должно быть при 8ми разрядных коэффициентах и частоте в 0.1 от тактовой, взятых просто для примера?
или кто-то мешает разрядность увеличить так, чтобы ошибка квантования стала меньше допустимой?
Go to the top of the page
 
+Quote Post
andyp
сообщение Dec 16 2014, 16:12
Сообщение #52


Местный
***

Группа: Участник
Сообщений: 453
Регистрация: 23-07-08
Пользователь №: 39 163



Цитата(Russky @ Dec 16 2014, 15:22) *
Нет. Не придется вычислять каждый раз.
Вы немного не поняли принцып.


Откройте для себя наконец как работает табличный DDS с интерполяцией. Заодно сможете любую частоту генерить из одной таблицы разумного размера. Вычислений там - пара умножений и сложений на отсчет.
Go to the top of the page
 
+Quote Post
mihalevski
сообщение Jan 6 2015, 14:18
Сообщение #53


Частый гость
**

Группа: Участник
Сообщений: 100
Регистрация: 20-05-10
Из: Omsk
Пользователь №: 57 391



Цитата(Russky @ Dec 10 2014, 22:43) *
Всем привет!
Вот есть задача - генерировать квадратурный сигнал для DDC. DDC сам реализован внутри DSP, поэтому надо алгоритм чтобы его можно было-бы реализвать потом на аасемблере.
Используется плавующая точка.
В идеальном случае ф-я должна выглядеть так:
result = GenSinCos(float freq); где result это структура содержащая Cos и Sin, т.е. сигналы сдвинуты на 90 градусов.
freq - 0...1.
Ф-я вызывается для каждого отсчета. Начальная фаза в общем не очень важна. Главное чтобы 90 градусов было. По идее это даже не ф-я а макрос.
Как-то так.
Может кто уже встречал подобное? Или может уже есть готовые решения?

Особенность в том, что наверняка есть решение которое не вызывает ф-ю sin и cos каждый раз. sm.gif

Спасибо!

PS. Табличный метод не предлагать! sm.gif



Функция из работающей программы писал для DSP правда на Сях далее сами разберетесь и переведете на asm:



//Генератор гармонического колебания с рекуррентным вычислением
//Возвращает значение функции cos + i * sin при каждом вызове функции
//Fs - частота генерируемого колебания, Гц
//Fd - частота дискретизации, Гц
//phase - начальная фаза в градусах
//order - изменение этого параметра используется для сброса накапливающихся
//ошибок и устанавливает процесс генерации в исходное состояние с заданной фазой
//Параметр order не должен быть равным нулю
//Значения Fs и Fd активируются только одновременно с изменением параметра order
//Параметр order может меняться в любой момент
complex_long_double generator_sin_cos(long double Fs, long double Fd, long double phase, int order)
{
static long double a, b, sin, cos;
static int i = 0;
long double c_1, s_1, pi2, radian;
complex_long_double rez;

if(i != order)//инициализация
{
pi2 = 6.28318530717; radian = 57.29577951308;
a = cosd( pi2 * Fs / Fd ); b = sind( pi2 * Fs / Fd );
sin = sind( phase / radian ); cos = cosd( phase / radian ); i = order;
}


c_1 = cos; s_1 = sin;

cos = a * c_1 - b * s_1;// cos и sin есть отсчеты взаимно ортогональных колебаний
sin = a * s_1 + b * c_1;
rez.re = cos; rez.im = sin;

return rez;
}// end generator_sin_cos()



Go to the top of the page
 
+Quote Post

4 страниц V  « < 2 3 4
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st June 2025 - 20:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01505 секунд с 7
ELECTRONIX ©2004-2016