C51的I/O口带有锁存器, ADC0809也带有锁存器, 所以不用外部锁存器. 用DB数据口连接I/O口, 在这里我用的P0口, 用P2的低三位作为串行输出. 用74HC595实现串入并出.
ADC0809的CLK要求为 10KHZ~1280KHZ 之间, 典型值为640K,此时的转换时间为100us, 如果直接和单片机的ALE相连(晶振为6MHZ时, ALE为1MHZ, 因为ALE是晶振的6分频),此时的转换时间为64us. ALE输出是1MHZ的时候还可以用一个D触发器进行2分频,得到500KHZ的; 还可以用外部的RC振荡电路实现, 其振荡频率为1/1.1RC .
其中START为启动转换, 开始为0, 为1时启动A/D, 在下降沿的时候开始转换.ALE可以和START相连.
EOC为转换结束, 在转换的时候为0, 转换完成为1
OE为输出允许, 高电平有效.
程序如下 :
/*-------------------------------------------------------------------------------
Copyrignt:vicenry 童希明
Date:2008 04 26
ADC0809
Tools: TKStudio
---------------------------------------------------------------------------------*/
#include <reg51.h>
#include <absacc.h>
#include <intrins.h>
sbit EOC=P3^2;
sbit SDATA_595=P2^2;
sbit SCLK_595=P2^0;
sbit RCK_595=P2^1;
/*sbit CLK=P2^7;*/
sbit WR_ADC0809=P3^6;
sbit RD_ADC0809=P3^7;
static unsigned char code Dig_Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9共阳段码表
unsigned char code Tab[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned int aver;
//unsigned char channel=0xfa;
/*-------------------------------------------------------------------------------
向74595输出一字节数据子程序
---------------------------------------------------------------------------------*/
void WR_595(unsigned char data num2 )
{
unsigned char data count1;
for(count1=0;count1<=7;count1++){
if((num2&0x80)==0x80) //最高位为1,则向SDATA_595发送1
SDATA_595=1; //发出数据的最高位
else
SDATA_595=0;
num2<<=1; //左移位
SCLK_595=0; //产生上生沿
_nop_();
_nop_();
SCLK_595=1;
}
}
/*-------------------------------------------------------------------------------
打开锁存,更新74595输出子程序
---------------------------------------------------------------------------------*/
void Out_595(void)
{
RCK_595=0;
_nop_();
_nop_();
RCK_595=1; /*上升沿锁存数据*/
}
void Delay(unsigned int k)
{ while(--k);
}
display(unsigned int Data1)
{
WR_595(Tab[Data1/100%10]);
WR_595(0x02);
Out_595();
WR_595(Dig_Tab[Data1/10%10]);
WR_595(0x04);
Out_595();
WR_595(Dig_Tab[Data1%10]);
WR_595(0x08);
Out_595();
}
void Ints()
{ TMOD = 0x10;
TL0 = (65536-1000)%256;
TH0 = (65536-1000)/256; // 定时器0赋初值 1ms
//TL1=(256-2)%256;
//TH1=(256-2)/256;
TR0=1;
ET0=1;
EA=1;
//TR1=1;
//ET1=1;
}
void timer0() interrupt 1
{
TL0=(65536-1000)%256;
TH0=(65536-1000)/256;
display(aver);
}
/*void timer1() interrupt 3 using 2
{
CLK=~CLK;
}*/
void main()
{
unsigned int i,tem,sum=0;
Ints();
WR_ADC0809=0;
P1=0xfa;
while(1)
{
WR_ADC0809=1; //启动转换,
Delay(100);
WR_ADC0809=0; //在START的下降沿启动转换同时锁存地址 ..
while(EOC==0); //查询EOC
RD_ADC0809=1;
Delay(100);
for(i=0;i<10;i++)
{
tem=P0;
sum+=tem;
}
aver=sum/10*195/100;
sum=0;
}
}
本来想用P2.7模拟ADC0809的CLK, 但是频率要求太高, 实现困难...