【问题标题】:Direct Digital Synthesis - What is Phase Truncation?直接数字合成 - 什么是相位截断?
【发布时间】:2015-03-30 08:36:42
【问题描述】:

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

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

【问题讨论】:

  • 这个问题属于Signal Processing SE
  • 想象一下你的 PA 用浮点数表示。您只能使用该浮点数的(截断的)整数部分作为索引,但您仍然可以使用完整的浮点精度进行累加以最大限度地减少错误。

标签: c++ matlab arduino signal-processing


【解决方案1】:

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

【讨论】:

  • 在 C 中:index = pac >> (N-P); 或使用 0.5-roding:index = ((pac >> (N-P-1)) + 1) >> 1;
  • 回答“最重要的位”已理解。谢谢你的比喻。在以 Fs 的采样率循环的 Arduino C++ 程序的上下文中,如何处理截断?随着 N 位相位累加器增长到大小 2^N(对应于角度 2*pi),如果 P 小于 N,如何评估 P 位查找表?只是跳过的问题吗?对 Hanno Binder 来说,这就是你的代码所表示的吗?
【解决方案2】:

这种二进制数学和按位操作对我来说是新的,但我开始理解了。我在 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 中断功能的基础。我肯定会使用二元运算符来加快除法(即“相位截断”)。

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

【讨论】:

    猜你喜欢
    • 2010-11-21
    • 2017-12-06
    • 2011-08-21
    • 2018-03-17
    • 1970-01-01
    • 2023-03-04
    • 2014-11-25
    • 1970-01-01
    相关资源
    最近更新 更多