1、 一、ADC0809引脚结构功能说明图: 1~5、26~28,IN0~IN7:8路模拟量输入端。 14~15、8、17~21,D0~D7:8位数字量输出端。 23~25,ADDA、ADDB、ADDC:3位地址输入线,用于选通8路模拟输入中的一路 22,ALE:地址锁存允许信号,输入,高电平有效,对应ALE上跳沿,A、B、C地址状态送入地址锁存器中。 6,START:A/D转换启动信号,输入高电平有效,START上升沿时,复位ADC0809;START下降沿时启动芯片,开始进行A/D转换;在A/D转换期间,START应保持 低电平。本信号有时简写为ST
2、 7,EOC:A/D转换结束信号,输出,当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平)。 9,OE:数据输出允许信号,输入,高电平有效。当A/D转换结束时,此端输入一个高电平,才能打开输出三态门,输出数字量,用于控制三态输出锁存器向单片机输出转换得到的数据。OE=0,输出数据线呈高阻;OE=1,输出转换得到的数据。 10,CLK:时钟脉冲输入端。要求时钟频率不高于640KHZ,EOC=0,正在进行转换;EOC=1,转换结束。使用中该状态信号即可作为查询的状态标志,又可作为中断请求信号使用。 12、16,REF(+)、REF(-):基准电压。 11,Vcc:电源,
3、单一+5V。 13,GND:地。 二、ADC0809与51单片机的接口电路 1、说明: D0~D7接51单片机的P2口(P2.0~P2.7) ADIN1和ADIN2为通道IN0和IN1的电压模拟量输入(0~5V) 应用程序如下: #include"reg52.h" #define uchar unsigned char sbit ST=P1^0; sbit EOC=P1^1; sbit OE=P1^2; sbit CL
4、K=P1^3; sbit ADDCS=P1^4; uchar AD_DATA[2];//保存IN0和IN1经AD转换后的数据 /*******延时函数*******/ void delay(uchar i) { uchar j; while(i--) { for(j=125;j>0;j--) ; } } /******系统初始化*******/ void init() { EA = 1; //开总中断 TMOD = 0x02; //设定定时器T0工作方式 TH0=216; //利用T0中断产生CLK信号 TL0
5、216; TR0=1; //启动定时器T0 ET0=1; ST=0; OE=0; } /******T0中断服务程序********/ void t0(void) interrupt 1 using 0 { CLK=~CLK; } /******AD转换函数*******/ void AD() { ST=0; ADDCS=0; //选择通道IN0 delay(10); ST=1; //启动AD转换 delay(10); ST=0; while(0==EOC); OE=1; AD_DATA[0]=P2; OE
6、0; ST=0; ADDCS=1; //选择通道IN1 delay(10); ST=1; //启动AD转换 delay(10); ST=0; while(0==EOC); OE=1; AD_DATA[1]=P2; OE=0; } /********主函数********/ void main() { init(); while(1) { AD(); } } 注: 由于ADC0809内部不带时钟电路,因此用51单片机的定时器T0来产生时钟信号。 在通道选择时,由于B,C接地,当A(ADDCS)为低电平时选择IN
7、0,A为高电平时选择IN1 2、利用单片机AT89S51与ADC0809设计一个数字电压表,实验任务利用单片机AT89S51与ADC0809设计一个数字电压表,能够测量0-5V之间的直流电压值,四位数码显示,但要求使用的元器件数目最少。 3. 系统板上硬件连线 (1).把“单片机系统”区域中的P1.0-P1.7与“动态数码显示”区域中的ABCDEFGH端口用8芯排线连接,数码管段码控制。 (2).把“单片机系统”区域中的P2.0-P2.3与“动态数码显示”区域中的S1S2
8、S3S4端口用8芯排线连接,数码管位码控制。 (3).把“单片机系统”区域中的P3.0与“模数转换模块”区域中的ST端子用导线相连接,转换启动控制。 (4).把“单片机系统”区域中的P3.1与“模数转换模块”区域中的OE端子用导线相连接,数据输出控制。 (5).把“单片机系统”区域中的P3.2与“模数转换模块”区域中的EOC端子用导线相连接,转换结束标志。 (6).把“单片机系统”区域中的P3.3与“模数转换模块”区域中的CLK端子用导线相连接,为转换器提供脉冲。 (7).把“模数转换模块”区域中的A2A1A0端子用导线连接到“电源模块”区域中的GND端子上,始终选择IN0单通道
9、8).把“模数转换模块”区域中的IN0端子用导线连接到“三路可调电压模块”区域中的VR1端子上,调节电压变化。 (9).把“单片机系统”区域中的P0.0-P0.7用8芯排线连接到“模数转换模块”区域中的D0D1D2D3D4D5D6D7端子上,数字结果输出。 4. 程序设计内容 i.由于ADC0809在进行A/D转换时需要有CLK信号,而此时的ADC0809的CLK是接在AT89S51单片机的P3.3端口上,也就是要求从P3.3输出CLK信号供ADC0809使用。因此产生CLK信号的方法就得用软件来产生了。 ii.由于ADC0809的参考电压VREF=VCC,所以转换之后的数据要经过数
10、据处理,在数码管上显示出电压值。实际显示的电压值 (D/256*VREF)
5. C语言源程序
#include
11、r dispcount; unsigned char getdata; unsigned int temp; unsigned char i; sbit ST=P3^0; sbit OE=P3^1; sbit EOC=P3^2; sbit CLK=P3^3; void main(void) { ST=0; OE=0; ET0=1; ET1=1; EA=1; TMOD=0x12; TH0=216; TL0=216; TH1=(65536-4000)/256; TL1=(65536-4000)%256
12、 TR1=1; TR0=1; ST=1; ST=0; while(1) { if(EOC==1) { OE=1; getdata=P0; OE=0; temp=getdata*235; temp=temp/128; i=5; dispbuf[0]=10; dispbuf[1]=10; disp
13、buf[2]=10; dispbuf[3]=10; dispbuf[4]=10; dispbuf[5]=0; dispbuf[6]=0; dispbuf[7]=0; while(temp/10) { dispbuf[i]=temp%10; temp=temp/10; i++; }
14、 dispbuf[i]=temp; ST=1; ST=0; } } } void t0(void) interrupt 1 using 0 { CLK=~CLK; } void t1(void) interrupt 3 using 0 { TH1=(65536-4000)/256; TL1=(65536-4000)%256; P1=dispcode[dispbuf[dispcount]];//显示电压值 P2=dispbitcode[dispcou
15、nt];//位码控制 if(dispcount==7) { P1=P1 | 0x80; } dispcount++; if(dispcount==8) { dispcount=0; } } 三、ADC0809应用说明 1、(1). ADC0809内部带有输出锁存器,可以与AT89S51单片机直接相连。 (2). 初始化时,使ST和OE信号全为低电平。 (3). 送要转换的哪一通道的地址到A,B,C端口上。 (4). 在ST端给出一个至少有100ns宽的正脉冲信号。 (5
16、. 是否转换完毕,我们根据EOC信号来判断。 (6). 当EOC变为高电平时,这时给OE为高电平,转换的数据就输出给单片机了。 2、ST为转换启动信号。当ST上跳沿时,所有内部寄存器清零;下跳沿时,开始进行A/D转换;在转换期间,ST应保持低电平。EOC为转换结束信号。当EOC为高电平时,表明转换结束;否则,表明正在进行A/D转换。OE为输出允许信号,用于控制三条输出锁存器向单片机输出转换得到的数据。OE=1,输出转换得到的数据;OE=0,输出数据线呈高阻状态。D7-D0为数字量输出线。 CLK为时钟输入信号线。因ADC0809的内部没有时钟电路,所需时钟信号必须由外界提供,通常使用频
17、率为500KHZ, VREF(+),VREF(-)为参考电压输入。(1). 进行A/D转换时,采用查询EOC的标志信号来检测A/D转换是否完毕,若完毕则把数据通过P0端口读入,经过数据处理之后在数码管上显示。(2). 进行A/D转换之前,要启动转换的方法: ABC=110选择第三通道 ST=0,ST=1,ST=0产生启动转换的正脉冲信号 . 3、ADC0809的工作过程是:首先输入3位地址,并使ALE=1,将地址存入地址锁存器中。此地址经译码选通8路模拟输入之一到比较器。START上升沿将逐次逼近寄存器复位。下降沿启动 A/D转换,之后EOC输出信号变低,指示转换正在进行。直到A/D转换
18、完成,EOC变为高电平,指示A/D转换结束,结果数据已存入锁存器,这个信号可用作中断申请。当OE输入高电平 时,输出三态门打开,转换结果的数字量输出到数据总线上。
4、C语言源程序
#include
19、d char dispbuf[8]={10,10,10,10,10,0,0,0}; unsigned char dispcount; sbit ST=P3^0; sbit OE=P3^1; sbit EOC=P3^2; unsigned char channel=0xbc;//IN3 unsigned char getdata; void main(void) { TMOD=0x01; TH0=(65536-4000)/256; TL0=(65536-4000)%256; TR0=1; ET0=1; EA=1; P3=chann
20、el; while(1) { ST=0; ST=1; ST=0; while(EOC==0); OE=1; getdata=P0; OE=0; dispbuf[2]=getdata/100;//分离百位 getdata=getdata%100;//除去百位 dispbuf[1]=getdata/10;//分离10位 dispbuf[0]=getdata%10;//分离各位 } } void t0(void) interrupt 1 using 0 { TH0=(65536-4000)/256; TL0=(65536-4000)%256; P1=dispc
21、ode[dispbuf[dispcount]];//采样数据 P2=dispbitcode[dispcount];//打开所要显示数据的位码 dispcount++; if(dispcount==8) { dispcount=0; } } 四、ADC0809的内部结构 1、ADC0809的内部逻辑结构图如图9-7所示。 表9-1 通道选择¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿表 2. 转换数据的传送 A/D转换后得到的数据应及时传送给单片机进行处理。数据
22、传送的关键问题是如何确认A/D转换的完成,因为只有确认完成后,才能进行传送。为此可采用下述三种方式。 (1)定时传送方式 对于一种A/D转换其来说,转换时间作为一项技术指标是已知的和固定的。例如ADC0809转换时间为128μs,相当于6MHz的MCS-51单片机共64个机器周期。可据此设计一个延时子程序,A/D转换启动后即调用此子程序,延迟时间一到,转换肯定已经完成了,接着就可进行数据传送。 (2)查询方式 A/D转换芯片由表明转换完成的状态信号,例如ADC0809的EOC端。因此可以用查询方式,测试EOC的状态,即可却只转换是否完成,并接着进行数据传送。 (3)
23、中断方式 把表明转换完成的状态信号(EOC)作为中断请求信号,以中断方式进行数据传送。 不管使用上述那种方式,只要一旦确定转换完成,即可通过指令进行数据传送。首先送出口地址并以信号有效时,OE信号即有效,把转换数据送上数据总线,供单片机接受。 不管使用上述那种方式,只要一旦确认转换结束,便可通过指令进行数据传送。所用的指令为MOVX 读指令,仍以图9-17所示为例,则有 MOV DPTR , #FE00H MOVX A , @DPTR 该指令在送出有效口地址的同时,发出有效信号,使0809的输出允许信号OE有 效,从而打开三态门输出,是转换后的数据通过数
24、据总线送入A累加器中。
这里需要说明的是,ADC0809的三个地址端A、B、C即可如前所述与地址线相连,也可与数据线相连,例如与D0~D2相连。这是启动A/D转换的指令与上述类似,只不过A的内容不能为任意数,而必须和所选输入通道号IN0~IN7相一致。
我为了这个ADC0809已经痛苦了好几天了,今天终于成功了。算是一个里程碑了。
为了纪念它,把东西发上来。
电路图
PCB图
实物图
程序
#include
25、 sbit OE=P2^6; sbit START=P2^5; unsigned char _data; void init() { SM0=0; //SM01组合代表8位uart方式,波特率可变 SM1=1; REN=1; //允许串行接受 TH1=0xF3; //波特率2400,误差0.12% TL1=0XF3; TMOD=0X20; //定时器1工作于8位自动重载模式, 用于产生波特率 EA=1; //总开关中断方式 ET1=0; //定时器1 不允许中断 ES=1; //允许串口中断 TR1=1; //计时
26、器启动控制位 START=0; OE=0; } void wait(unsigned char time) //产生时钟 { unsigned char i,j; for(i=0;i






