资讯详情

基于51单片机的火灾报警系统仿真

【基于51单片机的火灾报警系统模拟】 一、设计任务 在工业生产中,各种原因引起的火灾对人身安全、仪器设备和生产产品的后果是不可逆转的,因此及时检测生产中的火灾隐患至关重要。由于单一因素的偶然性过大,本设计采用烟雾值、湿度和温度(烟雾值和温度值小于设定阈值,湿度值大于设定阈值时正常),以达到及时报警的目的。要求系统:

  1. 每个指标的阈值(包括,K1选择模式:mode调整烟雾阈值,mode调节湿度阈值,mode调节温度阈值。K2为数值加一。K其中烟雾值为0-255,湿度为0-99,温度为0-99)。
  2. 使用烟雾传感器(模拟中使用滑动电阻和AD更换转换器模块),以及温湿度传感器(DHT11)测量外部实时指标。
  3. 各项指标阈值(第一行)和实际测量值(第二行)实时显示在液晶显示屏 湿度值 温度值。
  4. 报警环节:如果任何指标不合格,蜂鸣器会响,烟雾值超过设定红灯,湿度值低于设定蓝灯,温度值高于设定绿灯。
  5. 串口发送接收任务:虚拟串口向单片机发送信息,单片机存储信息并回复I received.”给PC机。 二、硬件设计图 在这里插入图片描述 三、软件部分代码
/*按键设置烟雾阈值、湿度阈值、温度阈值*/  //mode=设置烟雾阈值 mode=2湿度 mode=3温度 void Key1(){ 
         if(K1==0){ 
          if(mode<3)    mode ;   else    mode=1;  } }  //Key2为加一 void Key2(){ 
         if(K2==0){ 
          if(mode==1)    if(set_yanwu<255){ 
             set_yanwu ;    }    else{ 
            set_yanwu=0;    }   if(mode==2)    if(set_shidu<99){ 
             set_shidu ;    }    else{ 
            set_shidu=0;    }    if(mode==3)    if(set_wendu<99){ 
             set_wendu ;
			}
			else{ 
       
				set_wendu=0;
			}
	}
}

//Key3为减一
void Key3(){ 
       
	if(K3==0){ 
       
		if(mode==1)
			if(set_yanwu>0){ 
       
			  set_yanwu--;
			}
			else{ 
       
				set_yanwu=255;
			}
		if(mode==2)
			if(set_shidu>0){ 
       
			  set_shidu--;
			}
			else{ 
       
				set_shidu=99;
			}	
		if(mode==3)
			if(set_wendu>0){ 
       
			  set_wendu--;
			}
			else{ 
       
				set_wendu=99;
			}
	}
}

void Key(){ 
       
	Key1();
	Key2();
	Key3();
}

/*将设置的阈值存入显示数组*/

void dis_set(){ 
       
	uchar i;
	set_num[0]=(set_yanwu/100)+0x30;
	set_num[1]=(set_yanwu/10)%10+0x30;
	set_num[2]=((set_yanwu%100)%10)+0x30;
	set_num[3]=' ';
	set_num[4]=set_shidu/10+0x30;
	set_num[5]=set_shidu%10+0x30;
	set_num[6]='R';
	set_num[7]='H';
	set_num[8]=' ';
	set_num[9]=set_wendu/10+0x30;
	set_num[10]=set_wendu%10+0x30;
	set_num[11]='C';
}

/*与液晶显示1602相关的函数*/

void LCDdelay(uint x)		  //该延时大约100us(不精确,液晶操作的延时不要求很精确)
{ 
       
  uchar i;
	while(x--)
		for(i=0;i<120;i++);
}

//写命令
void write_com(uchar lcdcom)
{ 
       
  lcdrs=0;		
  P1=lcdcom;
  LCDdelay(5);
  lcden=1;
  LCDdelay(5);
  lcden=0;
}

//写数据
void write_data(uchar lcddate)
{ 
       
  lcdrs=1;
	P1=lcddate;
	LCDdelay(5);
	lcden=1;
	LCDdelay(5);
	lcden=0;
	
}

//1602初始化
void Init1602()
{ 
       
	uchar i;
	lcden=0; 
  write_com(0x38);//屏幕初始化
  write_com(0x0c);//打开显示 无光标 无光标闪烁
  write_com(0x06);//当读或写一个字符是指针后一一位
  write_com(0x01);//清屏
	write_com(0x80);
	for(i=0;i<4;i++){ 
       
		write_data(Set[i]);
	}
	write_com(0x80+0x40);
	for(i=0;i<4;i++){ 
       
		write_data(Rel[i]);
	}
}
	
/*模数转换器相关函数*/

uchar ADC(uint x){ 
          //形参为通道地址,返回值为转换值 
	uchar dat;  
  XBYTE[x]=0x00; //启动AD0809 
	while(EOC!=0);   //查询等待 
	dat=XBYTE[x];    //读取A/D转换值 
	return dat;          //返回ADC值
}

void samp(){ 
            
	uchar i;   
	total = 0;   
	for(i=0;i<50;i++)
	  total=total+ADC(0x7FF8); //求和 
  total=total/50;  //均值滤波 
  rel_yanwu=total;
}

void deal(){ 
        
	uchar x;     
	x=(uchar) total; 
	dis[0]=total%10;//求个位显示值 
	total=total/10;   
	dis[1]=total%10;//求十位显示值 
  dis[2]=total/10;  //求百位显示值 
}

/*温湿度传感器相关函数*/
void DHT11_delay_us(uchar n){ 
           //延时us
    while(--n);
}

void DHT11_delay_ms(uint z){ 
            //延时ms
   uint i,j;
   for(i=z;i>0;i--)
      for(j=110;j>0;j--);
}

void DHT11_start(){ 
       
   Data=1;
   DHT11_delay_us(2);
   Data=0;
   DHT11_delay_ms(30);   //延时18ms以上
   Data=1;
   DHT11_delay_us(30);
}

uchar DHT11_rec_byte(){ 
          //接收一个字节
   uchar i,dat=0;
   for(i=0;i<8;i++){ 
           //从高到低依次接收8位数据 
		 while(!Data);   等待50us低电平过去
     DHT11_delay_us(8);     //延时60us,如果还为高则数据为1,否则为0 
     dat<<=1;           //移位使正确接收8位数据,数据为0时直接移位
     if(Data==1)    //数据为1时,使dat加1来接收数据1
        dat+=1;
     while(Data);  //等待数据线拉低 
   }  
   return dat;
}

void DHT11_receive(){ 
             //接收40位的数据
   uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise; 
   DHT11_start();
   if(Data==0){ 
       
		 while(Data==0);   //等待拉高 
     DHT11_delay_us(40);  //拉高后延时80us
     R_H=DHT11_rec_byte();    //接收湿度高八位 
     R_L=DHT11_rec_byte();    //接收湿度低八位 
     T_H=DHT11_rec_byte();    //接收温度高八位 
     T_L=DHT11_rec_byte();    //接收温度低八位
     revise=DHT11_rec_byte(); //接收校正位

     DHT11_delay_us(25);    //结束

     if((R_H+R_L+T_H+T_L)==revise){ 
            //校正
			 RH=R_H;
       RL=R_L;
       TH=T_H;
       TL=T_L;
		 } 
     /*数据处理,方便显示*/
     rec_dat[0]='0'+(RH/10);
     rec_dat[1]='0'+(RH%10);
     rec_dat[2]='R';
     rec_dat[3]='H';
     rec_dat[4]=' ';
     rec_dat[5]='0'+(TH/10);
     rec_dat[6]='0'+(TH%10);
     rec_dat[7]='C';	
	 }
}

/*显示函数*/
void display() { 
        
	uchar i;
	DHT11_delay_ms(100);    //DHT11上电后要等待1S以越过不稳定状态在此期间不能发送任何指令
  DHT11_receive();
	dis_set();
	write_com(0x80+4);//显示设定阈值
	for(i=0;i<12;i++){ 
       
		write_data(set_num[i]);
	}
	write_com(0x80+0x40+4); //实测烟雾值
	write_data(dis[2]+0x30);
  write_data(dis[1]+0x30);
	write_data(dis[0]+0x30);
	write_com(0x80+0x40+8);   //实测温湿度
  for(i=0;i<8;i++){ 
       
		write_data(rec_dat[i]);  
	} 
	
	LCDdelay(1000);	
 
 }

/*比较设定阈值与实际测量值,给出响应*/
void comp(){ 
       
	rel_shidu=(rec_dat[0]-0x30)*10+(rec_dat[1]-0x30);
	rel_wendu=(rec_dat[5]-0x30)*10+(rec_dat[6]-0x30);
	if(rel_yanwu>set_yanwu)
		red_LED=0;
	else
		red_LED=1;//烟雾值过高红灯亮
	if(rel_shidu<set_shidu)
		blue_LED=0;
	else
		blue_LED=1;//湿度过低蓝灯亮
	if(rel_wendu>set_wendu)
		green_LED=0;
	else
		green_LED=1;//温度过高绿灯亮 
	if((rel_yanwu<set_yanwu)&&(rel_shidu>set_shidu)&&(rel_wendu<set_wendu))
		bee=1;
	else
		bee=0;//只要有一项不合标准则蜂鸣器报警
}

/*串口通信*/
//初始化串口 (设置串口,开启串口中断)
void init_uart(void)
{ 
       
	SCON = 0x50;		        // SCON: 方式 1, 8-bit, 允许接收数据 
	TMOD |= 0x20;               // TMOD: 设置定时器1工作在方式2, 8-bit 自动重装
	TH1 = 0xFD;               // TH1: 初始值为0xFD 波特率:9600 晶振频率:11.0592MHz 
	TL1 = 0x0;
	TR1 = 1;                  // TR1: 开启定时器1 
	EA  = 1;                  //打开总中断
	ES  = 1;                  //打开串口中断
}       

           
// 发送一个字节数据
void uart_send_byte(unsigned char dat)
{ 
       
	SBUF = dat; // 将数据送到发送缓冲寄存器SBUF,一位一位的发送
	while(!TI); // 等待发送完毕 (发送完毕TI硬件置1)
	TI = 0;// 将TI清零,表示可以发送下一字节数据。
}

// 发送字符串
void uart_send_str(unsigned char *s)
{ 
       
	while(*s != '\0')// '\0':字符串结束标志
	{ 
       
		uart_send_byte(*s);// 发送1个字节数据,1个字符占8位,1字节
		s++;// 指向下一个字符
	}
}


// 串口中断处理函数 (串口接收到数据,发送数据完毕都可以引起串口中断)
void uart_interrupt(void) interrupt 4 		//也叫串行中断服务程序
{ 
       
	unsigned char recv_data;// 用来存放接收到的数据
	unsigned char send_data[] = "I received.\n";// 要发送的信息
	
	if(RI) //接收数据(1字节)完毕,RI会被硬件置1
	{ 
       
		RI = 0;            		// 将 接收中断标志位 清零(让串口可以继续接收数据)
		recv_data = SBUF;           	//读取接收到的数据,并存放到data
	  uart_send_str(send_data); //收到数据之后,发送字符串"I received."给对方
	}
	if(TI)// 发送数据(1字节)完毕
	{ 
       
		TI = 0;// 将 发送中断标志位 清零(让串口可以继续发送数据)
	}
} 

基于以上可以完成在火灾报警器中对于温湿度的采集的模拟以及报警,全部代码及仿真文件下载链接:https://download.csdn.net/download/creampang/85766276

标签: tr200温度变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台