用ADC0808做了一个数字显示的电压计,主要为了学习ADC0808/ADC0809的使用原理和方法。
接线见图(是不是很夸张,4个IO口都用了):
示波器是非必须的,主要是为了观察由中断调制出来的时钟脉冲,因为ADC0808需要外部脉冲,这里采用的是软件模拟的方式,通过计时器中断,用P3.3口输出。
关键的代码如下:
#include <reg51.h>
#include <intrins.h>
#include <stdio.h>
#include "LCM1602.h"
sbit OE=P3^0;
sbit EOC=P3^1;
sbit START=P3^2;
sbit CLK=P3^3;
sbit ALE=P1^0;
sbit ADDA=P1^1;
sbit ADDB=P1^2;
sbit ADDC=P1^3;
unsigned char buff[16];
void Init_ADC0808()
{
ALE=0;
ADDA=0;
ADDB=0;
ADDC=0;//select analog channel
ALE=1;//address lock enable
START=1;//clear registers
_nop_();_nop_();_nop_();
OE=0;//Do not allow output
CLK=0;
}
void main()
{
float p;
P2=0xff;
TMOD=0x02;
TH0=0xF6;
TL0=0xF6;
ET0=1;//Enable T0
TR0=1;//T0 Run
EA=1;
Init_ADC0808();
Init_LCM1602();
//P2=0x00;
WriteString_LCM1602(0x80,"DC VOLTMETER");
while(1)
{
START=1;//clear registers
_nop_();_nop_();_nop_();
START=0;//start conversion
_nop_();_nop_();_nop_();
OE=0;
while(EOC==0);//wait for signal of END OF CONVERSION
OE=1;//output enable
p=P2*5.0/256;
sprintf(buff,"%1.2fV",p);
WriteString_LCM1602(0xc0,buff);
START=1;
}
}
//the ADC0808 CLOCK is 10kHz~1280kHz, typical is 640kHz
//each 10us trig edge, so frequency is 1000*1000/10/2=50kHz
void INT_TIMER0() interrupt 1
{
CLK=~CLK;
}
在使用ADC0808时切记这个地方:OUT1-OUT8这几个接口,其中OUT1是MSB,OUT8是LSB,因此接线的时候OUT1接的是P2.7而OUT8接的是P2.1。
仿真使用到了LCM1602,这个类库是自己实现的,当然可以使用7段码管等显示设备,甚至可以使用串口输出。
可以看到数字显示的电压计和虚拟仪器中显示的并不是完全一致的,因为IC的分辨率只有8位。
评论