基于51单片机环境监测系统

一、系统方案
本设计采用51单片机作为主控制器,DHT11采集温湿度,光敏电阻采集光照强度,烟雾MQ2传感器采集烟雾值,送到液晶1602显示,按键设置报警值,测量值超过设定值,系统声光报警。
基于51单片机环境监测系统_第1张图片
二、硬件设计
原理图如下:
基于51单片机环境监测系统_第2张图片
三、单片机软件设计
1、首先是系统初始化
//
// 1602液晶初始化函数
/
/
void LcdInit()
{
LcdWriteCmd(0x38); // 162显示,57点阵,8位数据口
LcdWriteCmd(0x0C); // 开显示,不显示光标
LcdWriteCmd(0x06); // 地址加1,当写入数据后光标右移
LcdWriteCmd(0x01); // 清屏
}

2、液晶显示程序
//
// 1602液晶写命令函数,cmd就是要写入的命令
/
/
void LcdWriteCmd(uchar cmd)
{
LcdRs_P = 0;
LcdRw_P = 0;
LcdEn_P = 0;
P0=cmd;
DelayMs(2);
LcdEn_P = 1;
DelayMs(2);
LcdEn_P = 0;
}

//
// 1602液晶写数据函数,dat就是要写入的数据
/
/
void LcdWriteData(uchar dat)
{
LcdRs_P = 1;
LcdRw_P = 0;
LcdEn_P = 0;
P0=dat;
DelayMs(2);
LcdEn_P = 1;
DelayMs(2);
LcdEn_P = 0;
}
3、按键程序

//
// 按键扫描
/
/
void KeyScanf()
{
if(KeySet_P0) // 判断是否有按键按下
{
DelayMs(10); // 消除按键按下的抖动
if(KeySet_P
0)
{
while(!KeySet_P); // 等待按键释放
menu_1++;
if(menu_15)
menu_1=0;
}
}
while(menu_1!=0)
{
if(KeySet_P
0) // 判断是否有按键按下
{
DelayMs(10); // 消除按键按下的抖动
if(KeySet_P0)
{
while(!KeySet_P); // 等待按键释放
menu_1++;
if(menu_1
9)
menu_1=0;
}
}
if(menu_11)
{
LcdGotoXY(0,0); // 液晶恢复测量时的内容显示
LcdPrintStr("Temp_Min set ");
LcdGotoXY(1,0); // 定位到第0行第7列
LcdPrintTHD(Set_Value[0][0]); // 显示当前下限
LcdGotoXY(1,3);
LcdPrintStr("C ");
if(KeyDown_P
0) // 报警值减的处理
{
DelayMs(10); // 消除按键按下的抖动
if(KeyDown_P0)
{
while(!KeyDown_P); // 等待按键释放
Set_Value[0][0]–;
}
}
if(KeyUp_P
0) // 报警值加处理
{
DelayMs(10); // 消除按键按下的抖动
if(KeyUp_P0)
{
while(!KeyUp_P); // 等待按键释放
Set_Value[0][0]++;
}
}
}
if(menu_1
2)
{
LcdGotoXY(0,0); // 液晶恢复测量时的内容显示
LcdPrintStr("Temp_MAX set ");
LcdGotoXY(1,0); // 定位到第0行第7列
LcdPrintTHD(Set_Value[0][1]); // 显示当前下限
LcdGotoXY(1,3);
LcdPrintStr("C ");
if(KeyDown_P0) // 报警值减的处理
{
DelayMs(10); // 消除按键按下的抖动
if(KeyDown_P
0)
{
while(!KeyDown_P);// 等待按键释放
Set_Value[0][1]–;
}
}
if(KeyUp_P0) // 报警值加处理
{
DelayMs(10);
if(KeyUp_P
0)
{
while(!KeyUp_P);
Set_Value[0][1]++;
}
}
}
if(menu_13)
{
LcdGotoXY(0,0); // 液晶恢复测量时的内容显示
LcdPrintStr("Humi_Min set “);
LcdGotoXY(1,0); // 定位到第0行第7列
LcdPrintTHD(Set_Value[1][0]); // 显示当前下限
LcdGotoXY(1,3);
LcdPrintStr(”%RH ");
if(KeyDown_P
0) // 报警值减的处理
{
DelayMs(10); // 消除按键按下的抖动
if(KeyDown_P0)
{
while(!KeyDown_P);// 等待按键释放
Set_Value[1][0]–;
}
}
if(KeyUp_P
0) // 报警值加处理
{
DelayMs(10);
if(KeyUp_P0)
{
while(!KeyUp_P);
Set_Value[1][0]++;
}
}
}
if(menu_1
4)
{
LcdGotoXY(0,0); // 液晶恢复测量时的内容显示
LcdPrintStr("Humi_MAX set “);
LcdGotoXY(1,0); // 定位到第0行第7列
LcdPrintTHD(Set_Value[1][1]); // 显示当前上限
LcdGotoXY(1,3);
LcdPrintStr(”%RH ");
if(KeyDown_P0) // 报警值减的处理
{
DelayMs(10); // 消除按键按下的抖动
if(KeyDown_P
0)
{
while(!KeyDown_P);// 等待按键释放
Set_Value[1][1]–;
}
}
if(KeyUp_P0) // 报警值加处理
{
DelayMs(10);
if(KeyUp_P
0)
{
while(!KeyUp_P);
Set_Value[1][1]++;
}
}
}
if(menu_15)
{
LcdGotoXY(0,0); // 液晶恢复测量时的内容显示
LcdPrintStr("Light_Min set “);
LcdGotoXY(1,0); // 定位到第0行第7列
LcdPrintTHD(Set_Value[2][0]); // 显示当前下限
LcdGotoXY(1,3);
LcdPrintStr(” ");
if(KeyDown_P
0) // 报警值减的处理
{
DelayMs(10); // 消除按键按下的抖动
if(KeyDown_P0)
{
while(!KeyDown_P);// 等待按键释放
Set_Value[2][0]–;
}
}
if(KeyUp_P
0) // 报警值加处理
{
DelayMs(10);
if(KeyUp_P0)
{
while(!KeyUp_P);
Set_Value[2][0]++;
}
}
}
if(menu_1
6)
{
LcdGotoXY(0,0); // 液晶恢复测量时的内容显示
LcdPrintStr("Light_MAX set “);
LcdGotoXY(1,0); // 定位到第0行第7列
LcdPrintTHD(Set_Value[2][1]); // 显示当前上限
LcdGotoXY(1,3);
LcdPrintStr(” “);
if(KeyDown_P0) // 报警值减的处理
{
DelayMs(10); // 消除按键按下的抖动
if(KeyDown_P
0)
{
while(!KeyDown_P);// 等待按键释放
Set_Value[2][1]–;
}
}
if(KeyUp_P0) // 报警值加处理
{
DelayMs(10);
if(KeyUp_P
0)
{
while(!KeyUp_P);
Set_Value[2][1]++;
}
}
}
if(menu_17)
{
LcdGotoXY(0,0); // 液晶恢复测量时的内容显示
LcdPrintStr(" YW_Min set ");
LcdGotoXY(1,0); // 定位到第0行第7列
LcdPrintTHD(Set_Value[3][0]); // 显示当前下限
LcdGotoXY(1,3);
LcdPrintStr("ppm ");
if(KeyDown_P
0) // 报警值减的处理
{
DelayMs(10); // 消除按键按下的抖动
if(KeyDown_P0)
{
while(!KeyDown_P);// 等待按键释放
Set_Value[3][0]–;
}
}
if(KeyUp_P
0) // 报警值加处理
{
DelayMs(10);
if(KeyUp_P0)
{
while(!KeyUp_P);
Set_Value[3][0]++;
}
}
}
if(menu_1
8)
{
LcdGotoXY(0,0); // 液晶恢复测量时的内容显示
LcdPrintStr(” YW_MAX set ");
LcdGotoXY(1,0); // 定位到第0行第7列
LcdPrintTHD(Set_Value[3][1]); // 显示当前上限
LcdGotoXY(1,3);
LcdPrintStr("ppm ");
if(KeyDown_P0) // 报警值减的处理
{
DelayMs(10); // 消除按键按下的抖动
if(KeyDown_P
0)
{
while(!KeyDown_P);// 等待按键释放
Set_Value[3][1]–;
}
}
if(KeyUp_P0) // 报警值加处理
{
DelayMs(10);
if(KeyUp_P
0)
{
while(!KeyUp_P);
Set_Value[3][1]++;
}
}
}
}
}
4、核心算法程序
void AlarmJudge(void)
{
if((temp_valueSet_Value[0][1])||
(humi_valueSet_Value[1][1])||
(ADC_Value[0]Set_Value[2][1])||
(ADC_Value[1]Set_Value[3][1]))
{
Led_P=0;
Buzzer_P=0;
DelayMs(50);
Led_P=1;
Buzzer_P=1;
DelayMs(50);
}
if(temp_value {
Led_0=0;
} else Led_0=1;
if(temp_value>Set_Value[0][1])//温度高于设定最大阈值
{
Led_1=0;
} else Led_1=1;
if(humi_value {
Led_2=0;
} else Led_2=1;
if(humi_value>Set_Value[1][1])//湿度高于设定最大阈值
{
Led_3=0;
} else Led_3=1;
if(ADC_Value[0] {
Led_4=0;
} else Led_4=1;
if(ADC_Value[0]>Set_Value[2][1])//光照高于设定最大阈值
{
Led_5=0;
} else Led_5=1;
if(ADC_Value[1] {
Led_6=0;
} else Led_6=1;
if(ADC_Value[1]>Set_Value[3][1])//烟雾高于设定最大阈值
{
Led_7=0;
} else Led_7=1;
}
四、proteus仿真设计
Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。
基于51单片机环境监测系统_第3张图片

你可能感兴趣的:(51单片机,嵌入式硬件,单片机)