直接数字合成 - 什么是相位截断?

时间:2015-03-30 08:36:42

标签: c++ matlab arduino signal-processing

我正在使用C / C ++中的Arduino Due开发直接数字合成(DDS)波形发生器。但我首先在Matlab中实现一个例子,以确保我理解主要组件,包括:相位或角度累加器(N位),查找表(P位)和数模转换器(12位)。我理解这些基本要素。

查找表大小将与DAC分辨率匹配,因此P = 12。累加器至少为16位(N = 16)。因此必须在此处进行相位截断。这就是我的困惑和我的问题。截断如何工作?取N的P有效位是什么意思?

2 个答案:

答案 0 :(得分:1)

一般情况下,如果你有 N位长值,一个可能的值,比如说(二进制,即用2位表示(1' s和0' s),其中每个位,取决于其位置代表2的幂是:
1000 1111 0000 1010
最重要的位是从左到右计数的位,即:示例中的四个最重要的位是:1000。因此,通过取P有效位进行截断意味着从左到右计数直到P并且忽略左边的内容。
在十进制表示中,即使用10个数字(0,1,..,8,9)表示,这类似于:如果你的值是:110124并且你只取P = 3个有效数字,你将保持:110000,即,不考虑3个最低有效数字(124),从而失去一些细节。

答案 1 :(得分:1)

这个二进制数学和按位操作对我来说是新的,但我开始明白了。我在Matlab中实现了直接数字合成(DDS)示例。其他人的代码如下。也可以在Octave上运行。

% INPUT PARAMETERS
%-----------------------
fs    = 2^14;   % Clock Sample Rate (hz)
NT    = 1e4;    % Total Samples for example 
foutd = 80;     % Desired Output Freq. (hz)
N     = 16;     % Accumulator resolution (bits)
P     = 12;     % Lookup Table resolution (bits)


% FREQUENCY TUNING WORD
%------------------------------
FTWf = foutd/fs*2^N;          % float
FTW  = round(foutd/fs*2^N);   % actual integer term for accumulator
fout = FTW*fs/2^N;            % actual output frequency


% SINE WAVE LOOKUP TABLE
%---------------------------
x = [0:2^P-1]';
y = sin(x*2*pi / (2^P-1) );


% INITIALIZE
%--------------------------
dt    = 1/fs;                % Time Step (sec)
t     = [0:dt:dt*(NT-1)]';   % Time Vector
phase = zeros(NT,1);         % Save phase vs. time
wave  = zeros(NT,1);         % Save wave amplitude vs. time


% SAMPLE THROUGH TIME
%-----------------------
pa = 0;   % Phase accumulator

for ii=1:length(t)

    % ACCUMULATE PHASE
    pa = pa + FTW;

    % ROLLOVER PHASE
    if pa > 2^N
        pa = 1;
    end 

    % PHASE TRUNCATION
    indx = ceil(pa * 2^(P-N));

    % LOOKUP
    phase(ii) = pa;
    wave(ii)  = y( indx );

end

figure;
subplot(211),  plot(t, phase); grid on;
subplot(212),  plot(t, wave);  grid on; hold on
               plot(t,sin(foutd*2*pi*t), 'r-.');

我的下一步是在ArduinoDue上实现这一点。该算法将成为ISR中断功能的基础。我肯定会使用二元运算符来加速除法(即“相位截断”)。

之后,我需要弄清楚如何处理非整数频率输入。