1、项目简介
1.1 系统构成
本系统采用stc89c51/stc89c52单片机+复位电路+晶振电路+OLED液晶显示屏+温湿度检测电路+红外检测电路+PCF8591 AD转换电路+风扇控制电路+水泵控制电路+烟雾检测电路+水位检测电路+蜂鸣器报警电路+按键电路+SIM900短信报警电路构成。
1.2 系统功能
- 1、使用51单片机检测并使用OLED显示温湿度、水浸、烟雾数据、是否有人入侵等数据
- 2、当湿度数据超出设置的阈值,通过短信发送报警信息,并使用蜂鸣器报警
- 3、当温度数据超出设置的阈值,通过短信发送报警信息,并使用蜂鸣器报警
- 4、当水位数据超过设置的阈值,通过短信发送报警信息,并使用蜂鸣器报警,并打开水泵抽水,反之关闭水泵
- 5、当烟雾数据超出设置的阈值,通过短信发送报警信息,并使用蜂鸣器报警,并打开风扇,反之关闭风扇
- 6、当检测到有人入侵,使用蜂鸣器报警,并通过短信发送报警信息
- 7、可以通过按键设置每个参数的报警阈值
2、部分电路设计
2.1 STC89C52单片机最小系统电路设计
STC89C52RC单片机是宏晶科技推出的新一代高速、低功耗、超强抗干扰的单片机,指令代码完全兼容传统8051单片机,12时钟/机器周期和6时钟/机器周期可以任意选择。
STC89C52单片机最小系统电路由复位电路、时钟电路和电源电路。拥有这三部分电路后,单片机即可正常工作。
单片机最小系统原理图如下图所示:
实物图:
2.2 PCF8591 AD转换电路设计
PCF8591是单片、单电源低功耗8位CMOS数据采集器件****,上面有光敏电阻、热敏电阻、和电位器,具有4个模拟输入(其中一个为电压模拟输入)、一个模拟输出和一个串行I2C总线接口。3个地址引脚A0、A1和A2用于编程硬件地址,允许将最多8个器件连接至I2C总线而不需要额外硬件。器件的地址、控制和数据通过两线双向I2C总线传输。器件功能包括多路复用模拟输入、片上跟踪和保持功能、8位模数转换和8位数模拟转换。最大转换速率取决于I2C 总线的最高速率。
PCF8591连接方式
- 左排接口:
AOUT:芯片DA输出接口,输出模拟信号。
AINO:芯片模拟输入接口0
AIN1:芯片模拟输入接口1
AIN2:芯片模拟输入接口2
AIN3:芯片模拟输入接口3 - 右边接口:
SCL IIC时钟接口:接树莓派的SCL口(接树莓派 I2C1 SCL口)
SDA IIC数字接口:接树莓派的SDA口(接单树莓派 I2C1 SDA口)
GND 模块地:外接地(接树莓派GND)
VCC 电源接口:外接3.3v-5v (接树莓派电源)这里用的是5V。 - 电路设计
PCF8591模块实物图:
2.2 MQ-2烟雾检测电路设计
- MQ-2 气体传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(SnO2)。当传感器所处环境中存在可燃气体时,传感器的电导率随空气中可燃气体浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。
- MQ-2 气体传感器对丙烷、烟雾的灵敏度高,对天然气和其它可燃蒸气的检测也很理想。这种传感器可检测多种可燃性气体,是一款适合多种应用的低成本传感器。
- 烟雾传感器输出的是模拟信号,这里需要使用AD模块将模拟信号转换为数字信号给单片机,电路图如下:
- MQ-2烟雾传感器实物图:
2.3 水位检测电路设计
- 水位传感器输出的是模拟信号,这里需要使用AD模块将模拟信号转换为数字信号给单片机,电路图如下:
- 水位传感器实物图:
3、部分代码展示
3.1 OLED液晶显示屏初始化
void OLED_Init(void) { OLED_RES_Clr(); delay_ms(200); OLED_RES_Set(); OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel OLED_WR_Byte(0x00,OLED_CMD);//---set low column address OLED_WR_Byte(0x10,OLED_CMD);//---set high column address OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F) OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常 OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常 OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64) OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F) OLED_WR_Byte(0x00,OLED_CMD);//-not offset OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration OLED_WR_Byte(0x12,OLED_CMD); OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02) OLED_WR_Byte(0x02,OLED_CMD);// OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5) OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) OLED_Clear(); OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ }
3.2 串口初始化
void InitUART(unsigned long baud) { //38400波特率的误差位25%,无法使用 SCON = 0x50; //8位数据,可变波特率 #ifdef UART_TIMER2 TL2 = RCAP2L = (65536-(FOSC/32/baud)); //Set auto-reload vaule TH2 = RCAP2H = (65536-(FOSC/32/baud)) >> 8; T2CON = 0x34; //Timer2 start run #else PCON |= 0x80; //使能波特率倍速位SMOD TMOD &= 0x0F; //清除定时器1模式位 TMOD |= 0x20; //设定定时器1为8位自动重装方式 TH1 = TL1 = 256 - FOSC/12/16/baud; ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 #endif EA = 1; //打开总中断 ES = 1; //打开串口中断 }
3.2 DHT11温湿度传感器读取数据
void RH(void) { //主机拉低18ms DHT21=0; DelayMs(18); DHT21=1; //总线由上拉电阻拉高 主机延时20us DelayUs2x(20); //主机设为输入 判断从机响应信号 DHT21=1; //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行 if(!DHT21) //T ! { U8FLAG=2; //判断从机是否发出 80us 的低电平响应信号是否结束 while((!DHT21)&&U8FLAG++); U8FLAG=2; //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态 while((DHT21)&&U8FLAG++); //数据接收状态 COM(); U8RH_data_H_temp=U8comdata; COM(); U8RH_data_L_temp=U8comdata; COM(); U8T_data_H_temp=U8comdata; COM(); U8T_data_L_temp=U8comdata; COM(); U8checkdata_temp=U8comdata; DHT21=1; //数据校验 U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp); if(U8temp==U8checkdata_temp) { U8RH_data_H=U8RH_data_H_temp; U8RH_data_L=U8RH_data_L_temp; U8T_data_H=U8T_data_H_temp; U8T_data_L=U8T_data_L_temp; U8checkdata=U8checkdata_temp; }//fi }//fi }