NB Частотная модуляция в dsPIC33
Сначала я пытаюсь сделать модулятор NB FM (затем я хотел бы реализовать модулятор WB), но мне нужна помощь, чтобы понять основы DDS.
Я использую встроенную систему с сигнальным процессором dsPIC33EP256MU806. Я установил осциллятор и TIMER1 на желаемые значения, так что теперь у меня есть прерывание 304 кГц (8*38 кГц на будущее). Я хотел бы сделать процесс модуляции в этом прерывании, вычислив данные I и Q. У меня на панели два ЦАП типа DAC8830 16 бит, я выставил шины SPI(3-4), они работают хорошо. Эти ЦАП работают с беззнаковыми 16-битными выборками. (0x0000 - 0 В; 0xFFFF - Vref)
Я нашел некоторую информацию о том, как вычислить максимальное отклонение частоты с помощью N-битного фазового аккумулятора и M-битного настроечного слова со знаком. Итак, если у меня есть 8-битное настроечное слово со знаком с 11-битным фазовым аккумулятором и эта "частота обновления" 304 кГц, максимальное отклонение будет:
(-128*304 кГц)/2^11 = -19 кГц
Что может быть идеальным для меня для тестирования моей системы, но я не могу знать, как правильно сделать эти числа беззнаковыми (хорошо для моей цели). У меня есть массив с 2048 (2^11) выборками (синус [2048]), они представляют один период синуса. Эти образцы представляют собой 16-битные беззнаковые образцы, соответствующие выходному диапазону ЦАП. Я хотел бы использовать синусоидальную волну 1 кГц для входного сигнала (настроечное слово), поэтому я определил другой массив с 304 выборками (sin1k[304]), где каждая выборка имеет ширину 8 бит, без знака.
Теперь у меня есть этот код в прерывании TIMER1:
void __attribute__((__interrupt__, __auto_psv__)) _T1Interrupt(void)
{
_T1IF = 0; //Reset TIMER1 interrupt flag
if (sin1k[j]<128)
acc = acc-((sine[(sin1k[j])])/256);
else
acc = acc+((sine[(sin1k[j])])/256);
IDACCS = 0; //I DAC Chip select active (low)
QDACCS = 0; //Q DAC Chip select active (low)
SPI3BUF = (sine[acc]); //Load the data to the SPI3, IDAC buffer
SPI4BUF = (sine[acc]); //Load the data to the SPI4, QDAC buffer
SPITXwait(); //Wait for the data to be transmitted
IDACCS = 1; //I DAC Chip select inactive (high)
QDACCS = 1; //Q DAC Chip select inactive (high)
if (acc>2047) acc=0; //Phase accumulator overflow test
if (acc<0) acc=2047; //Phase accumulator underflow test
j++; //Sine 1k tuning word array increment and overflow test
if (j>303) j=0;
}
Как вы можете видеть на моем старом добром аналоговом осциллографе, у меня выходной сигнал FM-подобный, но есть ошибки в точках пересечения нуля. (Ссылка на изображение в конце сообщения) Кто-нибудь может помочь понять, что я делаю не так?
Большое спасибо!
С уважением,
Питер