A/D转换器
8.1 A/D转换原理
在我们的日常生活中,会遇到很多的物理量,遇到很多的物理参数,其中,我们经常遇到的物理参数,如电流、电压、温度、压力、速度等电量或非电量都是模拟量。
模拟量的大小是连续分布的,且经常也是时间上的连续函数。要使计算机或数字仪表能识别、处理这些信号,必须首先将这些模拟信号转换成数字信号;而经计算机分析、处理后输出的数字量也往往需要将其转换为相应模拟信号才能为执行机构所接受。这样,就需要一种能在模拟信号与数字信号之间起桥梁作用的电路—模数和数模转换器。
A/D转换过程
模数转换一般要分采样、保持、量化和编码四个步骤进行。在保持过程中,采样的模拟电压经数字化编码电路转换成一组n位的二进制数输出。
A/D转换主要技术指标
1、分辨率
A/D转换器的分辨率用输出二进制数的位数表示,位数越多,误差越小,转换精度越高。例如,输入模拟电压的变化范围为0~5V,输出8位二进制数可以分辨的最小模拟电压为5V×2-8=20mV;而输出12位二进制数可以分辨的最小模拟电压为5V×2-12≈1.22mV。
2、量化误差
在A/D转换中由于整量化产生的固有误差。量化误差在±1/2LSB(最低有效位)之间。例如:一个8位的A/D转换器,它把输入电压信号分成28=256层,若它的量程为0~5V,那么,量化单位q为:
q ≈0.0195V=19.5mV
3、转换时间
转换时间是指A/D转换器完成一次转换所需的时间。转换时间是指从接到转换控制信号开始,到输出端得到稳定的数字输出信号所经过的这段时间。
4、偏移误差
输入信号为零时输出信号不为零的值,可外接电位器调至最小。
5、满刻度误差
满刻度输出时对应的输入信号与理想输入信号值之差。
6、线性度
实际转换器的转移函数与理想直线的最大偏移,不包括以上3种误差。
其他指标还有:绝对精度(Absolute Accuracy)、相对精度(Relative Accuracy)、微分非线性、单调性和无错码、总谐波失真(Total Harmonic Distortion,THD)和积分非线性。
A/D转换器的主要类型
A/D转换器的主要类型有:积分型A/D转换器、逐次比较型A/D、并行比较/串并行比较型A/D转换器、Σ-Δ(Sigma – delta)调制型A/D转换器、电容阵列逐次比较型A/D转换器和压频变换型A/D转换器。
1、积分型A/D转换器
积分型ADC的工作原理是将输入电压转换成时间(脉冲宽度信号)或频率(脉冲频率),然后由定时器/计数器获得数字值。其优点是用简单电路就能获得高分辨率,但缺点是由于转换精度依赖于积分时间,因此转换速率极低。
2、逐次比较型A/D转换器
逐次比较型ADC由一个比较器和DA转换器通过逐次比较逻辑构成,从最低位开始,顺序地对每一位将输入电压与内置DA转换器输出进行比较,经n次比较而输出数字值。其电路规模属于中等。其优点是速度较高、功耗低,在低分辩率(<12位)时价格便宜,但高精度(>12位)时价格很高。
3、并型比较型A/D转换器
并行比较型ADC采用多个比较器,仅作一次比较而实行转换,又称快速(Flash)型。电路规模极大,价格也高。
串并行比较型AD结构上介于并行型和逐次比较型之间,如由2个n/2位的并行型AD转换器配合DA转换器组成,用两次比较实行转换,所以称为半快速(Half flash)型。还有分成三步或多步实现AD转换的叫做分级(Multistep/Subrangling)型ADC。
4、Σ-Δ(Sigma – delta)调制型A/D转换器
Σ-Δ型ADC由积分器、比较器、1位DA转换器和数字滤波器等组成。原理上近似于积分型,将输入电压转换成时间(脉冲宽度)信号,用数字滤波器处理后得到数字值。电路的数字部分基本上容易单片化,因此容易做到高分辨率。主要用于音频采样和测量电路。AD7705是典型的Σ-Δ调制型 A/D转换器。
5、电容阵列逐次比较型A/D转换器
电容阵列逐次比较型ADC在内置DA转换器中采用电容矩阵方式,也可称为电荷再分配型。一般的电阻阵列DA转换器中多数电阻的值必须一致,在单芯片上生成高精度的电阻并不容易。如果用电容阵列取代电阻阵列,可以用低廉成本制成高精度单片AD转换器。最近的逐次比较型A/D转换器大多为电容阵列式的。
6、压频变换型A/D转换器
压频变换型(Voltage-Frequency Converter)是通过间接转换方式实现模数转换的。其原理是首先将输入的模拟信号转换成频率,然后用计数器将频率转换成数字量。从理论上讲这种ADC的分辨率几乎可以无限增加,只要采样的时间能够满足输出频率分辨率要求的累积脉冲个数的宽度。其优点是分辩率高、功耗低、价格低,但是需要外部计数电路共同完成AD转换。AD650是典型的压频变换型A/D转换器。
8.2 S5PV210的A/D转换器
概述
S5PV210微处理器支持10位或12位CMOS逐次逼近型模拟/数字转换器,它具有10通道输入,并可将模拟量转换至10位或12位二进制数输出。5MHz A/D转换时钟时,最大1Msps的转换速度。A/D转换具备片上采样保持功能,同时也支持待机工作模式。
特性
● 10bit/12bit输出位可选。
● 微分误差±1.0LSB。
● 积分误差±2.0LSB。
● 最大转换速率:1 Msps。
● 功耗少,电压输入3.3V。
● 模拟量输入范围:0~3.3V。
● 支持片上采样保持功能。
● 通用转换模式。
模块图
ADC与触摸屏控制是复用的,其中AIN9、AIN8、AIN7、AIN6可用于触摸屏1的XP1、XM1、YP1、YM1通道,AIN5、AIN4、AIN3、AIN2可用于触摸屏0的XP0、XM0、YP0、YM0通道。AIN1和AIN0是单独拉出的AD输入端。在A/D控制器内部的10选1多路选择器切换ADC的输入通道,并送入A/D转换器中,转换结果除可以输出数字量外,还可以通过中断产生器输出ADC中断信号。
8.3 S5PV210的A/D转换寄存器
1、A/D通道选择寄存器(ADCMUX)
A/D通道选择寄存器ADCMUX 对ADC的10个输入通道进行选择切换。由于S5PV210的A/D控制器和触摸屏复用端口,也可对触摸屏输入进行选择。
2、A/D控制寄存器(TSADCONn)
A/D控制寄存器TSADCONn对A/D转换器及触摸屏进行配置。
A/D转换预分频器值:5~255
当预分频器值为N时,分割因素为N+1。例如:当PCLK为66MHz,预分频器值为19时,ADC频率为3.3MHz。
A/D转换器最大操作频率为5MHz,所以预分频器值得设置必须使结果时钟频率不超过5MHz。
3、ADC延时寄存器(TSDLYn)
A/D延时寄存器TSDLYn配置延时引用时钟源和延时时间。
4、ADC转换数据X寄存器
A/D转换数据X寄存器TSDATXn定义了X位置触摸屏相关的显示值以及正常的A/D转换AIN0数据值。
5、ADC转换数据Y寄存器
A/D转换数据X寄存器TSDATYn定义了Y位置触摸屏相关的显示值以及正常的A/D转换AIN1数据值。
6、ADC中断清除寄存器
该寄存器用来清除相关中断。当中断服务完成后,由中断服务例程清除中断。对该寄存器写值可以清除相关中断标志,读操作会返回不确定值。
8.4 S5PV210的A/D编程
硬件电路
S5PV210微处理器的A/D转换器的通道0输入被接到电位器上,通过调节电位器,电路可以输出0V~3.3V之间不同的电压值。该电压值通过A/D转换转变成数字量,并通过UART串口输出到计算机屏幕上。
程序代码
1)adc.c源文件
adc_test()函数调用read_adc(0)获取通道0电压数据,向UART串口打印。
函数read_adc()很重要,它包括几个步骤:
(1) 设置时钟。相关代码如下:
TSADCCON0 = (1<<16)|(1 << 14) | (65 << 6);
首先使用12bit adc,然后使能分频,最后设置分频系数为66。
(2) 选择通道。代码如下:
ADCMUX = 0;
设置寄存器 ADCMUX,选择通道 0。
(3) 启动转换。代码如下:
TSADCCON0 |= (1 << 0);
while (TSADCCON0 & (1 << 0));
首先设置寄存器 TSADCCON0 的 bit[0],启动 A/D 转换,然后读 bit[0]以确定转换已经启动。
(4) 检查转换是否完成。代码如下:
while (!(TSADCCON0 &(1 << 15)) );
读寄存器 TsdACCON0 的 bit[15],当它为 1 时表示转换结束。
(5) 读数据,代码如下:
return (TsdATX0 & 0xfff);
由于使用的 12bit 的模式,所以只读寄存器 TsdATX0 的前 12bit。
程序代码
文件详细代码如下:
#include "lib\stdio.h"
#defineADCTS_PRSCVL65
#define ADCTS_BASE0xE1700000
#define TSADCCON0 ( *((volatile unsigned long *)(ADCTS_BASE+0x0)) )
#define TSCON0( *((volatile unsigned long *)(ADCTS_BASE+0x4)) )
#define TSDLY0( *((volatile unsigned long *)(ADCTS_BASE+0x8)) )
#define TSDATX0( *((volatile unsigned long *)(ADCTS_BASE+0xc)) )
#define TSDATY0(*((volatile unsigned long *)(ADCTS_BASE+0x10)) )
#define TSPENSTAT0 (*((volatile unsigned long *)(ADCTS_BASE+0x14)) )
#define CLRINTADC0(*((volatile unsigned long *)(ADCTS_BASE+0x18)) )
#define ADCMUX(*((volatile unsigned long *)(ADCTS_BASE+0x1c)) )
#defineCLRINTPEN0(*((volatile unsigned long *)(ADCTS_BASE+0x20)) )
// 延时函数
void delay(unsigned long count)
{
volatile unsigned long i = count;
while (i--) ;
}
int read_adc(int ch)// 使用查询方式读取A/D转换值
{ // 使能预分频功能,设置A/D转换器的时钟 = PCLK/(65+1)
TSADCCON0 = (1<<16)|(1 << 14) | (65 << 6);
// 清除位[2],设为普通转换模式,禁止read start
TSADCCON0 &= ~((1<<2)|(1<<1));
// 选择通道
ADCMUX = 0;
// 设置位[0]为1,启动A/D转换
TSADCCON0 |= (1 << 0);
// 当A/D转换真正开始时,位[0]会自动清0
while (TSADCCON0 & (1 << 0));
// 检测位[15],当它为1时表示转换结束
while (!(TSADCCON0 & (1 << 15)) );
// 读取数据
return (TSDATX0 & 0xfff);
}
void adc_test(void)
{printf("\r\n============adc test=============\r\n");
while(1)
{printf("adc = %d\r\n",read_adc(0));
delay(0x100000);
}
}
main.c文件详细代码如下:
#include "lib\stdio.h"
void uart_init(void);
void adc_test(void);
int main(void)
{
uart_init(); // 初始化串口
adc_test(); // 测试ADC
return 0;
}