基于51单片机的4路电压测量(4路,ADC0808)原理图、流程图、物料清单、仿真图、源代码
基于51单片机的电压测量(4路,ADC0808)
4路电压测量
1、输入信号0-5V,显示精度为0.01V
2、轮流显示各个通道电压值
3、使用按键设置各个通道报警值
4、超过报警值蜂鸣器响,同时显示当前通道号和电压
#include "reg51.h"
#include "lcd1602.h"
#include"ADC0809.h"
sbit k1=P3^2;//查看模式
sbit k2=P3^3;//设置模式
sbit k3=P3^4;//切换
sbit k4=P3^5;//加
sbit k5=P3^6;//减
sbit beep=P3^7;//蜂鸣器
uint lim0=200,lim1=250,lim2=300,lim3=350;//报警阀值
uint volt0=0,volt1=0,volt2=0,volt3=0;//电压值
uchar xian=0;//查看模式指示
uchar mode=0;//模式
uchar disp1[]="Chan 1:0.00V ";//显示通道电压
uchar disp2[]="1:0.00V 2:0.00V";//显示阀值
uchar disp3[]="3:0.00V 4:0.00V";
uchar disp4[]="Warn 1:0.00V";
uchar time=0;//延时
uchar time1=0;//轮流控制
void main()
{
adc0809_init();//初始化ADC0809
init_1602();//初始化LCD1602
TMOD|=0X01;
TH0=0X3C;
TL0=0XB0;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
while(1)
{
if(!k1)//查看模式
{
mode=0;
}
if(!k2)//设置模式
{
mode=1;
}
if(!k3)//切换
{
if(xian<3)
xian++;
else
xian=0;
while(!k3);
}
if(mode)//设置模式
{
if(!k4)//加
{
switch(xian)
{
case 0:lim0+=5;break;
case 1:lim1+=5;break;
case 2:lim2+=5;break;
case 3:lim3+=5;
}
while(!k4);
}
if(!k5)//减
{
switch(xian)
{
case 0:lim0-=5;break;
case 1:lim1-=5;break;
case 2:lim2-=5;break;
case 3:lim3-=5;
}
while(!k5);
}
}
}
}
void Timer0() interrupt 1
{
if(time<10) //0.5s测量一次
time++;
else
{
time=0;
volt0=2*adc0809_read(0);//测量通道1
volt1=2*adc0809_read(1);//测量通道2
volt2=2*adc0809_read(2);//测量通道3
volt3=2*adc0809_read(3);//测量通道4
if(volt0>500)
volt0=500;
if(volt1>500)
volt1=500;
if(volt2>500)
volt2=500;
if(volt3>500)
volt3=500;
if(mode==0)//查看模式
{
switch(xian)//显示计算
{
case 0:disp1[5]=xian+0x31;//显示通道1
disp1[7]=volt0/100+0x30;
disp1[9]=volt0%100/10+0x30;
disp1[10]=volt0%10+0x30;
break;
case 1:disp1[5]=xian+0x31;//显示通道2
disp1[7]=volt1/100+0x30;
disp1[9]=volt1%100/10+0x30;
disp1[10]=volt1%10+0x30;
break;
case 2:disp1[5]=xian+0x31;//显示通道3
disp1[7]=volt2/100+0x30;
disp1[9]=volt2%100/10+0x30;
disp1[10]=volt2%10+0x30;
break;
case 3:disp1[5]=xian+0x31;//显示通道4
disp1[7]=volt3/100+0x30;
disp1[9]=volt3%100/10+0x30;
disp1[10]=volt3%10+0x30;
}
write_string(1,0,disp1);
}
else//设置模式
{
disp2[2]=lim0/100+0x30;//显示通道1阀值
disp2[4]=lim0%100/10+0x30;
disp2[5]=lim0%10+0x30;
disp2[10]=lim1/100+0x30;//显示通道2阀值
disp2[12]=lim1%100/10+0x30;
disp2[13]=lim1%10+0x30;
disp3[2]=lim2/100+0x30;//显示通道3阀值
disp3[4]=lim2%100/10+0x30;
disp3[5]=lim2%10+0x30;
disp3[10]=lim3/100+0x30;//显示通道4阀值
disp3[12]=lim3%100/10+0x30;
disp3[13]=lim3%10+0x30;
write_string(1,0,disp2);
write_string(2,0,disp3);
switch(xian)//设置光标位置
{
case 0:write_sfm(1,4); break;
case 1:write_sfm(1,12);break;
case 2:write_sfm(2,4); break;
case 3:write_sfm(2,12);
}
}
//判断报警
if(volt0>lim0)//通道1
{
disp4[5]='1';
disp4[7]=volt0/100+0x30;
disp4[9]=volt0%100/10+0x30;
disp4[10]=volt0%10+0x30;
write_string(2,0,disp4);
beep=0;//蜂鸣器响
}
else if(volt1>lim1)//通道2
{
disp4[5]='2';
disp4[7]=volt1/100+0x30;
disp4[9]=volt1%100/10+0x30;
disp4[10]=volt1%10+0x30;
write_string(2,0,disp4);
beep=0;//蜂鸣器响
}
else if(volt2>lim2)//通道3
{
disp4[5]='3';
disp4[7]=volt2/100+0x30;
disp4[9]=volt2%100/10+0x30;
disp4[10]=volt2%10+0x30;
write_string(2,0,disp4);
beep=0;//蜂鸣器响
}
else if(volt3>lim3)//通道4
{
disp4[5]='4';
disp4[7]=volt3/100+0x30;
disp4[9]=volt3%100/10+0x30;
disp4[10]=volt3%10+0x30;
write_string(2,0,disp4);
beep=0;//蜂鸣器响
}
else
{
if(mode==0)
write_string(2,0," ");
beep=1;//关蜂鸣器
}
//轮流
if(time1<10)
time1++;
else
{
time1=0;
if(mode==0)
{
if(xian<3)
xian++;
else
xian=0;
}
}
}
TH0=0X3C;
TL0=0XB0;
}