使用51单片机构建烟雾温度火灾报警器:Proteus仿真与LCD1602显示

设计要求
设计一个简单、实用的基于单片机室内火灾报警系统(模拟机),对火灾的实时、准确监测,快速、自动报警,该系统能自动完成对布测点的火情检测即气体温度、浓度,设定一个温度,由液晶显示屏会看到温度变化,如果超过设定温度就会自动报警,报警形式有声音和灯光闪烁,。要求报警时输出一个状态指示信号,用一个LED点亮示意。

设计指标
(1) 选择一款合适的烟雾传感器,在兼顾检测精度的同时尽量降低成本用于前端检测电路之用;
(2) 以51单片机为核心对烟雾浓度进行实时检测,检测结果可通过数码管、液晶或者其他方式进行显示;
(3) 检测结果与阈值进行比较,通过启动蜂鸣器达到超限报警的功能,并触发继电器闭合。

硬件设计

系统方案设计
本设计以STC89C51单片机为系统的核心处理芯片,通过烟雾传感器MQ-2模块及温度传感器DS18B20进行检测环境中的烟雾浓度及温度进行实施监测,同时也采用ADC0832数模转换模块将烟雾传感器所采集到的烟雾值转化为电压值从而传递给核心处理芯片,通过核心处理芯片STC89C51单片机对数据进行,并且将其监测到的温度和烟雾浓度通过LcD1602液晶显示屏幕进行显示。
预设温度过高和烟气浓度过高报警的临界值,如果探测所得数据超过报警值,便接通蜂鸣器和LED灯开始报警;如果没有达到报警临街值则继续正常工作;如果收到的是报警按键信号,则立即报警。同时无论哪种情况显示模块都正常显示温度和烟雾浓度。
系统工作原理框图如2.1所示:

液晶显示电路
LCD1602的引脚RS,RW,E,DBO,DB1,DB2,DB3,DB4,DB5,DB6,DB7分别接到单片机P20,P26,P27,P00,P01,P02,P03,P04,P05,P06,P07进行与单片机的通信,以便于显示出单片机所要求要显示的字符。本部分硬件连接情况就是这样,软件系和几部分第四部分有更详细的说明。
由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点。因此,液晶显示器画质高且不会闪烁。
液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。
液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多。
相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。并且在考虑系统耗电及供电的问题我们采用了LCD1602液晶显示屏幕。
(1)引脚说明:
第1脚:VSS为地电源。
第2脚:VDD接5V正电源。
第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平
R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:D0~D7为8位双向数据线。
第15脚:背光源正极。
第16脚:背光源负极。

仿真图:

原理图:

程序设计

#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "intrins.h"											   

#define     u8  			unsigned char
#define     u16   		unsigned int
#define     uchar  			unsigned char
#define     uint   		unsigned int

uchar yushe_wendu=50;				//温度预设值
uchar yushe_yanwu=100;				//烟雾预设值
uint wendu; 								//温度值全局变量
uchar yanwu;					 			//用于读取ADC数据

//运行模式  
uchar Mode=0;				 				//=1是设置温度阀值  =2是设置烟雾阀值	=0是正常监控模式
//管脚声明
sbit Led_Reg		 =P2^2;				 //红灯
sbit Led_Yellow  =P2^4;				 //黄灯
sbit Buzzer    	 =P2^0;				 //蜂鸣器
sbit Fan    	 	 =P3^3;				 //


/********************************************************************
* 名称 : delay_1ms()
* 功能 : 延时1ms函数
* 输入 : q
* 输出 : 无
***********************************************************************/
void delay_ms(uint q)
{
	uint i,j;
	for(i=0;i<q;i++)
		for(j=0;j<110;j++);
}
/***********************************************************************************************************
LCD1602相关函数
***********************************************************************************************************/

//LCD管脚声明 (RW引脚实物直接接地,因为本设计只用到液晶的写操作,RW引脚一直是低电平)
sbit LCDRS = P2^7;
sbit LCDEN = P2^6;
sbit D0		 = P0^0;
sbit D1		 = P0^1;
sbit D2		 = P0^2;
sbit D3		 = P0^3;
sbit D4		 = P0^4;
sbit D5		 = P0^5;
sbit D6		 = P0^6;
sbit D7		 = P0^7;



//LCD延时
void LCDdelay(uint z)		  //该延时大约100us(不精确,液晶操作的延时不要求很精确)
{
  uint x,y;
  for(x=z;x>0;x--)
    for(y=10;y>0;y--);
}
void LCD_WriteData(u8 dat)	  
{
	if(dat&0x01)D0=1;else D0=0;
	if(dat&0x02)D1=1;else D1=0;
	if(dat&0x04)D2=1;else D2=0;
	if(dat&0x08)D3=1;else D3=0;
	if(dat&0x10)D4=1;else D4=0;
	if(dat&0x20)D5=1;else D5=0;
	if(dat&0x40)D6=1;else D6=0;
	if(dat&0x80)D7=1;else D7=0;
}
//写命令
void write_com(uchar com)
{
  LCDRS=0;				  
	LCD_WriteData(com);
//  DAT=com;
  LCDdelay(5);
  LCDEN=1;
  LCDdelay(5);
  LCDEN=0;
}
//写数据
void write_data(uchar date)
{
  LCDRS=1;
	LCD_WriteData(date);
//  DAT=date;
  LCDdelay(5);
  LCDEN=1;
  LCDdelay(5);
  LCDEN=0;
}

/*------------------------------------------------
              选择写入位置
------------------------------------------------*/
void SelectPosition(unsigned char x,unsigned char y) 
{     
	if (x == 0) 
	{     
		write_com(0x80 + y);     //表示第一行
	}
	else 
	{      
		write_com(0xC0 + y);      //表示第二行
	}        
}
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
{     
	SelectPosition(x,y) ;
	while (*s) 
	{     
		write_data( *s);     
		s ++;     
	}
}
//========================================================================
// 函数: void LCD_Write_Char(u8 x,u8 y,u16 s,u8 l)
// 应用: LCD_Write_Char(0,1,366,4) ;
// 描述: 在第0行第一个字节位置显示366的后4位,显示结果为 0366
// 参数: x:行,y:列,s:要显示的字,l:显示的位数
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注: 最大显示65535
//========================================================================
void LCD_Write_Char(u8 x,u8 y,u16 s,u8 l) 
{     
	SelectPosition(x,y) ;

	if(l>=5)
		write_data(0x30+s/10000%10);	//万位
	if(l>=4)
		write_data(0x30+s/1000%10);		//千位
	if(l>=3)
		write_data(0x30+s/100%10);		//百位
	if(l>=2)
		write_data(0x30+s/10%10);			//十位
	if(l>=1)
		write_data(0x30+s%10);		//个位

}
/*1602指令简介
  write_com(0x38);//屏幕初始化
  write_com(0x0c);//打开显示 无光标 无光标闪烁
  write_com(0x0d);//打开显示 阴影闪烁
  write_com(0x0d);//打开显示 阴影闪烁
*/
//1602初始化
void Init1602()
{
  uchar i=0;
  write_com(0x38);//屏幕初始化
  write_com(0x0c);//打开显示 无光标 无光标闪烁
  write_com(0x06);//当读或写一个字符是指针后一一位
  write_com(0x01);//清屏
	
}

void Display_1602(yushe_wendu,yushe_yanwu,c,temp)
{
	//显示预设温度
	LCD_Write_Char(0,6,yushe_wendu,2) ;
	
	//显示预设烟雾
	LCD_Write_Char(0,13,yushe_yanwu,3) ;
	
	//时时温度
	LCD_Write_Char(1,6,c/10,2) ;
	write_data('.');
	LCD_Write_Char(1,9,c%10,1) ;
	
	//时时烟雾
	LCD_Write_Char(1,13,temp,3) ;
}

附:http://www.jh-tec.cn/archives/7147

.

物联沃分享整理
物联沃-IOTWORD物联网 » 使用51单片机构建烟雾温度火灾报警器:Proteus仿真与LCD1602显示

发表评论