Попробую еще раз "на пальцах" и в цифрах. Допустим
имеем:
частота тактирования - 1Мгц,
таблица синуса - 36 отсчетов на период,
дискретность изменения амплитуды 1/256 (ЦАП - 8 разрядов).
хотим:
получить выходную частоту
23кГц.
Таблица у нас с приращением фазы 10 градусов для
частоты сэмплирования 1МГц/36=
27777,7(7)Гца) считаем требуемое
приращение фазы 23кГц/(1МГц/36)=
0,828, если просто округлим до целых получим
0, если правильно округлим, то получим
1. Облом-с. Тогда отсчеты у нас будут строго по таблице и выходная частота получится, не 23кГц, а 27,777кГц. Ошибка выходной частоты при этом будет (1МГц/36-23кГц)/23кГц*100%
=+20,77%. Чтобы уменьшить погрешность вычисления фазы отсчетов увеличим разрядность фазового аккумулятора. Для этого при расчете фазового приращения домножим его значение на 256 и получим 256*23кГц/(1МГц/36)=
211,968. После округления будем иметь фазовое приращение dph=
212. Поскольку у нас всего 36 элементов в таблице, то для аккумулятора фазы хватит 6-и разрядов. Но мы еще должны учесть 8-и битное расширение приращения фазы. Поэтому для аккумулятора фазы возьмем (6+8)>=16 разрядов. Берем пример исходного когда из википедии и немного дорабатываем его.
Код
#include <stdint.h>
#define SINTBLSIZE 36U //размер таблицы синуса
#define TBLIDXPRD (256U*36U) //период фазового аккумулятора
uint8_t sinTbl[SINTBLSIZE]=
{ 128, 150, 171, 191, 209, 225, 238, 247, 253, 255,
253, 247, 238, 225, 209, 191, 171, 150, 128, 105,
84, 64, 46, 30, 17, 8, 2, 0, 2, 8,
17, 30, 46, 64, 84, 105
]; // таблица синуса
uint8_t next_amp(uint16_t dph)
{ static uint16_t phase=0;
uint8_t amp;
unsigned int idx;
phase+=dph;
while(phase>TBLIDXPRD)
phase-=TBLIDXPRD;
idx=phase>>8;
amp=sinTbl[idx];
return amp;
}
Результатом работы при dph=212 будет такая последовательность
Код
128 128 150 171 191 209 209 225 238 247
253 255 255 253 247 238 225 209 209 191
171 150 128 105 105 84 64 46 30 17
17 8 2 0 2 2 8 17 30 46
64 64 84 105
127 150 171 171 191 209
225 238 247 247 253 255 253 247 238 238
Отступом я выделил период, который равен 44 отсчетам. Считаем период получившейся частоты. 1МГц/44=22727,27(27)Гц. Ошибка формирования выходной частоты составляет (1МГц/44-23кГц)/23кГц*100%=
--1,19%. Сравните с исходной погрешностью
+20,77% Улучшение точности выше, чем на порядок!
Такой пример вам будет понятен?

Еще в дополнение замечу, что поскольку в моем примере разрядность фазового аккумулятора была 16, а требуемая разрядность индекса таблицы отсчетов составляла всего 6 разрядов, то легко можно было домножать не на 2^8=256, а на 2^10=1024. Точность вычисления фазы была бы еще выше. Правда для выбранных условий это не очень актуально, т.к. выходная частота и табличная частота сэмплирования слишком близкие.