这样,A/D转换的最高位数字量就形成了。
控制电路依次对N-1、N-2、…、N-(N-1)位重复上述过程,就可使“N位寄存器”中得到和模拟电压Vx相对应的数字量。
“控制电路”在A/D转换完成后,自动使“DONE”输出端为高电平。
CPU查询DONE端的状态(或作为中断请求信号)就可以从A/D转换器读出A/D转换后的数字量。
10.1.3A/D转换器的主要技术指标
A/D转换器按照输出数字量的有效位数分为4位、8位、10位、12位、14位、16位并行输出以及BCD码输出的3位半、4位半、5位半等多种。
A/D转换器按照转换速度可大致分为超高速(转换时间≤1ns)、高速(转换时间≤1μs)、中速(转换时间≤1ms)、低速(转换时间≤1s)等几种不同转换速度的芯片。
为适应系统集成的需要,有些转换器还将多路转换开关、时钟电路、基准电压源、二-十进制译码器和转换电路集成在一个芯片内,为用户提供很多方便。
(1)转换时间和转换速率
A/D完成一次转换所需要的时间。
转换速率是转换时间的倒数。
是一个很重要的指标。
ADC型号不同,转换速率差别很大。
通常,8位逐次比较型ADC的转换时间为100μs左右。
(2)分辨率
在A/D转换器中,分辨率是衡量A/D转换器能够分辨出输入模拟量最小变化程度的技术指标。
分辨率取决于A/D转换器的位数,所以习惯上用输出的二进制位数或BCD码位数表示。
例如,A/D转换器AD1674的满量程输入电压为5V,可输出12位二进制数,即用212个数进行量化,其分辨率为1LSB,也即5V/212=1.22mV,其分辨率为12位,或A/D转换器能分辨出输入电压1.22mV的变化。
ADC0809,其分辨率为1LSB,也即5V/28=0.01953V=19.53mV.
又如,双积分型输出BCD码的A/D转换器MC14433,其满量程输入电压为2V,其输出最大的十进制数为1999,分辨率为三位半(BCD码),如果换算成二进制位数表示,其分辨率约为11位,因为1999最接近于211=2048。
量化过程引起的误差称为量化误差。
是由于有限位数字量对模拟量进行量化而引起的误差。
理论上规定为一个单位分辨率的-1/2-+1/2LSB,提高A/D位数既可以提高分辨率,又能够减少量化误差。
(3)转换精度
A/D转换器的转换精度定义为一个实际A/D转换器与一个理想A/D转换器在量化值上的差值,可用绝对误差或相对误差表示。
10.2.2AT89C51与逐次比较型8位A/D转换器――ADC0809的接口
1.ADC0809的内部结构
ADC0809的结构如图10-3所示。
采用逐次比较法完成A/D转换,单一的+5V电源供电。
片内带有锁存功能的8选1模拟开关,由C、B、A的编码来决定所选的通道。
完成一次转换需100μs左右(在fCLK=640KHz时,转换时间与CLK脚的时钟频率有关),具有输出TTL三态锁存缓冲器,可直接连到单片机数据总线上。
通过适当的外接电路,ADC0809可对0~5V的模拟信号进行转换。
图10-3ADC0809结构框图
2.ADC0809引脚及功能
ADC0809逐次比较型8路模拟输入、8位数字量输出的A/D转换器,其引脚如图10-4所示。
图10-4ADC0809引脚图
共28个引脚,双列直插式封装。
引脚功能如下:
IN0~IN7:
8路模拟信号输入端。
用于输入要转换的模拟电压。
D0~D7:
转换完后的8位数字量输出端。
C、B、A:
3位地址输入线,C、B、A = 000~111分别对应IN0~IN7通道的地址(C为高位,A为低位)。
各路模拟输入之间切换由软件改变C、B、A引脚的编码来实现。
用于选择8路模拟输入通道的一路。
图10-5通道选择(C为高位,A为低位)
ALE:
地址(C、B、A)锁存允许信号,输入,高电平有效。
在ALE的上升沿将C、B、A三条地址线上的地址锁存到内部的地址锁存器中,经译码后控制8路模拟开关。
START:
A/D转换启动信号输入线,该线上的正脉冲由CPU送来。
正脉冲宽度应大于100ns。
下降沿启动ADC工作。
EOC:
A/D转换结束信号输出线。
EOC=0,正在进行转换;
EOC=1,表示一次转换完成,数字量已经锁入“三态输出锁存器”。
OE:
数据输出允许信号输入线,高电平有效。
当转换结束后,如果从该引脚输入高电平,则打开输出三态门,输出锁存器中保存的转换后的数据量,可以从D0~D7输出。
CLK:
时钟脉冲输入端。
用于为AD0809提供逐次比较所需的640KHz时钟脉冲信号。
(转换时间为100μs),但实际上AD0809的时钟输入工作频率可以为10kHz~1280kHz,大于1.43MHz将停止工作。
一般可以采用单片机的ALE信号(经过分频后,几分频视振荡频率而定)。
VR(+)、VR(−):
为参考电压输入端。
决定输入模拟量的范围。
VR(+)通常和VCC相连,VR(−)常接地。
【典型值分别为+5V和0V。
】
VCC:
电源,接+5V。
GND:
地。
【定时时间t=计数值×机器周期
=(28-初值)×(1/晶体振荡频率)×12】
10KHz(5KHz)TH=156
100KHz(50KHz)TH=256-10=246
200KHz(100KHz)TH=
300KHz(150KHz)TH=
400KHz(200KHz)TH=
500KHz(250KHz)TH=
600KHz(300KHz)TH=256-2=254
800KHz(400KHz)TH=
1280KHz(640KHz)TH=
3.AT89S51单片机与ADC0809的接口
MCS-51与ADC的接口,必须注意三个问题:
(1)要给START线上送一个100ns宽的启动正脉冲。
(2)获取EOC线上的状态信息,因为它是A/D转换的结束标志。
(3)要给“三态输出锁存器”分配一个端口地址,也就是给OE线上送一个地址译码器输出信号。
单片机读取ADC的转换结果时,可以采用查询或中断两种方式。
采用查询方法时,在把启动信号送到ADC之后,对ADC0809的EOC引脚不断进行检测,以查询ADC变换是否已经结束。
如果为低电平(EOC=0),表示A/D转换正在进行,单片机应当继续查询;如查询到变换已经结束(EOC=1),则给OE线送一个高电平,打开输出三态门,以便从D0~D7线上读取A/D转换后的数字量。
采用中断方式时,是在启动信号送到ADC之后,EOC线作为单片机的中断请求输入线。
单片机响应中断后,应在中断服务程序中使OE线变为高电平,以读取A/D转换后的数字量。
中断控制方式效率高,所以特别适合于转换时间较长的ADC。
ADC0809和单片机的连线如下:
【注意0809的引脚对应关系为:
OUT1为最高位,OUT8为最低位)
D7
D6
D5
D4
D3
D2
D1
D0
21
20
19
18
8
15
14
17
】
#include
unsignedcharcodeLEDData[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
sbitOE=P1^0;
sbitEOC=P1^1;
sbitSTART=P1^2;
sbitCLK=P1^3;
voidDelayMS(unsignedintcount)
{
unsignedchari;
unsignedintj;
for(j=0;jfor(i=0;i<120;i++);
}
voidDisplay_Result(uchard)//应该学会这种取待显示数字的方法
{
P2=0xF7;//F7=11110111,LED上的“4”引脚为低,显示最低位
P0=LEDData[d%10];//取个位数码
DelayMS(5);
P2=0xFB;//FB=11111011,LED上的“3”引脚为低,显示左起第二位
P0=LEDData[d%100/10];//取十位数码
DelayMS(5);
P2=0xFD;//FD=11111101,LED上的“2”引脚为低,显示右起第二位
P0=LEDData[d/100];//取百位数码
DelayMS(5);
}
voidmain()
{
TMOD=0x02;//02=00000010,定时器T0,定时方式,模式2
TH0=0x14;
TL0=0x14;
IE=0x82;//10000010,EA=1,ET0=1
//EA=1;ET0=1;和上面的一样
TR0=1;//启动T0
P1=0x3F;//3f=00111111(P16=0,P15=1,P14=1,选择IN3通道)
while
(1)
{
START=0;
START=1;//START线上加一个正脉冲【正脉冲宽度应大于100ns】
START=0;//START线上加一个负脉冲,下降沿启动ADC
while(EOC==0);//等待转换结束【查询转换是否结束】
OE=1;//结束后,输出三态门打开,允许输出
Display_Result(P3);//从LED上显示结果
OE=0;//关闭输出三态门
}
}
voidTimer0_INT()interrupt1//定时器0中断服务程序
{
CLK=!
CLK;//CLK端上产生时钟信号。
频率为XX
}
【改写其中的一部分内容,程序如下】
#include
unsignedcharcodeLEDData[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
sbitOE=P1^0;
sbitEOC=P1^1;
sbitSTART=P1^2;
sbitCLK=P1^3;
sbitADDA=P1^4;
sbitADDB=P1^5;
sbitADDC=P1^6;
voidDelayMS(unsignedintcount)
{
unsignedchari;
unsignedintj;
for(j=0;jfor(i=0;i<120;i++);
}
voidDisplay_Result(uchard)//应该学会这种取待显示数字的方法
{
P2=0xF7;//F7=11110111,LED上的“4”引脚为低,显示最低位
P0=LEDData[d%10];//取个位数码
DelayMS(5);
P2=0xFB;//FB=11111011,LED上的“3”引脚为低,显示左起第二位
P0=LEDData[d%100/10];//取十位数码
DelayMS(5);
P2=0xFD;//FD=11111101,LED上的“2”引脚为低,显示右起第二位
P0=LEDData[d/100];//取百位数码
DelayMS(5);
}
voidmain()
{
TMOD=0x02;//02=00000010,定时器T0,定时方式,模式2
TH0=0x14;
TL0=0x14;
【IE=0x82;//10000010,EA=1,ET0=1】
EA=1;
ET0=;
TR0=1;//启动T0
【P1=0x3F;//3f=00111111(P16=0,P15=1,P14=1,选择IN3通道)】
ADDC=0;【011=3,选择通道3】
ADDB=1;
ADDA=1;
while
(1)
{
START=0;
START=1;//START线上加一个正脉冲【正脉冲宽度应大于100ns】
START=0;//START线上加一个负脉冲,下降沿启动ADC
while(EOC==0);//等待转换结束【查询转换是否结束】
OE=1;//结束后,输出三态门打开,允许输出
Display_Result(P3);//转换数据从P3口输入,送LED上显示
OE=0;//关闭输出三态门
}
}
voidTimer0_INT()interrupt1//定时器0中断服务程序
{
CLK=!
CLK;//CLK端上产生时钟信号。
频率为XX
}
【作业:
把上面的查询方式,改为中断方法实现,需要改变有些线的连接位置。
做完的同学,信箱发】
仅供个人用于学习、研究;不得用于商业用途。
Forpersonaluseonlyinstudyandresearch;notforcommercialuse.
NurfürdenpersönlichenfürStudien,Forschung,zukommerziellenZweckenverwendetwerden.
Pourl'étudeetlarechercheuniquementàdesfinspersonnelles;pasàdesfinscommerciales.
толькодлялюдей,которыеиспользуютсядляобучения,исследованийинедолжныиспользоватьсявкоммерческихцелях.
以下无正文