#define uchar unsigned char
#define uint unsigned int
sbit RS=P1^7; //定义LCD1602端口线
sbit RW=P1^6;
sbit EN=P1^5;
sbit ST=P3^7; //定义0808控制线
sbit OE=P3^6;
sbit EOC=P1^3;
sbit CLK=P1^4;
sbit buzzer = P1^1; //喇叭
sbit alarm = P1^2; //led
uchar data chnumber; //存放当前通道号
uchar disbuffer[4]={0,'.',0,0}; //定义显示缓冲区
uchar data ad_data[8]={0,0,0,0,0,0,0,0}; //0808的8个通道转换数据缓冲区
uint temp;
//检查忙函数
void fbusy()
{
P0 = 0xff;
RS = 0;
RW = 1;
EN = 1;
EN = 0;
while((P0 & 0x80))
{
EN = 0;
EN = 1;
}
}
//写命令函数
void wc51r(uchar {
fbusy();
EN = 0;
RS = 0;
RW = 0;
EN = 1;
P0 = j;
EN = 0;
}
j)
//写数据函数
void wc51ddr(uchar j)
{
fbusy(); //读状态;
EN = 0;
RS = 1;
RW = 0;
EN = 1;
P0 = j;
EN = 0;
}
void init()
{
wc51r(0x01); //清屏
wc51r(0x38); //使用8位数据,显示两行,使用5*7的字型
wc51r(0x0c); //显示器开,光标开,字符不闪烁
wc51r(0x06); //字符不动,光标自动右移一格
}
/********0808转换子函数********/
void test()
{
uchar m;
for (m=0;m<8;m++)
{
P3=m; //送通道
ST=0;_nop_();_nop_();ST=1;_nop_();_nop_();ST=0;//锁存通道启动转换
_nop_();_nop_();_nop_();_nop_();
while (EOC==0); //等待转换结束
OE=1;ad_data[m]=P2;OE=0; //读取当前通道转换数据
}
}
//************延时函数************
void delay(uint i) //延时函数
{
uint y,j;
for (j=0;jfor (y=0;y<0xff;y++){;}}
}
//定时器/计数器T0产生0808的时钟
void T0X(void)interrupt 1 using 0
{
CLK=~CLK;
}
void main(void)
{
uchar i;
uint temp1;
SP=0X50;TMOD=0x02;TH0=246;TL0=246;
ET0=1;EA=1;TR0=1;
delay(10);
init(); //lcd显示器初始化
wc51r(0x80); //写入显示缓冲区起始为第1行第1列
wc51ddr('V'); //第1行第1列显示字母V
wc51ddr('A'); //第1行第2列显示字母A
wc51ddr('L'); //第1行第3列显示字母 L
wc51ddr('U'); wc51ddr('E'); wc51ddr('0'); wc51ddr(':'); wc51r(0xC0); wc51ddr('V'); wc51ddr('A'); wc51ddr('L'); wc51ddr('U'); wc51ddr('E'); //第1行第4列显示字母 U
//第1行第5列显示字母 E
//第1行第6列显示数字 0
//第1行第7列显示字母 :
//写入显示缓冲区起始为第2行第1列 //第2行第1列显示字母V
//第2行第2列显示字母A
//第2行第3列显示字母 L
//第2行第4列显示字母 U
//第2行第5列显示字母 E
wc51ddr('1'); //第2行第6列显示数字 1
wc51ddr(':'); //第2行第7列显示字母 :
alarm = 0; //关闭led和报警
buzzer = 0;
while(1)
{
test(); //调用ADC0808转换程序8个通道转换一次
alarm = 0;
//chnumber = ~chnumber;
temp=ad_data[chnumber]; //取出当前通道值,转换成电压值所对应的字符
temp=(temp*100)/51;
temp1 = temp;
disbuffer[0]=temp/100+0x30; temp=temp%100;
disbuffer[2]=temp/10+0x30;
disbuffer[3]=temp%10+0x30;
if(chnumber == 0) //采集的第零个电压
{
wc51r(0x);
if(temp1 >= 125) //电压达到了1.25
{
alarm = 1; //开启led和报警
buzzer = 1;
}else{
alarm = 0; //关闭led和报警
buzzer = 0;
}
chnumber = 1; //下次采集第一个电压
}else{ //采集的第一个电压
wc51r(0xc9); //显示当前通道
if(temp1 >= 250 || alarm == 1) //电压达到了2.5v
{
alarm = 1; //开启led和报警
buzzer = 1;
}else{
alarm = 0; //关闭led和报警
buzzer = 0;
}
chnumber = 0; //下次采集第零个电压
}
for (i=0;i<4;i++) //显示三个电压数字
{
wc51ddr(disbuffer[i]);
}
wc51ddr('v'); //最后显示出电压符号
}
}
Proteus仿真图: