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

Цифровой генератор синусоиды

SSerge, так вам надо постоянно генерировать синусоиду во времени или всё-таки синусы произвольных аргументов считать?

 

Для первого случая ничего лучше sin(a + b) не придумаешь.

 

Для второго случая: я писал библиотеку для TI DSP 64XX. Использовал свой формат с плавающей точкой мантисса - 23 бита, только нормированные числа так что значащих бит вообще 22. Синус считал тейлором на отрезке 0 - Пи/4 (для синуса на этом отрезке полином был такой x + A*x^3 + B*x^5 + C*x^7) в итоге для всего допустимого диапазона значений аргумента (что-то типа до 2^24) получается погрешность 4 ULP от floata, то есть 2 ULP от моего представления. A, B и C похожи на тейлоровские но слегка модифицированные чтобы минимизировать относительную погрешность. По любому больше чем 18 бит точности (не забываем ещё и про argument reduction, который у меня есть и соответственно он тоже привносит ненулевую погрешность). Без argument reduction на 0 - Пи/4 ошибка 1 ULP флоата (в принципе это неустранимая ошибка так как мантисса на 1 бит меньше).

 

вот на всякий случай кодд:

 

CAFloat sin1 = -0.16666666666666666666666666666667f;

CAFloat sin2 = 0.0083333333333333333333333333333333f;

CAFloat sin3 = -0.0001984126984126984126984126984127f*0.9925f;

 

inline CAFloat CF_sin_reduced(const CAFloat &x)

{

if(_ext(x.x, 0, 24) < -11)

return x;

 

CAFloat arg = x * x;

return x + x*(sin1 + arg*(sin2 + arg*sin3))*arg;

}

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


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

Посмотрите эту статью.

Можно зайти на сайт GlobalDSP

Стастья за декабрь 2003 года -> Algorithms (Fast, Continuous, Sine Wave Generator)

Судя по статье, результаты не плохие. Там же есть пример кода на DSP.

 

Успехов.Pages_from_GlobalDSP_December2003.pdf

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


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

Попробуйте применить DDS (прямой цифровой синтез) или, по крайней мере, применить те же алгоритмы

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


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

Попробуйте применить DDS (прямой цифровой синтез) или, по крайней мере, применить те же алгоритмы

Это же чистая табличная реализация, с нее-то и начинали. А в Spartan'е, между прочим, память свободная не завалялась? А то можно взять и просто сделать аккумулятор фазы бита на 32 и иметь ~0,01Гц разешение (см. теорию DDS лучше по datasheet на AD9854) . Хотя -90dB получишь где-то в районе 32к-точечной таблицы...

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


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

Требуется сформировать 2 синуса (естественно в цифре). Можно пойти табличным методом - но для 8 бит и 1к хватит, а для 18 бит и метра может мало оказатся. Есть другой метод http://www.gaw.ru/html.cgi/txt/doc/...v/max2000_5.htm .

Но интересные эфекты: даже при инт64 вылазеют гармоники на уровне -70 дб + к этому и частота не точно заданная.

Попробывал так:

X(n)=k*X(n-1)-X(n-2), где k=2*cos(2*Pi*F/Fd);

для 0 градусов X(-1)=0, X(-2)=-A*sin(2*Pi*F/Fd);

для 90 градусов X(-1)=A, X(-2)=A*sin(pi/2+2*Pi*F/Fd)

90 гр. частота на сотые доли процентов выше и уползает вперёд по отношению к 0 гр.

Сейчас хочу через приблежённое вычеслени по Тейлору попробывать. Но явно по вычислениям более накладно будет.

Может ещё есть способ с минимум вычислений сгенерить синус?

(Всё должно в итоге оказатся в FPGA Спартан3).

А микросхему DDS поставить не проще?

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


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

Попробуйте применить DDS (прямой цифровой синтез) или, по крайней мере, применить те же алгоритмы

Это же чистая табличная реализация, с нее-то и начинали. А в Spartan'е, между прочим, память свободная не завалялась? А то можно взять и просто сделать аккумулятор фазы бита на 32 и иметь ~0,01Гц разешение (см. теорию DDS лучше по datasheet на AD9854) . Хотя -90dB получишь где-то в районе 32к-точечной таблицы...

 

Я реализовал DDS на сигнальном процессоре. Для сокращения объема выборок (оставил 1024 отсчета) использовал линейную интерполяцию между соседними отсчетами (старшие 10 бит фазового аккумулятора адресуют выборку из таблицы, а младшие (32-10) бит используются для интерполяции). На интерполяцию ушло 2 умножения и 3 сложения. Проверял в MathCad, отличие от чистой синусоиды не более 5*10^-4 % (я, правда, не учитывал, что выборки 16-битные).

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


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

А что, линейная интерполяция... не так уж и плохо... А хранить можно только pi/2, усложнив адресацию и добавив (+/-).

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

5e-4% - это не так и много, около -66dB, а как получено это значение (среднее квадратичное отклонение или...)? Посчитать бы еще Кг.

Изменено пользователем sansh

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


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

Думаю, что ещё раз в 10 улучшить интерполяцию синуса можно если линейно интерполировать производную, а потом брать от неё интеграл. Например если нарисовать производную в виде треугольного сигнала, то первообразная будет очень похожа на синус.

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


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

Дык производная ж - тот самый синус: sin'(x) = cos(x) = sin(x+pi/2).

И про интегрирование не понял, как его делать? Каждый новый отсчет в копилку класть? Тогда быстро за пару десятков периодов набежит ошибка.

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


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

Есть две табличные точки А и Б. Б-А = интеграл от производной. При линейной интерполяции подразумевается производная = const = (Б-А)/шаг таблицы. Однако если производную наклонить так, чтобы "определённый интеграл" не изменился, то получится гораздо большая точность. При этом производная будет прямой наклонённой линией. Никаких накоплений для этого делать не надо. Немного больше арифметических действий и фсё.

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


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

http://www.gaw.ru/html.cgi/txt/doc/micros/...v/max2000_5.htm

 

Требуется генерить синусоиды с частотами от 300 Гц до 2,5 МГц с шагом 1 Гц.

Желательно с нелиненостями -90 дБ. Проект - селективный вольтметр, с полосами 30 и 100 Гц, желательно и со спектроанализатором.

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

Т.к. в спартане умножители 18 битные, то и синус желательно сформировать 18 битный. Частота опорного генератора 10 МГц.

 

Готовый DDC, например AD6620, не хотите попробовать?

 

А так, для этой задачи не столько нелинейность синуса важна, сколько SFDR (хотя они взаимосвязаны). При этом спектральные "палки" можно с помощью дизеринга "размазать". У нас, например, -110dBc SFDR получалось на таблице 256x25 бит с линейной интерполяцией и дизерингом фазы (около -90dBc без дизеринга).

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


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

Подскажите кто-нибудь сколько я насчитал децибелл.

Составил прогу на паскале с линейной интерполяцией синуса по таблице 256*16 бит. Максимальное отклонение по центру между колонками составило 3.1e-6 относительно самого синуса (+-1.0).

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


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

Аномалия какая-то!!!

Таблица 128*13 бит с линейной интерполяцией даёт ещё большее качество - 0.9e-6 !!!

 

 

Кто-нибудь может мне это объяснить?

Изменено пользователем GetSmart

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


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

Подскажите кто-нибудь сколько я насчитал децибелл.

Составил прогу на паскале с линейной интерполяцией синуса по таблице 256*16 бит. Максимальное отклонение по центру между колонками составило 3.1e-6 относительно самого синуса (+-1.0).

 

Странно. При ширине выхода таблицы 16бит, максимальное отклонение от "истинного" синуса должно было быть порядка 1.5e-5. Или в программе что-то не то, или я не правильно понял, что такое "Максимальное отклонение по центру между колонками" :(.

 

При отклонении от "идеального" синуса на 3.1e-6, SFDR даже в самом поганом случае (вся "энергия" отклонения "ушла" в один спур), думаю, будет ниже -110dBc.

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


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

Вот прога на паскале. Если кто хочет меня проверить.

 

При отклонении от "идеального" синуса на 3.1e-6, SFDR даже в самом поганом случае (вся "энергия" отклонения "ушла" в один спур), думаю, будет ниже -110dBc.

Правда? А для 0.9e-6 сколько децибелл будет?

sinus.rar

Изменено пользователем GetSmart

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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