原创 AD0809应用原理--很全面的资料

2008-5-1 14:50 6050 5 7 分类: 模拟

1. 0809的芯片说明:


ADC0809是带有8位A/D转换器、8路多路开关以及微处理机兼容的控制逻辑的CMOS组件。它是逐次逼近式A/D转换器,可以和单片机直接接口。


(1)ADC0809的内部逻辑结构


点击开大图


由上图可知,ADC0809由一个8路模拟开关、一个地址锁存与译码器、一个A/D转换器和一个三态输出锁存器组成。多路开关可选通8个模拟通道,允许8路模拟量分时输入,共用A/D转换器进行转换。三态输出锁器用于锁存A/D转换完的数字量,当OE端为高电平时,才可以从三态输出锁存器取走转换完的数据。


(2). 引脚结构


b5287624-e757-4a53-969a-9d9dfe4d3eef.jpg74692556-1675-4139-9daa-6753e331580d.jpg


IN0-IN7:8条模拟量输入通道


    ADC0809对输入模拟量要求:信号单极性,电压范围是0-5V,若信号太小,必须进行放大;输入的模拟量在转换过程中应该保持不变,如若模拟量变化太快,则需在输入前增加采样保持电路。


地址输入和控制线:4条


    ALE为地址锁存允许输入线,高电平有效。当ALE线为高电平时,地址锁存与译码器将A,B,C三条地址线的地址信号进行锁存,经译码后被选中的通道的模拟量进转换器进行转换。A,B和C为地址输入线,用于选通IN0-IN7上的一路模拟量输入。通道选择表如下表所示。




C

B

A

选择的通道

0

0

0

IN0

0

0

1

IN1

0

1

0

IN2

0

1

1

IN3

1

0

0

IN4

1

0

1

IN5

1

1

0

IN6

1

1

1

IN7

数字量输出及控制线:11条


    ST为转换启动信号。当ST上跳沿时,所有内部寄存器清零;下跳沿时,开始进行A/D转换;在转换期间,ST应保持低电平。EOC为转换结束信号。当EOC为高电平时,表明转换结束;否则,表明正在进行A/D转换。OE为输出允许信号,用于控制三条输出锁存器向单片机输出转换得到的数据。OE=1,输出转换得到的数据;OE=0,输出数据线呈高阻状态。D7-D0为数字量输出线。


CLK为时钟输入信号线。因ADC0809的内部没有时钟电路,所需时钟信号必须由外界提供,通常使用频率为500KHZ,


VREF(+),VREF(-)为参考电压输入。


2. ADC0809应用说明


(1). ADC0809内部带有输出锁存器,可以与AT89S51单片机直接相连。


(2). 初始化时,使ST和OE信号全为低电平。


(3). 送要转换的哪一通道的地址到A,B,C端口上。


(4). 在ST端给出一个至少有100ns宽的正脉冲信号。


(5). 是否转换完毕,我们根据EOC信号来判断。


(6). 当EOC变为高电平时,这时给OE为高电平,转换的数据就输出给单片机了。


3. 实验任务


如下图所示,从ADC0809的通道IN3输入0-5V之间的模拟量,通过ADC0809转换成数字量在数码管上以十进制形成显示出来。ADC0809的VREF接+5V电压。


4. 电路原理图


点击开大图


 


5.程序设计:


(1). 进行A/D转换时,采用查询EOC的标志信号来检测A/D转换是否完毕,若完毕则把数据通过P0端口读入,经过数据处理之后在数码管上显示。


(2). 进行A/D转换之前,要启动转换的方法:


ABC=110选择第三通道


ST=0,ST=1,ST=0产生启动转换的正脉冲信号 .


(3). 关于0809的计算:


ad0809是根据逐位逼近的方法产生数据的。。

参考电压为0-5V的话。以0809八位255的转换精度每一位的电压值为(5-0)/255≈0.0196V
设输入电压为X则:
X-27*0.0196>=0则AD7=1否则AD7=0。
X-26*0.0196>=0则AD6=1否则AD6=0。
       。
       。
       。
X-20*0.0196>=0则AD0=1否则AD0=0。
(27指2的7次方。26-------20同理)

若参考电压为0-1V
(1-0)/255≈0.0039V精度自然高了。。可测量范围小了。


 


1)汇编源程序:
CH EQU 30H
DPCNT EQU 31H
DPBUF EQU 33H
GDATA EQU 32H
ST BIT P3.0
OE BIT P3.1
EOC BIT P3.2



ORG 00H
LJMP START
ORG 0BH
LJMP T0X
ORG 30H
START: MOV CH,#0BCH
MOV DPCNT,#00H
MOV R1,#DPCNT
MOV R7,#5
MOV A,#10
MOV R0,#DPBUF
LOP: MOV @R0,A
INC R0
DJNZ R7,LOP
MOV @R0,#00H
INC R0
MOV @R0,#00H
INC R0
MOV @R0,#00H
MOV TMOD,#01H
MOV TH0,#(65536-4000)/256
MOV TL0,#(65536-4000) MOD 256
SETB TR0
SETB ET0
SETB EA
WT: CLR ST
SETB ST
CLR ST
WAIT: JNB EOC,WAIT
SETB OE
MOV GDATA,P0
CLR OE
MOV A,GDATA
MOV B,#100
DIV AB
MOV 33H,A
MOV A,B
MOV B,#10
DIV AB
MOV 34H,A
MOV 35H,B
SJMP WT
T0X: NOP
MOV TH0,#(65536-4000)/256
MOV TL0,#(65536-4000) MOD 256
MOV DPTR,#DPCD
MOV A,DPCNT
ADD A,#DPBUF
MOV R0,A
MOV A,@R0
MOVC A,@A+DPTR
MOV P1,A
MOV DPTR,#DPBT
MOV A,DPCNT
MOVC A,@A+DPTR
MOV P2,A
INC DPCNT
MOV A,DPCNT
CJNE A,#8,NEXT
MOV DPCNT,#00H
NEXT: RETI
DPCD: DB 3FH,06H,5BH,4FH,66H
DB 6DH,7DH,07H,7FH,6FH,00H
DPBT: DB 0FEH,0FDH,0FBH,0F7H
DB 0EFH,0DFH,0BFH,07FH
END


 


 


2)C语言源程序
#include
unsigned char code dispbitcode[]={0xfe,0xfd,0xfb,0xf7,
 0xef,0xdf,0xbf,0x7f};
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,0x00};
unsigned 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=channel;


while(1)
{
ST=0;
ST=1;
ST=0;
while(EOC==0);
OE=1;
getdata=P0;
OE=0;
dispbuf[2]=getdata/100;
getdata=getdata%10;
dispbuf[1]=getdata/10;
dispbuf[0]=getdata%10;
}
}


void t0(void) interrupt 1 using 0
{
TH0=(65536-4000)/256;
TL0=(65536-4000)%256;
P1=dispcode[dispbuf[dispcount]];
P2=dispbitcode[dispcount];
dispcount++;
if(dispcount==8)
{
dispcount=0;
}
}


 


3)FPGA实现的程序:(verilog)


module   AD0809(clk,  //脉宽(至少100ns



                      rst_n,


                      EOC,  //100usEOC变为高电平转换结束


                      START, //启动信号,上升沿有效(至少100ns


                      OE,   //高电平打开三态缓冲器输出转换数据


                      ALE,  //高电平有效,选择信道口


                      ADDA,//因为ADDB,ADDC都接地了,这里只有ADDA为变量


                      DATA,// //转换数据


                      DATA_R);


<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 


output           START,OE,ALE,ADDA;


input             EOC,clk,rst_n;


input[7:0]      DATA;


output[7:0] DATA_R;


 


reg                START,OE,ALE,ADDA;


reg[7:0]  DATA_R;


 


reg[4:0]   CS,NS;


parameter  IDLE=5''b00001,START_H=5''b00010,START_L=5''b00100,


                    CHECK_END=5''b01000,GET_DATA=5''b10000;


 


always   @(*)


 


case(CS)


 


IDLE:


      NS=START_H;


START_H:     


      NS=START_L;


START_L:


      NS=CHECK_END;


CHECK_END:


if(EOC)


      NS=GET_DATA;


else


      NS=CHECK_END;


GET_DATA:


      NS=IDLE;     


default:


      NS=IDLE;


endcase  


 


 


always   @(posedge clk)


 


if(!rst_n)


      CS<=IDLE;


else 


      CS<=NS;


      


      


always   @(posedge clk)


 


case(NS)


IDLE:


      begin


      OE<=0;


      START<=0;


      ALE<=0;ADDA<=1;


      end


START_H:     


      begin


      OE<=0;


      START<=1;     //产生启动信号


      ALE<=1;ADDA<=1;//选择信道口IN0


      end


START_L:


      begin


      OE<=0;


      START<=0;


      ALE<=1;//启动信号脉宽要足够长,在启动的时候ALE要一直有效


      end


CHECK_END:


      begin


      OE<=0;


      START<=0;


      ALE<=0;


      end


GET_DATA:


      begin


      OE<=1;         //高电平打开三态缓冲器输出转换数据


      DATA_R<=DATA;//提取转换数据


      START<=0;


      ALE<=0;


      end 


default:


      begin


      OE<=0;


      START<=0;


      ALE<=0;ADDA<=0;


      end


endcase         


endmodule


 


 


4)FPGA实现的程序:(VHDL)




LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY AD0809 IS
  PORT( D: IN STD_LOGIC_VECTOR(7 DOWNTO 0);   CLK,EOC: IN STD_LOGIC; 


  CLOCK:IN STD_LOGIC; 


  ALE,START,OE,LOCK0: OUT STD_LOGIC;
  DOUT:OUT STD_LOGIC_VECTOR(6 DOWNTO 0); 
  SEL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END AD0809;


ARCHITECTURE behav OF AD0809 IS
TYPE states IS (st0,st1,st2,st3,st4);


SIGNAL current_state,next_state:states:=st0;


SIGNAL REGL :STD_LOGIC_VECTOR(7 DOWNTO 0);


SIGNAL LOCK :STD_LOGIC;


SIGNAL CNT1:STD_LOGIC_VECTOR(0 DOWNTO 0);
SIGNAL A :INTEGER RANGE 0 TO 1;
SIGNAL LOWDATA:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL HIGHDATA:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL LOWLED7S:STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL HIGHLED7S:STD_LOGIC_VECTOR(6 DOWNTO 0);
BEGIN
LOCK0<=LOCK;  



PROCESS(REGL)
  BEGIN  
  LOWDATA<=REGL(3 DOWNTO 0);
  HIGHDATA<=REGL(7 DOWNTO 4);
  CASE LOWDATA IS
  WHEN "0000" => LOWLED7S<="0111111";
  WHEN "0001" => LOWLED7S<="0000110";
  WHEN "0010" => LOWLED7S<="1011011";
  WHEN "0011" => LOWLED7S<="1001111";
  WHEN "0100" => LOWLED7S<="1100110";
  WHEN "0101" => LOWLED7S<="1101101";
  WHEN "0110" => LOWLED7S<="1111101";
  WHEN "0111" => LOWLED7S<="0000111";
  WHEN "1000" => LOWLED7S<="1111111";
  WHEN "1001" => LOWLED7S<="1101111";
  WHEN "1010" => LOWLED7S<="1110111";
  WHEN "1011" => LOWLED7S<="1111100";
  WHEN "1100" => LOWLED7S<="0111001";
  WHEN "1101" => LOWLED7S<="1011110";
  WHEN "1110" => LOWLED7S<="1111001";
  WHEN "1111" => LOWLED7S<="1110001";
  WHEN OTHERS => Null;
  END CASE;  


CASE HIGHDATA IS
  WHEN "0000" => HIGHLED7S<="0111111";
  WHEN "0001" => HIGHLED7S<="0000110";
  WHEN "0010" => HIGHLED7S<="1011011";
  WHEN "0011" => HIGHLED7S<="1001111";
  WHEN "0100" => HIGHLED7S<="1100110";
  WHEN "0101" => HIGHLED7S<="1101101";
  WHEN "0110" => HIGHLED7S<="1111101";
  WHEN "0111" => HIGHLED7S<="0000111";
  WHEN "1000" => HIGHLED7S<="1111111";
  WHEN "1001" => HIGHLED7S<="1101111";
  WHEN "1010" => HIGHLED7S<="1110111";
  WHEN "1011" => HIGHLED7S<="1111100";
  WHEN "1100" => HIGHLED7S<="0111001";
  WHEN "1101" => HIGHLED7S<="1011110";
  WHEN "1110" => HIGHLED7S<="1111001";
  WHEN "1111" => HIGHLED7S<="1110001";
  WHEN OTHERS => Null;  
  END CASE;
END PROCESS;


PROCESS(CLOCK)
  BEGIN
  IF CLOCK'EVENT AND CLOCK='1' THEN CNT1<=CNT1+1;
  END IF;
END PROCESS;


PROCESS(CNT1)
  BEGIN
  CASE CNT1 IS
  WHEN "0" =>SEL<="111"; A<=0;
  WHEN "1" =>SEL<="110";  A<=1;
  WHEN OTHERS =>NULL;
  END CASE;
END PROCESS;


 


PROCESS(A)
  BEGIN
  CASE A IS
  WHEN 0 =>DOUT<=LOWLED7S;
  WHEN 1 =>DOUT<=HIGHLED7S;
  WHEN OTHERS =>NULL;
  END CASE;
END PROCESS;

COM:  PROCESS(current_state,EOC) 
      BEGIN
  CASE current_state IS
  WHEN st0=>ALE<='0';START<='0';LOCK<='1';OE<='0';next_state<=st1; 
  WHEN st1=>ALE<='1';START<='0';LOCK<='1';OE<='0';next_state<=st2; 
  WHEN st2=>ALE<='0';START<='1';LOCK<='0';OE<='0';
    IF (EOC='1') THEN next_state<=st3; 


    ELSE next_state<=st2;   
    END IF;
  WHEN st3=>ALE<='0';START<='0';LOCK<='0';OE<='1';next_state<=st4; 
  WHEN st4=>ALE<='0';START<='0';LOCK<='1';OE<='1';next_state<=st0; 
  WHEN OTHERS=>next_state<=st0;
  END CASE;
END PROCESS COM;


REG: PROCESS(CLK)
  BEGIN
   IF(CLK'EVENT AND CLK='1') THEN current_state<=next_state;
   END IF;
END PROCESS REG;


LATCH1: PROCESS(LOCK) 
  BEGIN
  IF LOCK='1' AND LOCK'EVENT THEN REGL<=D;
  END IF;
END PROCESS LATCH1;


END behav;

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户1438040 2009-8-14 08:59

很好 我好好研究研究 谢谢

用户1569463 2009-4-21 12:10

顶一下。 Versaloon一直很好用,呵呵

用户157223 2008-8-16 17:44

如果没有sun7474可否用别的代替,有那些可以替代?
相关推荐阅读
用户131105 2008-07-05 23:57
全新RIGOL VS5000系列虚拟示波器推动MSO混合测试实践应用
日前,北京普源精电科技有限公司(RIGOL)宣布,全新的VS5000系列虚拟数字示波器进入市场后,受到用户的普遍关注。RIGOL VS5000系列虚拟数字示波实时采样率高达400 MSa/s, 等 效...
用户131105 2008-07-05 23:55
虚拟数字示波器的设计与实现
虚拟数字示波器的设计与实现2008-3-20摘 要: 结合一个虚拟数字示波器的设计开发,介绍了虚拟仪器的基本组成,并重点介绍了基于图形化编程语言LabVIEW的虚拟仪器编程方法与实现技术。    关键...
用户131105 2008-07-05 23:53
使用TDS3000系列数字荧光示波器观察波形的频率成分 (2)
这时一篇PDF的文档,用泰克的TDS3000系列数字荧光示波器在分析时就可以用FFT图来观察波形的频率成分,希望对大家能有帮助,喜欢的可以下载看看 转自:www.kingcable.com.cn ...
用户131105 2008-06-28 13:10
labview中的串口通信协议示例与分析
变频器与个人电脑使用RS-232/RS-485 串行总线连接,如下所示:         在通讯操作中,通过个人电脑以命令方式控制仪器。    通讯数据格式:    l  起始位: 1 位    l ...
用户131105 2008-06-28 13:07
用示波器的第三维发现信号异常
用示波器的第三维发现信号异常引言  示波器的显示质量极大影响能否有效进行设计查错。如果您的示波器只有低质量的显示,您就不可能看到关键的信号异常。能示出信号亮度等级的示波器也能展示重要的波形细节,包括揭...
用户131105 2008-06-28 13:05
当今仪器仪表的特点与设计方法
1 当今仪器仪表的特点     1.1 硬件功能软件化  随着微电子技术的发展,微处理器的速度越来越快,价格越来越低,已被广泛应用于仪器仪表中,使得一些实时性要求很高,原本由硬件完成的功能,可以通过软...
EE直播间
更多
我要评论
2
5
关闭 站长推荐上一条 /3 下一条