摘要 Σ-ΔADC应用设计方法以很低的采样分辨率和很高的采样速率将模拟信号数字化,克服了传统RC充放电电路模拟ADC受RC误差、PCB分布电容及温度的影响导致一致性太差的缺点。
关键词 P87LPC764 片内比较器 Σ-ΔADC 噪声整形 数字滤波
一、简介
Σ-ΔADC主要使用数字技术,具有数字系统高可靠性、高稳定性的优点,也为用单片机软件实现ADC提供了可能性。
Σ-ΔADC具有分辨率高、线性度好、抗干扰能力强(对噪声的抑制能力不亚于双积分ADC)、成本低等不可多得的优点。Σ-ΔADC以很低的采样分辨率(1bit)和很高的采样速率将模拟信号数字化,通过使用采样、噪声整形和数字滤波等方法增加有效分辨率,然后,对ADC输出进行采样抽取,以降低有效采样速率。
本文研究用低成本单片机实现8位精度的Σ-ΔADC的软件实现方法,并给出具体线路及源代码。关于16位分辨率ADC实现的技术较为复杂,后续将有文章详细介绍。
本方案适用于PHILIPS 51LPC系列P87LPC760/761/762/764等内含比较器的单片机,经在摩托车车速里程表、电子秤(人体秤、脂肪秤、厨房秤)、电热水器、电饭锅、消毒碗柜、电冰箱等一系列产品中实际使用证明:不受RC器件的误差、PCB板的分布电容及环境温度变化的影响,软件便于无障碍地移植,测量结果一致性好,实用、可靠、价格低廉,且能够满足大多数速度要求不太高的产品。
二、原理
Σ-ΔADC主要由调制器、数字滤波和采样抽取等几部分组成,如图1所示。调制器本质上是一个高速低精度(1bit)的ADC,调制器以非常大的过采样率采样模拟信号。在这个阶段,调制器将输入和输出之间的差值(Δ)进行一阶或多阶积分(Σ),结果通过一个量化器(1位ADC)输出二进制码流。该码流一方面输出给数字滤波,另一方面通过一位DAC后和输入信号比较产生差值信号,继续反馈循环。通过数字滤波和采样抽取,滤除经过调制器整形后的量化噪声,提高系统精度。采样抽取的底限是满足信号无损重建的采样定律,采样频率大于奈奎斯特频率两倍(fn>2fb)。

图1 Σ-ΔADC组成原理图
1. 调制器数学模型
图2所示为调制器的组成框图,其中一位A/D的量化器由比较器构成,检测出差值积分后的正负结果转换成1、0的位流。转换过程中会产生基于转换精度的量化误差(±1/2LSB),它是分布在整个频域范围内的白噪声。

图2 调制器数学模型
调制器的离散描述如图3所示。

图3 调制器离散性描述图
积分器在Z域由具有如下传递函数的累加器构成:

系统的Z域描述如下:

输入信号无损地传到输出端W(z)=1。量化噪声的传递函数N(z)=1-z-1,对应于频域的一阶高通滤波器(HP1),传输特性如图4中HP1线所示。

图4 噪声传输特性图
噪声传输特性图4中HP2线是二阶系统的噪声传输特性。当采用二阶以上系统时,通带内的量化噪声已基本滤除,噪声被转移到所关心的频带以外,将通过数字滤波去除。
2. 过采样对量化噪声的影响
奈奎斯特采样时,量化噪声的能谱密度为

其中Δ为量化步长,fa为模拟信号经抗混叠低通滤波后的通带频率(=奈奎斯特频率)。通带范围内,噪声电压的有效值为
,如图5所示。

图5 带模拟低通滤波器采样频谱图
当以Kfs的采样速率进行过采样时,奈奎斯特频率增至Kfs/2,量化噪声位于0~(1/2)Kfs之间,其有效值降为原来的
,调制器将噪声转移到fs/2 ~kfs/2之间,这部分噪声由数字低通滤波器滤除,如图6所示。

图6 带模拟低通及数字滤波器的采样频谱图
3. 信噪比以及精度转换
通过以上分析可知,提高调制器的阶数(n)和过采样率(OSR)均可提高系统的信噪比SNR。

b位ADC的理想信噪比(动态范围DR)可用如下方式求得。
信号功率:

噪声信号功率(白噪声):

信噪比:

由以上关系可得图7所示关联图。

图7 信噪比及精度转换关系图
图7中,左边纵轴为信噪比SNR(或动态范围DR),单位为3dB;右边纵轴为位数;横轴为过采样率(OSR)。函数线由式(1)计算所得,n为调制器的阶数。右纵轴的分布由式(2)计算所得。
DR为信号的动态范围,即最大信号与杂散信号之比。由于此处输入的为理想信号,无谐波分量,杂散信号只有量化噪声,故动态范围即为信噪比SNR。
由图7可知,8位ADC的理想信噪比大致为45dB,采用一阶调制器实现需要大于64的过采样率。实现12位精度需要大于380的过采样率,16位需大于2415。
三、实现
1. 基本方案
如图8所示为用单片机实现一阶Σ-ΔADC的原理图,虚线框内为MCU。

图8 一阶Σ-ΔADC的基本方案原理图
其中,阻抗变换器实际为一跟随器,用于减小信号源内阻的影响。如果不考虑边缘的非线性,积分器可用简单的RC网络替代,如图9所示。

图9 一阶Σ-ΔADC的简化方案原理图
一位量化器可用单片机的内部比较器,也可以用普通口线替代,只是不同的单片机口线翻转电平不一样,测量结果差别很大。一位DAC用口线置高或置低来模拟,需较强的高电平驱动能力。图10所示为用P87LPC764内部比较器实现的8位ADC原理图,比较器偏置在(1/2)VCC,输入信号的内阻必须足够小,必要时可加跟随器。

图10 8位Σ-ΔADC的基本方案原理图
;特殊功能寄存器定义
P1M1 DATA 91H ;P1方式寄存器1
P1M2 DATA 92H ;P1方式寄存器2
PT0AD DATA 0F6H
P0M1 DATA 84H ;P0方式寄存器1
P0M2 DATA 85H ;P0方式寄存器2
CMP1 DATA 0ACH ;比较器1控制寄存器
CMP2 DATA 0ADH ;比较器2控制寄存器
;变量定义
;端口定义
AD_CON BIT P1.6
ORG 0000H
AJMP START
;*******************************************
START:
MOV SP,#60H
MOV PT0AD,#24H ;禁止CMPREF、CIN2A
ANL P0M2,#0DBH
ORL P0M1,#24H
MOV CMP2,#20H ;CIN2A为输入端
MAINLOOP:
LCALL AD_CONV
SJMP MAINLOOP
;*******************************************
;Σ-Δ ADC转换程序
;占用R2,R3,R4,R5结果于A中
;*******************************************
AD_CONV:
ORL P1M2,#40H
ANL P1M1,#0BFH ;AD_CON设为上拉
AD_START:
MOV R4,#2 ;循环次数
MOV R2,#0 ;总计数值256次
AD_TEST:
MOV R3,#0 ;TON计数值256,开始转换
AD_LOOP:
MOV A,CMP2
JB ACC.1,AD_HIGH
SETB AD_CON ;输出正脉冲
NOP
NOP
SJMP AD_COUNT
AD_HIGH:
CLR AD_CON ;输出负脉冲
CJNE R3,#255,AD_INC
SJMP AD_COUNT
AD_INC:
INC R3
NOP
AD_COUNT:
LCALL DELAY10us
DJNZ R2,AD_LOOP ;未完成256次循环,继续
DJNZ R4,AD_TEST
MOV A,R3 ;转换完成,存结果于A
RET
;----------------------------------------------
DELAY10us:
MOV R5,#10
DJNZ R5,$
RET
2. 试验结果
表1为试验测试报告。测试条件:VCC = 4.92V,晶振12MHz,采用以上线路和源代码。由于没有采用跟随器,结果有些偏差。
表1 测试报告
3. 扩充方案
(1) 原理
图11所示为一阶Σ-ΔADC原理图。该方案由于相对于被测信号量化,被测信号即为比较基准,被测信号和基准之间无电压差,其积分为零,故只对反馈信号求积。电容C的信号围绕Vin上下变化,完成Σ-ΔADC差值(Δ)和积分(Σ)的作用,实现比较巧妙,完全符合一阶Σ-Δ模型。输入信号端加一电阻电容,形成一阶RC低通滤波器,滤除高频杂散信号,有抗混叠滤波的作用,同时也可补偿比较器的失调误差。

图11 一阶Σ-ΔADC的扩充方案原理图
图11所示电路,采样频率500kHz(20μs采样一次),过采样率OSR=256>64,输出数据速率 1.95kHz,采用一级256阶梳状滤波后完全可满足8位精度的要求。
另外,这种电路形式对信号源的输入阻抗没有要求,因而可达到更高的精度。
为了进一步认识其工作过程,作一下时域分析。1位DAC输出可看作PWM脉冲。
对于RC时间常数远大于脉冲宽度标准PWM信号,有
Vin=Vref [Ton/(Ton+Toff)] (1)
如果分级地调整波形使较大的时间常数稳定下来,这将消耗很长的时间。如采用对分搜索,可大大加快计算过程,可能效果会比较理想,但要花费较大的软件资源。
这里,我们采用一种新的思路(Σ-Δ),使用相对小的时间常数,每20μs对比较器作一次采样。VC<Vin时,输出为正脉冲,反之为负脉冲。这种方法在固定周期内把PWM波形分解成数个小脉冲,代替表示占空比的单脉冲。
Vin=Vref [ΣTon/Σ(Ton+Toff)] (2)
我们把该系统看作一个动态的控制系统,系统动态平衡时,电容的充电电荷等于其放电电荷。VC在Vin上下波动,VC≈Vin,故充放电公式写作:
Vcharge = (Vout-VC) [1-exp(-t/RC)] ≈
(Vout-Vin) [1-exp (-t/RC)]
Vdischarge = (VC-V0) [1-exp(-t/RC)] ≈
(Vin-V0) [1-exp (-t/RC)]
令 n=Ton脉冲的总次数;
m=Toff脉冲的总次数;
t=采样时间。
则 n (Vout-Vin) [1-exp(-t/RC)] =
m (Vin-V0) [1-exp(-t/RC)]
解得
Vin = (nVout+mV0) / (n+m) (3)
其中Vout=Vref-Vos,Vos为口线的失调电压,Vref =VCC,V0为口线的低电平电压。所以
Vin = nVref /(n+m)-(nVos-mV0) / (n+m) (4)
前面一项为测量结果,后面为误差,方程中不存在RC值,它不是误差因子。比较器的失调电压和口线的失调电压均会影响测量精度。前者使VC不能正确地跟踪Vin而造成误差。
(2) 利用P87LPC764 内部比较器实现8位Σ-ΔADC
这里,用P87LPC764的内部比较器来实现,如图12所示。在正确测量之前,必须保证VC = Vin(实际有一微小误差)。为此,进行两次测量:第一次使VC锁定Vin,扔掉测量结果;第二次进行真正测量。8位精度需256个计数。

图12 8位Σ-ΔADC的扩充方案原理图
图13是8位Σ-ΔADC实现原理流程图。

图13 8位Σ-ΔADC实现原理流程图
;特殊功能寄存器定义
PT0AD DATA 0F6H
P0M1 DATA 84H ;P0方式寄存器1
P0M2 DATA 85H ;P0方式寄存器2
P1M1 DATA 91H ;P1方式寄存器1
P1M2 DATA 92H ;P1方式寄存器2
CMP1 DATA 0ACH ;比较器1控制寄存器
CMP2 DATA 0ADH ;比较器2控制寄存器
;变量定义
;端口定义
AD_CON BIT P1.7
;**************************************************
;Σ-Δ AD 转换程序
;占用R2,R3,R4,R5结果于A中
;**************************************************
AD_CONV:
ANL P1M1,#7FH
ORL P1M2,#80H ;AD_CON设为上拉
MOV PT0AD,#24H ;禁止CMPREF、CIN2A
ANL P0M2,#0DBH
ORL P0M1,#24H
MOV CMP2,#20H ;比较器2的CIN2A为输入端
AD_START:
MOV R4,#2 ;循环次数
MOV R2,#0 ;总计数值256次
AD_TEST:
MOV R3,#0 ;Ton计数值256次,开始转换
AD_LOOP:
MOV A,CMP2
JB ACC.1,AD_HIGH
CLR AD_CON ;输出负脉冲
DEC R3
SJMP AD_COUNT
AD_HIGH:
SETB AD_CON ;输出正脉冲
NOP
NOP
NOP ;平衡时间
AD_COUNT:
LCALL DELAY10us
DJNZ R2,AD_LOOP ;未完成256次循环,继续
DJNZ R4,AD_TEST
MOV A,R3 ;转换完成,存结果于A
RET
;----------------------------------------------
DELAY10us:
MOV R5,#10
DJNZ R5,$
RET
表2为测试报告。测试条件:VCC = 4.87V,晶振6MHz采用以上线路和源代码。
表2 测试报告
由以上结果可知,Σ-ΔADC转换具有非常高的准确度和线性度。
(3) 利用P87LPC764双比较器实现4路A/D

图14 4路8位Σ-ΔADC的原理图
图14为4路8位Σ-ΔADC原理图。
;特殊功能寄存器定义
PT0AD DATA 0F6H
P0M1 DATA 84H ;P0方式寄存器1
P0M2 DATA 85H ;P0方式寄存器2
1M1 DATA 91H ;P1方式寄存器1
P1M2 DATA 92H ;P1方式寄存器2
CMP1 DATA 0ACH ;比较器1控制寄存器
CMP2 DATA 0ADH ;比较器2控制寄存器
;变量定义
AD_BUF DATA 30H ;结果单元
;端口定义
AD_CON BIT P1.7
;----------------------------------------------
AD_4_CH:
ANL P1M1,#7FH
ORL P1M2,#80H ;AD_CON设为上拉
MOV PT0AD,#3EH ;禁止CMPREF、CIN1A、;CIN1B、CIN2A、CIN2B数字输入、输出
ANL P0M2,#0C1H
ORL P0M1,#3EH
MOV R0,#AD_BUF
MOV CMP2,#30H ;比较器2的CIN2B为输入端
LCALL AD_START2
MOV @R0,A ;存第一路结果
INC R0
MOV CMP2,#20H ;CIN2A为输入端
LCALL AD_START2
MOV @R0,A ;存第二路结果
INC R0
MOV CMP1,#30H ;CIN1B为输入端
LCALL AD_START1
MOV @R0,A ;存第三路结果
INC R0
MOV CMP1,#20H ;CIN1A为输入端
LCALL AD_START1
MOV @R0,A ;存第四路结果
AD_START1:
MOV R4,#2 ;循环次数
MOV R2,#0 ;总计数值256次
AD_TEST1:
MOV R3,#0 ;TON计数值256次,开始转换
AD_LOOP1:
MOV A,CMP1
JB ACC.1,AD_HIGH1
CLR AD_CON ;输出负脉冲
DEC R3
SJMP AD_COUNT1
AD_HIGH1:
SETB AD_CON ;输出正脉冲
NOP
NOP
NOP ;平衡时间
AD_COUNT1:
LCALL DELAY10us
DJNZ R2,AD_LOOP1 ;未完成256次循环,继续
DJNZ R4,AD_TEST1
MOV A,R3 ;转换完成,存结果于A
RET
;----------------------------------------------
AD_START2:
MOV R4,#2 ;循环次数
MOV R2,#0 ;总计数值256次
AD_TEST2:
MOV R3,#0 ;TON计数值256次,开始转换
AD_LOOP2:
MOV A,CMP2
JB ACC.1,AD_HIGH2
CLR AD_CON ;输出负脉冲
DEC R3
SJMP AD_COUNT2
AD_HIGH2:
SETB AD_CON ;输出正脉冲
NOP
NOP
NOP ;平衡时间
AD_COUNT2:
LCALL DELAY10us
DJNZ R2,AD_LOOP2 ;未完成256次循环,继续
DJNZ R4,AD_TEST2
MOV A,R3 ;转换完成,存结果于A
RET
;----------------------------------------------
DELAY10us:
MOV R5,#10
DJNZ R5,$
RET
