主要是想大致了解Sigma-delta ADC是怎么工作的,写了个乱七八糟的代码来简单看下。很粗略的解释,主要给自己参考。

SAR ADC

successive approximation register adc,简单理解为一个采样开关和采样电容。采样开关定时闭合,忽略暂态,则采样电容上的电压等于采样开关闭合时刻的输入电压。

image-20220403105120710

因此理想的SAR ADC相当于一个采样开关 ,把连续的输入信号变成了离散的采样结果。

或者,另一种画图的方法,就是说,[n*Ts,(n+1)*Ts]期间的采样结果恒定为Vin(n*Ts)

image-20220403102424255

Sigma-delta ADC

核心是sigma-delta调制,如下图。

1-bit DAC的输出只有两种电压,取决于给它提供的电压基准Vref+和Vref-:

  • 输入为0,输出为Vref-
  • 输入为1,输出为Vref+

sigma-delta调制的运算过程:

  • 输入与1-bit DAC相减,得到误差
  • 对误差积分
  • 积分结果与0比较,输出调制信号
  • 同时,调制信号再通过1-bit DAC反馈到输入侧,与输入相减

通过sigma-delta调制,输入的模拟量变为了01的调制信号。而且0和1的比例与输入信号幅值有关。举个极端的例子,

DAC的参考Vref+=3V,Vref-=0。输入信号也是2.99V,那么,

  • 第1次运算,误差2.99V,积分器输出2.99V,调制信号1

  • 第2次运算,误差-0.01V,积分器输出2.98V,调制信号1

  • 第299次运算,误差-0.01V,积分器输出0.01V,调制信号1

  • 第300次运算,误差-0.01V,积分器输出0.00V,调制信号0

大致可以看出,当输入信号电压高时,调制信号中的1占比就更高。

image-20220403103423943

以上过程转换成matlab代码:

    sigma_delta = zeros(1,N_over_sample); 
    for i = 1:N_over_sample  % intput: N samples, output: N sigma_delta values
        vfb = vref * out; % 根据上一次比较结果,vfb可能是0,也可能是Vref
        err = vin(k*N_over_sample+i) -  vfb; % 误差
        vint = vint + err; %积分
        out = (vint > 0); %再与0比较
        sigma_delta(i) = out; %输出的sigma_delta调制结果
    end
    SigD_result(k+1) = mean(sigma_delta)*vref; 
    % 对调制后的信号低通滤波,再乘以Vref可以获得最终ADC结果。
    % 比如,可以用求平均值实现低通滤波
    % ADC results is obtained by averaging the N sigma_delta values and *vref

image-20220403102438382

对比

降低采样频率,便于画图对比两种ADC的区别:

  • 对于SAR ADC,转换结果是输入信号在某个时刻的实际值
  • 对于sigma-delta ADC,转换结果接近输入信号在某一小段时间内的平均值

image-20220403102528263

TI视频的这张图解释得更清楚一些:

image-20220403102926743

参考资料

查到ADI官网上有个教程,里面可以一步一步演示Sigma-delta调制过程,可以参考下。

Sigma-Delta ADC Tutorial | Design Center | Analog Devices

TI有个视频,介绍两种ADC的基本原理。

https://youtu.be/U_Yv69IGAfQ

画各个图的代码:

close all;
clear;

f0 = 1e3; % frequency of the input signal 
T = 1/f0; % period 
dt = 1e-8; % time step 
t = 0:dt:T; 
vin = 1+sin(2*pi*f0*t)+0.3*sin(2*pi*3*f0*t); % input signal


Fs = 20e3; % sample rate
Nt = round((1/Fs)/dt); % 每Nt个点中取一个作为理想SAR ADC的采样结果

SAR_result = vin(1:Nt:length(vin)); % SAR结果
SAR_t_instance = t(1:Nt:length(vin)); % SAR采样时刻

figure(1)
plot(t,vin,SAR_t_instance,SAR_result,'*');
grid

% 换种方式来画SAR ADC的图,就是说,[n*Ts,(n+1)*Ts]期间的采样结果恒定为Vin(n*Ts)
v_sar = vin;
sample = vin(1);
for i = 1:length(vin)
    if mod(i,Nt) == 0 % From Ns*100 points, take Ns samples, thus 1 out of 100 
        sample = vin(i);
    end
    v_sar(i) = sample; 
end
figure(2)
plot(t,vin,t,v_sar)
grid

% 换种方式来画SAR ADC的图


% Sigma-delta ADC 
vref = 3; %这里Vref_P=3V  Vref_N = 0V

Fs_sigma = 20e3;
N_over_sample = round((1/Fs_sigma)/dt); %例如,sigma delta 对1000次采样进行运算,输出1个最终结果
N_sample = round(length(vin)/N_over_sample); 
%例如采样周期是dt=100MHz,每1000个
SigD_t_instance = zeros(1,N_sample);
SigD_result = zeros(1,N_sample);
for k = 0:N_sample-1
    sigma_delta = zeros(1,N_over_sample); 
    vint = 0;
    out = 0;
    for i = 1:N_over_sample  % intput: N samples, output: N sigma_delta values
        vfb = vref * out; % 根据上一次比较结果,vfb可能是0,也可能是Vref
        err = vin(k*N_over_sample+i) -  vfb; % 误差
        vint = vint + err; %积分
        out = (vint > 0); %再与0比较
        sigma_delta(i) = out; %输出的sigma_delta调制结果
    end
    SigD_result(k+1) = mean(sigma_delta)*vref; 
    % 对调制后的信号低通滤波,再乘以Vref可以获得最终ADC结果。
    % 比如,可以用求平均值实现低通滤波
    % ADC results is obtained by averaging the N sigma_delta values and *vref
    SigD_t_instance(k+1) = t((k+1)*N_over_sample);
end
figure(3)
plot(t,vin,SigD_t_instance,SigD_result,'*')
grid


figure(4)
plot(t,vin,t,v_sar)
hold on
plot(SigD_t_instance, SigD_result,'*')
grid



Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐