用单片机实现AD0809转化
实验七基于AD0808的八路电压采集系统
一、实验目的
掌握AD0808的应用,及LCD的初始化设置指令。
二、实验要求
通过AD0808采集八路电压,用LCD液晶屏显示,每屏显示四路电压值。时间间隔一秒。
三、实验原理
通过在Keil C51中对单片机AT89C52进行编程,硬件中单片机与ADC0808及LCD显示屏连接。P0与ADC0808相连,P2与LCD连接。A、B、C口控制选通通道号,模拟信号通过IN0——IN7输入到ADC0808中转换为数字信号,P0获得此值后,经过处理得到每位的数据后,通过P2口写数据到LCD屏上。
四、实验电路如下图所示:
五、程序代码:
/*通过AD0808采集八路电压,用LCD液晶屏移屏显示,每屏显示四路电压值。时间间隔一秒。*/
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit adoe=P3^0;
sbit eoc=P3^1;
sbit adstart=P3^2;
sbit a0=P3^3;
sbit a1=P3^4;
sbit a2=P3^5;
sbit lcdrs=P3^6;
sbit lcden=P3^7;
long int temp,b1,b2,b3,b4,b5;
uchar tt;
uchar code table[]="0123456789.V";
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=100;y>0;y--);
}
void write_command(uchar com)//写命令
{
lcdrs=0;
P2=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date)//写数据
{
lcdrs=1;
P2=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()//初始化
{
lcden=0;
write_command(0x38);//不可变,显示模式设置:16*2显示,5*7点阵,8位数据接口write_command(0x0c);//屏幕开启和光标闪烁
write_command(0x06);//显示开关及光标设置
write_command(0x01);//清屏
}
void start() //开始AD转换
{
adoe=0;
adstart=0;
adstart=1;
_nop_();
adstart=0;
}
void xianshi() //AD转化结果显示
{
write_data(table[b1]);
delay(1);
write_data(table[10]);
delay(1);
write_data(table[b2]);
delay(1);
write_data(table[b3]);
delay(1);
write_data(table[11]);
delay(1);
}
void first_mark() //0-4路通道的标号{
write_command(0x01);
write_command(0x80);
write_data('A');
delay(1);
write_command(0x80+0x01);
write_data('=');
delay(1);
write_command(0x80+0x09);
write_data('B');
delay(1);
write_command(0x80+0x0a);
write_data('=');
delay(1);
write_command(0x80+0x40);
write_data('C');
delay(1);
write_command(0x80+0x41);
write_data('=');
delay(1);
delay(1);write_command(0x80+0x49);
write_data('D');
delay(1);
write_command(0x80+0x4a);
write_data('=');
delay(1);
}
void second_mark() //5-7路通道的标号{
write_command(0x01);
write_command(0x80);
write_data('E');
delay(1);
write_command(0x80+0x01);
write_data('=');
delay(1);
write_command(0x80+0x09);
write_data('F');
delay(1);
write_command(0x80+0x0a);
write_data('=');
delay(1);
write_command(0x80+0x40);
write_data('G');
delay(1);
write_command(0x80+0x41);
write_data('=');
delay(1);
delay(1);write_command(0x80+0x49);
write_data('H');
delay(1);
write_command(0x80+0x4a);
write_data('=');
delay(1);
}
void main()
{
a2=0;
init(); //LCD初始化
TMOD=0x01;
EA=1;//开总中断
TH0=(65535-1000)/256;
TL0=(65535-1000)%256;
ET0=1;//开定时器0中断
TR0=1;//定时器0置位
first_mark();
while(1)
{
a0=0; //0路或4路通道的AD转化
a1=0;
start();
while(!eoc);
adoe=1;
temp=P0;
delay(3);
adoe=0;
b1=(temp*500/255)/100; //最高位b2=(temp*500/255)%100/10; //第二位
b3=(temp*500/255)%10; //第三位
write_command(0x80+0x02);
xianshi();
a0=1; //1路或5路通道的AD转化
a1=0;
start();
while(!eoc);
adoe=1;
temp=P0;
delay(3);
adoe=0;
b1=(temp*500/255)/100; //最高位b2=(temp*500/255)%100/10; //第二位
b3=(temp*500/255)%10; //第三位
write_command(0x80+0x0b);
xianshi();
a0=0; //2路或6路通道的AD转化
a1=1;
start();
while(!eoc);
adoe=1;
temp=P0;
delay(3);
adoe=0;
b1=(temp*500/255)/100; //最高位b2=(temp*500/255)%100/10; //第二位
b3=(temp*500/255)%10; //第三位
write_command(0x80+0x42);
xianshi();
a0=1; //3路或7路通道的AD转化
a1=1;
start();
while(!eoc);
adoe=1;
temp=P0;
delay(3);
adoe=0;
b1=(temp*500/255)/100; //最高位
b2=(temp*500/255)%100/10; //第二位
b3=(temp*500/255)%10; //第三位
write_command(0x80+0x4b);
xianshi();
}
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
tt++;
if((a2==0&&tt==20)==1) //LCD第二屏显示
{
tt=0;
a2=1;
second_mark();
}
if((a2==1&&tt==20)==1) //LCD第一屏显示
{
tt=0;
a2=0;
first_mark();
}
}