Цитата(akimych @ Feb 9 2011, 01:00)

А что надо получить в конечном итоге, прямоугольник заданной частоты? Может быть как-то на таймерах это сделать, неужели синус + компаратор лучше (не спорю, просто не сталкивался).
Мне нужны разные виды модуляции, в том числе ЛЧМ.
Код
typedef struct
{
u32 freq_start; //начальная частота, Гц
u32 freq_stop; //конечная частота, Гц
u32 tau_f; //время изменения от начальной до конечной, мкс
u32 tau_d; //длительность радиоимпульса,мкс
u32 freq_carrier;//частота гетеродина, Гц
}DDS_CONFIG;
Таймера в стм32, конечно, хорошие, учитывая 16-битные прескалеры и авторелоады (кстати, для гетеродина использую), позволяют с достаточной точностью получить требуемые частоты, но не годятся для получения ЛЧМ-сигнала: при частоте 400кГц и тактовой таймера 72МГц прескалер=0, ARR=180-1. Следующее возможное значение по частоте 72000/179=402,234кГц, ниже 397,790кГц, - порядок шага по частоте ясен. Сравним с разрешающей способностью DDS (аккумулятор 32-битный) dF=Fd/2^32=72000000/(кол-во тактов на выполнение кода DDS)/2^32=72000000/20/2^32=0,00083819 Гц.
Это почему не таймеры, с приращением ARR в обработчике.
А почему именно синусы (комплементарные), кажется пояснял выше, может нет, повторюсь: кажется очевидным простой ход - вместо таблицы синуса подсунуть DDS-у таблицу меандра (наполовину 0х000, наполовину 0хFFF), как вариант, можно выводить на пин старший бит из таблицы сигнала. На низких формируемых частотах можете не заметить, но на высоких выползает джиттер (дрожат фронты). Причина в большой величине приращения аккумулятора фазы на каждом шаге... вобщем, тут нужно прочувствовать и увидеть

А побороть это можно сделав 2 синуса, отфильтровать и подать на компаратор - так сделано у Analog Devices в некоторых DDS-чипах.
Цитата(akimych @ Feb 9 2011, 01:00)

На счет цапов я бы предложил попробовать реализовать используя возможности стм32, а именно дма + синхр. по таймеру.
Не знаю.... В итоге нужно в ЦАП-ы засовывать, посредством дма или софтом, значение из таблицы сигнала, причём не значения по порядку, а вычислять индекс на основании значения аккумулятора фазы, так что сдаётся мне, дма по таймеру здесь не помогут. Собсно код:
Код
....
register union
{
struct
{
uint32_t unused:24;
uint32_t index:8;
}field;
uint32_t total;
}acc;
......
while(bStopDSS == 0)
{
if( dp > freq_stop )
{
// acc.total = 0;
dp = freq_start;
ddp = tau;
// break;
}
DAC->DHR12RD = _sinewave[acc.field.index];
acc.total += dp;
dp += ddp;
}