|
|
  |
Как реализовать генератор квадратуры, Надо генерировать cos/sin одинаковой чатоты в DSP |
|
|
|
Dec 15 2014, 23:46
|
Знающий
   
Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730

|
Цитата(Fat Robot @ Dec 16 2014, 01:53)  Вы сами себе противоречите: Чтобы генератор был "абсолютно стабилен", полюсы его передаточной функции должны находиться точно на единичной окружности. А для любой частоты при арифметике с конечной разрядностью это, увы, не выполняется. увы, тока это и выполняется вне зависимости от разрядности. в случае биквадратного звена только результат после умножения на а1 квантуется. шум квантования есть вход для фильтра с полюсами на единичной окружности. т е неустойчивого фильтра. результат закономерен.
|
|
|
|
|
Dec 16 2014, 08:11
|
Гуру
     
Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954

|
Цитата(Fat Robot @ Dec 16 2014, 04:53)  Вы сами себе противоречите: Чтобы генератор был "абсолютно стабилен", полюсы его передаточной функции должны находиться точно на единичной окружности. А для любой частоты при арифметике с конечной разрядностью это, увы, не выполняется. с целочисленной арифметикой можно точно в желаемую частоту и амплитуду не попасть, но осциллятор будет стабильным сколь угодно долго. Цитата(thermit) в случае биквадратного звена только результат после умножения на а1 квантуется. шум квантования есть вход для фильтра с полюсами на единичной окружности. т е неустойчивого фильтра. результат закономерен. int a0, a1 = 0, a2 = 100, K=450; for (int i = 0; i < 1000; i++){ a0 = (K*a1)/256 - a2; a2 = a1; a1 = a0; printf("%d\n",a0); } через 765*N шагов, значения a0,a1,a2 опять станут -100, 0, 100, почему же он не развалился раз он не устойчивый?
|
|
|
|
|
Dec 16 2014, 08:31
|
ʕʘ̅͜ʘ̅ʔ
    
Группа: Свой
Сообщений: 1 008
Регистрация: 3-05-05
Пользователь №: 4 691

|
Я посчитал. Устойчивость действительного генератора определяется только шумами квантования отсчетов, в отличие от комплексного, где и квантованные отсчеты, и квантованные коэффициенты играют роль. Цитата(thermit @ Dec 16 2014, 00:46)  увы, тока это и выполняется вне зависимости от разрядности. Хороший пример. Много подтверждает (limit cycles при единственном значении коэффициента). Попробуйте так: К = 45 * pi * pi; Цитата(_pv @ Dec 16 2014, 09:11)  с целочисленной арифметикой можно точно в желаемую частоту и амплитуду не попасть, но осциллятор будет стабильным сколь угодно долго.
int a0, a1 = 0, a2 = 100, K=450; for (int i = 0; i < 1000; i++){ a0 = (K*a1)/256 - a2; a2 = a1; a1 = a0; printf("%d\n",a0); } через 765*N шагов, значения a0,a1,a2 опять станут -100, 0, 100, почему же он не развалился раз он не устойчивый?
|
|
|
|
|
Dec 16 2014, 08:56
|
Гуру
     
Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954

|
Цитата(Fat Robot @ Dec 16 2014, 14:31)  Хороший пример. Много подтверждает (limit cycles при единственном значении коэффициента). Попробуйте так: К = 45 * pi * pi; а как же: " А для любой частоты при арифметике с конечной разрядностью это, увы, не выполняется." ? 45*pi*pi = 444 арифметика-то целая, в частоту немного не попадёт из-за округления, но работать будет стабильно: 0 100 173 200 173 100 0 -100 -173 -200 -173 -100 0
|
|
|
|
|
Dec 16 2014, 11:08
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 17-11-11
Пользователь №: 68 371

|
Что-то мы скатились на обсуждение ерунды. Ситуация с ф-й генератора вот какая. Когда мы описываем те или иные методы, надо всегода смотреть на то, как данная ф-я будет использоваться. Вот у меня задача достаточно общая: есть приложение в котором используется DDC. Для этого DDC мне нужен генератор квадратуры с постоянной частотойк. Значение частоты может меняться, но не в реальном времени. Т.е. получаем вот что. То что считается постоянно в реал-тайме критично ко времени. То что относится к расчету параметров - не критично. В итоге получается, что расчитать один раз sin/cos/step и т.д. это не проблема, но зато потом просто умножать нару раз и выбирать значения из таблицы. В общем метод Blackfinа самое то. Сам генератор там состоит из вдух сложений и четырех умножений. А инициализация приращения и шаг таблицы расчитываются неспеша как угодно. Причем это "именно то" при условии что значения генератора реинициализируются через фиксированные промежутки (в моем случае 128 отсчетов). Методы генерирования на основе расчета синуса и косинуса "налету" с помощью полиномов и т.д. имеют свое применение. Например когда у меня частота меняется в реальном времени и я ее должен постоянно подстраивать на основе ФАПЧ или что-то такое. В этом случае конечно надо делать генератор на основе прямого расчета синуса и косинуса. То-же самое относится когда генератор должен работать на "бесконечном интервале времени". Тут шумы никуда не уйдут, и генератор просто "зазвенит".  В общем, побеждает как всегда компромис.
|
|
|
|
|
Dec 16 2014, 11:33
|
Местный
  
Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778

|
Цитата(_pv @ Dec 16 2014, 14:05)  расползётся причем синус от косинуса по фазе тоже, так как ошибка будет копиться на каждом шаге. при раздельной генерации косинус можно получить просто как производную от синуса. Компоненты вектора на единичной окружности дают всегда согласованные sin/cos, как они могут расползтись по фазе между собой? Удержание на единичной окружности обеспечивает нормирование. Итого дрейф может быть только по общей фазе/частоте, ну и амплитуда может стабилизироваться с небольшим смещением нормы от единицы. Цитата То-же самое относится когда генератор должен работать на "бесконечном интервале времени". Тут шумы никуда не уйдут, и генератор просто "зазвенит". У меня не звенит на бесконечном времени. Да и частоту тоже перестраивать пробовал в реальном времени.
|
|
|
|
|
Dec 16 2014, 11:36
|
Знающий
   
Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730

|
Цитата(_pv @ Dec 16 2014, 12:11)  с целочисленной арифметикой можно точно в желаемую частоту и амплитуду не попасть, но осциллятор будет стабильным сколь угодно долго.
int a0, a1 = 0, a2 = 100, K=450; for (int i = 0; i < 1000; i++){ a0 = (K*a1)/256 - a2; a2 = a1; a1 = a0; printf("%d\n",a0); } через 765*N шагов, значения a0,a1,a2 опять станут -100, 0, 100, почему же он не развалился раз он не устойчивый? а он и развалился. сразу. результат никак не гармоника.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|