功能介绍:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时显示当前温湿度/烟雾浓度,同时WIFI串口上报
2.当温湿度或烟雾浓度超过设定阈值时,向WIFI串口发送报警信息
3.通过WIFI串口发送命令可更改设定阈值
*T=xx# 设定温度阈值,xx为数字
*R=xx# 设定湿度阈值,xx为数字
*S=xx# 设定烟雾浓度阈值,xx为数字
4.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <stdio.h>
#include "delay.h"
#include "tlc0832.h"
#include "oled_iic.h"
#include "dht11.h"
/************************* 变量定义 *************************/
int smog = 0;
unsigned char tempMax = 30; //温度上限
unsigned char RHMax = 70; //湿度上限
unsigned char smogMax = 20; //烟雾浓度上限
char dis0[16]; //定义显示区域临时存储数组
bit refreshFlag = 1; //刷新标志
unsigned char setIndex = 0;
/************************* 函数声明 *************************/
void Timer0_Init(void); //函数声明
void KeyProcess(void); //按键处理
void UART_Init(void); //串口初始化
void UART_SendByte(unsigned char dat); //串口发送单字节数据
void UART_SendStr(unsigned char *s, unsigned char length); //发送定长度字符串
void SendData(void); //WIFI串口发送数据
void main(void)
{
/************************* 初始化 *************************/
Timer0_Init();
OLED_Init();
OLED_Clear();
UART_Init();
/************************* 读取数据 *************************/
DHT11_0_ReadData();
smog = (100 * (ReadADC(AIN0_GND) - 29)) / 227; //计算烟雾浓度百分比
if (smog < 0)
{
smog = 0;
}
/************************* 显示 *************************/
sprintf(dis0, "T:%3d", (int)U8T_data_H);
OLED_ShowString(0, 0, dis0, FONT_1608); //显示温度
OLED_ShowWord(5 * 8, 0, 0); //显示摄氏度
sprintf(dis0, " Max:%2d", (int)tempMax);
OLED_ShowString(7 * 8, 0, dis0, FONT_1608); //显示温度阈值
OLED_ShowWord(14 * 8, 0, 0); //显示摄氏度
sprintf(dis0, "RH:%3d%%", (int)U8RH_data_H); //显示湿度
OLED_ShowString(0, 2, dis0, FONT_1608);
sprintf(dis0, " Max:%3d%%", (int)RHMax); //显示湿度阈值
OLED_ShowString(7 * 8, 2, dis0, FONT_1608);
sprintf(dis0, "S:%3d%%", (int)smog); //显示烟雾
OLED_ShowString(0, 4, dis0, FONT_1608);
sprintf(dis0, " Max:%3d%%", (int)smogMax); //显示烟雾阈值
OLED_ShowString(6 * 8, 4, dis0, FONT_1608);
/************************* WIFI模式配置 *************************/
UART_SendStr("AT+CIPMUX=1\r\n", 13); //打开多连接
DelayS(1);
UART_SendStr("AT+CIPSERVER=1,8080\r\n", 21); //建立服务 端口号为8080
/************************* 主循环 *************************/
while (1)
{
if (refreshFlag == 1) //定时刷新屏幕
{
refreshFlag = 0;
DHT11_0_ReadData();
smog = (100 * (ReadADC(AIN0_GND)-29)) / 227; //计算烟雾浓度百分比
if (smog < 0)
{
smog = 0;
}
sprintf(dis0, "%3d", (int)U8T_data_H);
OLED_ShowString(2*8, 0, dis0, FONT_1608);
sprintf(dis0, "%2d", (int)tempMax);
OLED_ShowString(12 * 8, 0, dis0, FONT_1608); //显示温度阈值
sprintf(dis0, "%3d", (int)U8RH_data_H); //显示湿度
OLED_ShowString(3*8, 2, dis0, FONT_1608);
sprintf(dis0, "%3d", (int)RHMax); //显示湿度阈值
OLED_ShowString(12*8, 2, dis0, FONT_1608);
sprintf(dis0, "%3d", (int)smog); //显示烟雾
OLED_ShowString(2*8, 4, dis0, FONT_1608);
sprintf(dis0, "%3d", (int)smogMax); //显示烟雾阈值
OLED_ShowString(11*8, 4, dis0, FONT_1608);
SendData();
}
KeyProcess();
}
}
void Timer0_Init(void)
{
TMOD &= 0xF0; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TL0 = 0x00; //设置定时初始值
TH0 = 0x4C; //设置定时初始值 50ms
PT0 = 1; //设置高优先级
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 1; //定时器开关打开
}
void Timer0_isr(void) interrupt 1
{
static unsigned char numCount = 0;
TL0 = 0x00; //设置定时初始值
TH0 = 0x4C; //设置定时初始值 50ms
numCount++;
if (numCount > 4)
{
numCount = 0;
refreshFlag = 1;
}
}
void SendData(void)
{
char dis[26];
UART_SendStr("AT+CIPSEND=0,26\r\n", 17); //发送数据
DelayMs(100);
sprintf(dis,"T:%3d'C RH:%3d%% S:%3d%%\r\n\r\n", (int)U8T_data_H, (int)U8RH_data_H, (int)smog);
UART_SendStr(dis, 26);
DelayMs(100);
if (U8T_data_H > tempMax) //温度过高
{
UART_SendStr("AT+CIPSEND=0,27\r\n", 17); //发送数据
DelayMs(100);
UART_SendStr("Temperature is too high\r\n\r\n", 27);
DelayMs(100);
}
if (U8RH_data_H > RHMax) //湿度过高
{
UART_SendStr("AT+CIPSEND=0,24\r\n", 17); //发送数据
DelayMs(100);
UART_SendStr("Humidity is too high\r\n\r\n", 24);
DelayMs(100);
}
if (smog > smogMax) //烟雾浓度过高
{
UART_SendStr("AT+CIPSEND=0,38\r\n", 17); //发送数据
DelayMs(100);
UART_SendStr("The smog concentration is too high\r\n\r\n", 38);
DelayMs(100);
}
}
/************************* 串口配置 *************************/
void UART_Init(void)
{
SCON = 0x50;
TH2 = 0xFF;
TL2 = 0xFD;
// RCAP2H = 0xFF; //(65536-(FOSC/32/BAUD)) BAUD = 9600 FOSC = 11059200
// RCAP2L = 0xDC;
RCAP2H = 0xFF; //(65536-(FOSC/32/BAUD)) BAUD = 115200 FOSC = 11059200
RCAP2L = 0xFD;
/*****************/
TCLK = 1;
RCLK = 1;
C_T2 = 0;
EXEN2 = 0;
/*****************/
TR2 = 1;
ES = 1; //串口中断
EA = 1; //打开总中断
}
/************************* 串口发送字节 *************************/
void UART_SendByte(unsigned char dat) //串口发送单字节数据
{
unsigned char time_out;
time_out = 0;
SBUF = dat; //将数据放入SBUF中
while ((!TI) && (time_out < 100)) //检测是否发送出去
{
time_out++;
DelayUs10x(2);
} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
///************************* 串口发送字符串 *************************/
void UART_SendStr(unsigned char *s, unsigned char length)
{
unsigned char num;
num = 0x00;
while (num < length) //发送长度对比
{
UART_SendByte(*s); //放松单字节数据
s++; //指针++
num++; //下一个++
}
}
/************************* 串口中断 *************************/
void UART_Interrupt(void) interrupt 4 //串行中断服务程序
{
static unsigned char i = 0;
static unsigned char firstBit = 0;
static unsigned char R_buf[6];
if (RI)//判断是接收中断产生
{
RI = 0; //标志位清零
TR0 = 0;
//SBUF = SBUF;
if (SBUF == '*') //检查到帧头
{
firstBit = 1; //接收标志成功
i = 0;
R_buf[1] = 0;
R_buf[2] = 0;
R_buf[3] = 0;
R_buf[4] = 0;
R_buf[5] = 0;
}
if (firstBit == 1)
{
R_buf[i] = SBUF;
i++;
if (i == 6 || R_buf[4] == '#' || R_buf[5] == '#') //检测到帧尾
{
if (i == 5 && R_buf[4] == '#')
{
if (R_buf[0] == '*' && R_buf[1] == 'T' && R_buf[2] == '=')
{
tempMax = R_buf[3] - '0';
}
else if (R_buf[0] == '*' && R_buf[1] == 'R' && R_buf[2] == '=')
{
RHMax = R_buf[3] - '0';
}
else if (R_buf[0] == '*' && R_buf[1] == 'S' && R_buf[2] == '=')
{
smogMax = R_buf[3] - '0';
}
}
else if (i == 6 && R_buf[5] == '#') //检测到帧尾
{
if (R_buf[0] == '*' && R_buf[1] == 'T' && R_buf[2] == '=')
{
tempMax = (R_buf[3] - '0') * 10 + (R_buf[4] - '0');
}
else if (R_buf[0] == '*' && R_buf[1] == 'R' && R_buf[2] == '=')
{
RHMax = (R_buf[3] - '0') * 10 + (R_buf[4] - '0');
}
else if (R_buf[0] == '*' && R_buf[1] == 'S' && R_buf[2] == '=')
{
smogMax = (R_buf[3] - '0') * 10 + (R_buf[4] - '0');
}
}
firstBit = 0;
i = 0;
}
}
TR0 = 1;
}
if (TI)//判断是发送中断产生
{
TI = 0; //标志位清零
}
}