一、系统方案
本设计采用AT89C51单片机作为主控制器,ADC0809采集8路电压值、按键设置报警阀值,液晶1602显示,蜂鸣器报警。
二、硬件设计
原理图如下:
三、单片机软件设计
1、首先是系统初始化:
TMOD=0x01; //设置为定时器模式1
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
IE=0x82;//开全局中断和定时中断
LCD1602_init();//LCD1602初始化
init_eeprom();
beep=1;
2、液晶显示程序
void display7()
{
AA=0;
BB=1;
CC=1;
ST=0;
ST=1; //获得上升沿复位
ST=0; //获得下降沿启动转换,同时ALE开锁存
do
{
CLK=~CLK; //时钟信号
}
while(EOC0);//等待转换结束,eoc=1结束
OE=1;//三态锁存缓冲器打开
date=P1;//数字电压信号输出
OE=0;//三态锁存缓冲器关闭
temp=date*196;
tab[0]=temp/10000;//个位
tab[1]=temp/1000%10;//第一位小数
tab[2]=temp/100%10;//第二位小数
tab[3]=temp/10%10;//第三位小数
vh7=tab[0];
write_com(0x0c);//设置光标不显示,不闪烁
delay(20);
write_com(0xc0+3);//第二行起始显示地址0x80
write_date(‘U’); //显示字符串’volatage is’
write_date(‘O’);
write_date(‘7’);
write_date(‘=’);
//显示电压值的大小
write_date(table[tab[0]]); //个位
write_date(‘.’);//小数点
write_date(table[tab[1]]);//第一位小数
write_date(table[tab[2]]);//第二位小数
write_date(table[tab[3]]);//第三位小数
write_date(‘V’);//电压单位
write_date(’ ‘);
write_date(’ ‘);
write_date(’ ');
}
void display8()
{
AA=1;
BB=1;
CC=1;
ST=0;
ST=1; //获得上升沿复位
ST=0; //获得下降沿启动转换,同时ALE开锁存
do
{
CLK=~CLK; //时钟信号
}
while(EOC0);//等待转换结束,eoc=1结束
OE=1;//三态锁存缓冲器打开
date=P1;//数字电压信号输出
OE=0;//三态锁存缓冲器关闭
temp=date*196;
tab[0]=temp/10000;//个位
tab[1]=temp/1000%10;//第一位小数
tab[2]=temp/100%10;//第二位小数
tab[3]=temp/10%10;//第三位小数
vh8=tab[0];
write_com(0x0c);//设置光标不显示,不闪烁
delay(20);
write_com(0xc0+3);//第二行起始显示地址0x80
write_date(‘U’); //显示字符串’volatage is’
write_date(‘O’);
write_date(‘8’);
write_date(‘=’);
//显示电压值的大小
write_date(table[tab[0]]); //个位
write_date(‘.’);//小数点
write_date(table[tab[1]]);//第一位小数
write_date(table[tab[2]]);//第二位小数
write_date(table[tab[3]]);//第三位小数
write_date(‘V’);//电压单位
write_date(’ ‘);
write_date(’ ‘);
write_date(’ ');
}
3、按键检测程序
//voltage_H
void key_set()
{
if(KEY_ADD0)
{
delay(10);
if(KEY_ADD0)
{
voltage_H++;
if(voltage_H>50)
voltage_H=50;
write_eeprom();
while(!KEY_ADD);
}
}
if(KEY_DEC0)
{
delay(10);
if(KEY_DEC0)
{
if(voltage_H>0)
voltage_H–;
write_eeprom();
while(!KEY_DEC);
}
}
}
4、核心算法程序
while(1)//大循环
{
if(KEY_MODE0)
{
delay(10);
if(KEY_MODE0)
{
mode_select=~mode_select;
LCD1602_init();//LCD1602初始化
// flag_clr=mode_select;
while(!KEY_MODE);
}
}
if(mode_select0)
{
/******************************************************************************************/
key();
if(aa0)
{
if(num0)
display1();//调用液晶显示电压值子函数
if(num1)
display2();
if(num2)
display3();
if(num3)
display4();
if(num4)
display5();
if(num5)
display6();
if(num6)
display7();
if(num7)
display8();
}
if(aa1)
{
if(num0)
display1();//调用液晶显示电压值子函数
if(num1)
display2();
if(num2)
display3();
if(num3)
display4();
if(num4)
display5();
if(num5)
display6();
if(num6)
display7();
if(num==7)
display8();
}
/报警********************************/
// vh=temp;
vh=tab[0]*1000+tab[1]100+tab[2]10+tab[3]; //计算当前电压放大1000倍
if(vh>(voltage_H100)) //如果大于上限 则报警
// if(vh>(voltage_H10000))
// if((vh1>voltage_H)||(vh2>voltage_H)||(vh3>voltage_H)||(vh4>voltage_H)||(vh5>voltage_H)||(vh6>voltage_H)||(vh7>voltage_H)||(vh8>voltage_H))
{
beep_alarm();
}
else
beep=1;
/********************************************************************************************************/
}
else
{
write_com(0x80);//第1行起始显示地址0x80
write_date('v'); //显示字符串'volatage is'
write_date('o');
write_date('l');
write_date('t');
write_date('_');
write_date('H');
write_date(':');
//显示电压值的大小
write_com(0x87);
write_date(voltage_H/10+0x30); //个位
write_date('.'); //个位
write_date(voltage_H%10+0x30); //小数点一位
write_date('V');//电压单位
key_set();
}
}
四、proteus仿真设计
Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。