功能:
0.本项目采用STC89C52作为单片机系统的控制MCU
1.LCD1602液晶实时显示当前煤气浓度,光强,温湿度和CO2浓度
2.当煤气浓度,光强,温湿度和CO2浓度超过设定阈值时,蜂鸣器报警提醒
3.系统设计有四个功能按键可设置各指标阈值
4.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#include "reg52.h"
#include <intrins.h>
#include <stdio.h>
#include "lcd1602.h"
#include "tlc0832.h"
#include "delay.h"
#include "dht11.h"
#include "sgp30.h"
sbit BUZZER = P2^3;
sbit KEY_ADD = P3^4;
sbit KEY_SUB = P3^6;
sbit KEY_PREVIOUS = P3^3;
sbit KEY_NEXT = P3^5;
enum _MODE_DF_{NORMAL, SET_TEMP_LIMIT, SET_HM_LIMIT, SET_LIGHT_LIMIT, SET_GAS_LIMIT, SET_CO2_LIMIT};
enum _MODE_DF_ dispMode;
unsigned char dis0[16]; //数组暂存
unsigned int temprature_max = 35; //温度阈值
unsigned char humidity_min = 60; //湿度阈值
unsigned int light = 0; //光照强度
unsigned int light_max = 80; //光照强度阈值
int GAS_Conc = 0; //GAS浓度
unsigned int GAS_Conc_max = 30; //GAS浓度阈值
unsigned int CO2_Conc_max = 1000; //CO2浓度阈值
unsigned char i;
bit dispFlag = 1;
void Timer0_Init(void); //函数声明
void DispSetTempLimit(void);
void DispSetHmLimit(void);
void DispSetLightLimit(void);
void DispSetGASLimit(void);
void DispSetCO2Limit(void);
void KeyProcess(void);
void main(void)
{
unsigned long int sgp30_dat = 0;
unsigned char disCnt = 0;
unsigned char gasBuf = 0;
unsigned char timeCnt = 200;
Timer0_Init(); //定时器0初始化
LCD_Init();
DelayMs(100);
LCD_Clear();
LCD_DispStr(0, 0, " Waiting... ");
// SGP30_Init(); //初始化SGP30
//
// do
// {
// SGP30_Write(0x20,0x08);
// SGP30_Read();//读取SGP30的值
// DelayMs(10);
// timeCnt--;
// }
// while (CO2_Conc == 400 && timeCnt != 0);
LCD_DispStr(0, 0, "Temp: C Hm: %");
LCD_DispOneChar(7, 0, 0xdf); //摄氏度的点
while (1) //主循环
{
if (dispMode == NORMAL)
{
if (dispFlag == 1)
{
dispFlag = 0;
TR0 = 0;
DHT11_ReadData();
DelayMs(10);
TR0 = 1;
sprintf(dis0, "%2d", (unsigned int)U8T_data_H);
LCD_DispStr(5, 0, dis0);
sprintf(dis0, "%2d", (unsigned int)U8RH_data_H);
LCD_DispStr(13, 0, dis0);
disCnt++;
if (disCnt > 4)
{
disCnt = 1;
}
if (disCnt <= 2)
{
light = 99 - 99 * ReadADC(AIN0_GND) / 255;
gasBuf = ReadADC(AIN1_GND);
if (gasBuf <= 29)
{
gasBuf = 29;
}
GAS_Conc = (100 * (gasBuf-29)) / 227; //计算有害气体浓度百分比
sprintf(dis0, "Lt:%2d%% Gas:%2d%%", light, GAS_Conc);
LCD_DispStr(0, 1, dis0);
}
else if (disCnt <= 4)
{
// TR0 = 0;
// SGP30_Write(0x20,0x08);
// SGP30_Read();//读取SGP30的值
// TR0 = 1;
CO2_Conc = 400;
sprintf(dis0, "CO2:%5uppm ", CO2_Conc);
LCD_DispStr(0, 1, dis0);
}
}
if ((U8T_data_H > temprature_max) || (U8RH_data_H < humidity_min) || (light > light_max) || (GAS_Conc > GAS_Conc_max) || (CO2_Conc > CO2_Conc_max))
{
BUZZER = 0; //蜂鸣器报警
}
else
{
BUZZER = 1; //关闭蜂鸣器
}
}
KeyProcess();
}
}
void DispSetTempLimit(void)
{
LCD_DispStr(0, 0, " Temprature Max ");
sprintf(dis0, "%2d", temprature_max);
LCD_DispStr(6, 1, dis0);
LCD_DispOneChar(8, 1, 0xdf); //摄氏度的点
LCD_DispOneChar(9, 1, 'C'); //摄氏度C
}
void DispSetHmLimit(void)
{
LCD_DispStr(0, 0, " Humidity Min ");
sprintf(dis0, "%2d%%", (unsigned int)humidity_min);
LCD_DispStr(7, 1, dis0);
}
void DispSetLightLimit(void)
{
LCD_DispStr(0, 0, " Light Max ");
sprintf(dis0, "%2d%%", (unsigned int)light_max);
LCD_DispStr(7, 1, dis0);
}
void DispSetGASLimit(void)
{
LCD_DispStr(0, 0, " Gas Conc Max ");
sprintf(dis0, "%2d%%", (unsigned int)GAS_Conc_max);
LCD_DispStr(7, 1, dis0);
}
void DispSetCO2Limit(void)
{
LCD_DispStr(0, 0, " CO2 Conc Max ");
sprintf(dis0, "%5uppm", CO2_Conc_max);
LCD_DispStr(5, 1, dis0);
}
/************************* 按键处理 *************************/
void KeyProcess(void)
{
if (KEY_ADD == 0) //加
{
DelayMs(190);
if (KEY_ADD == 0)
{
if (dispMode == SET_TEMP_LIMIT)
{
temprature_max++;
if(temprature_max > 99)
{
temprature_max = 1;
}
}
else if (dispMode == SET_HM_LIMIT)
{
humidity_min++;
if(humidity_min > 99)
{
humidity_min = 1;
}
}
else if (dispMode == SET_LIGHT_LIMIT)
{
light_max++;
if(light_max > 99)
{
light_max = 1;
}
}
else if (dispMode == SET_GAS_LIMIT)
{
GAS_Conc_max++;
if(GAS_Conc_max > 99)
{
GAS_Conc_max = 1;
}
}
else if (dispMode == SET_CO2_LIMIT)
{
CO2_Conc_max = CO2_Conc_max + 10;
if(CO2_Conc_max > 60000)
{
CO2_Conc_max = 400;
}
}
switch (dispMode)
{
case SET_TEMP_LIMIT: DispSetTempLimit(); break;
case SET_HM_LIMIT: DispSetHmLimit(); break;
case SET_LIGHT_LIMIT: DispSetLightLimit(); break;
case SET_GAS_LIMIT: DispSetGASLimit(); break;
case SET_CO2_LIMIT: DispSetCO2Limit(); break;
}
}
// while (!KEY_ADD);
}
else if (KEY_SUB == 0) //减
{
DelayMs(190);
if (KEY_SUB == 0)
{
if (dispMode == SET_TEMP_LIMIT)
{
temprature_max--;
if(temprature_max < 1)
{
temprature_max = 99;
}
}
else if (dispMode == SET_HM_LIMIT)
{
humidity_min--;
if(humidity_min < 1)
{
humidity_min = 99;
}
}
else if (dispMode == SET_LIGHT_LIMIT)
{
light_max--;
if(light_max < 1)
{
light_max = 99;
}
}
else if (dispMode == SET_GAS_LIMIT)
{
GAS_Conc_max--;
if(GAS_Conc_max < 1)
{
GAS_Conc_max = 99;
}
}
else if (dispMode == SET_CO2_LIMIT)
{
CO2_Conc_max = CO2_Conc_max - 10;
if(CO2_Conc_max < 400)
{
CO2_Conc_max = 60000;
}
}
switch (dispMode)
{
case SET_TEMP_LIMIT: DispSetTempLimit(); break;
case SET_HM_LIMIT: DispSetHmLimit(); break;
case SET_LIGHT_LIMIT: DispSetLightLimit(); break;
case SET_GAS_LIMIT: DispSetGASLimit(); break;
case SET_CO2_LIMIT: DispSetCO2Limit(); break;
}
}
// while (!KEY_SUB);
}
else if (KEY_PREVIOUS == 0) //上一页
{
DelayMs(20);
if (KEY_PREVIOUS == 0)
{
LCD_Clear();
if (dispMode == NORMAL)
{
dispMode = SET_CO2_LIMIT;
}
else
{
dispMode--;
}
switch (dispMode)
{
case NORMAL: LCD_DispStr(0, 0, "Temp: C Hm: %"); LCD_DispOneChar(7, 0, 0xdf); break;
case SET_TEMP_LIMIT: DispSetTempLimit(); break;
case SET_HM_LIMIT: DispSetHmLimit(); break;
case SET_LIGHT_LIMIT: DispSetLightLimit(); break;
case SET_GAS_LIMIT: DispSetGASLimit(); break;
case SET_CO2_LIMIT: DispSetCO2Limit(); break;
}
}
while (!KEY_PREVIOUS);
}
else if (KEY_NEXT == 0) //下一页
{
DelayMs(20);
if (KEY_NEXT == 0)
{
LCD_Clear();
if (dispMode == SET_CO2_LIMIT)
{
dispMode = NORMAL;
}
else
{
dispMode++;
}
switch (dispMode)
{
case NORMAL: LCD_DispStr(0, 0, "Temp: C Hm: %"); LCD_DispOneChar(7, 0, 0xdf); break;
case SET_TEMP_LIMIT: DispSetTempLimit(); break;
case SET_HM_LIMIT: DispSetHmLimit(); break;
case SET_LIGHT_LIMIT: DispSetLightLimit(); break;
case SET_GAS_LIMIT: DispSetGASLimit(); break;
case SET_CO2_LIMIT: DispSetCO2Limit(); break;
}
}
while (!KEY_NEXT);
}
}
void Timer0_Init(void)
{
TMOD &= 0xF0;
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0 = (65536 - 18432) / 256; //重新赋值 20ms
TL0 = (65536 - 18432) % 256;
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 1; //定时器开关打开
}
void Timer0_Interrupt(void) interrupt 1
{
static unsigned char time_20ms = 0; //定时变量
TH0 = (65536 - 18432) / 256; //重新赋值 20ms
TL0 = (65536 - 18432) % 256;
time_20ms++;
if (time_20ms > 50)
{
dispFlag = 1;
time_20ms = 0;
}
}