这应该算是我本科阶段做的第一个项目,入门单片机的时候拿51做的一个简单的火灾报警装置,由于年代久远,很多细节可能都忘了,不过有什么问题欢迎大家留言,看到后还是会尽力帮大家解决。

写在前面

这个装置用的是最简单的51单片机外加几个简单的传感器,项目大致流程就是:

收集传感器信息 —> 信息处理 —> 执行对应动作

目录

  • 火灾报警装置功能介绍
  • 原理图
  • 源代码

功能介绍

总览

android 自动重连蓝牙_#include

  • 这是整个装置的总览图, 各种零件标注如下:
  • 1、温度阈值
  • 2、烟雾浓度阈值
  • 3、实时温度
  • 4、实时烟雾浓度
  • 5、蜂鸣器用于报警
  • 6、黄、红色LED灯指示
  • 7、风扇用于疏散烟雾
  • 8、烟雾传感器
  • 9、温度传感器

功能一:温度实时监测

android 自动重连蓝牙_android 自动重连蓝牙_02

  • LCD1602中第二行显示的为当前环境的温度和烟雾浓度
  • 这两个数值会随环境变化而实时变化

功能二:两级阈值及报警

  • LCD1062第一行为温度和烟雾浓度的阈值(上图为一级阈值)
  • 当温度或烟雾浓度超过对应一级阈值后,蜂鸣器会报警,并且亮起黄色警报灯,风扇启动一级转速,同时阈值变为二级阈值(如下图)
  • 当温度或烟雾浓度超过二级阈值后,蜂鸣器持续报警,亮起红色指示灯,风扇全速转动
  • 当温度和烟雾浓度都降到一级阈值以下,自动关闭所有报警措施
  • 一级、二级阈值均可自行设定

android 自动重连蓝牙_#include_03

功能三:手机远程遥控

android 自动重连蓝牙_单片机_04

  • 本装置装有HC-05蓝牙模块,可与手机通信(当时不是很了解,HC-05不支持IOS,还特意借了个安卓调试)
  • 手机通过串口助手连上蓝牙后,装置会不断向手机发送当前的温度和烟雾浓度
  • 手机可通过向装置发送0、1、2指令分别控制装置的关闭、一级警报、二级警报。

以上所有图均有动图展示,由于图片过大无法上传,感兴趣的可以到文章底部的github上下载。

原理图

android 自动重连蓝牙_#include_05

  • 原理图用的是AD17自行绘制的,毕竟不是学这个的,所以画的不是很专业,大致一看即可。
  • github有pdf版和源文件,需要可自己去下载。

源码

  • 源码部分每个模块对应了一个.c文件,共7个:
  • 主逻辑函数main.c
  • 蜂鸣器模块Buzzer.c
  • 温度模块DS18B20.c
  • 蓝牙模块HC-05.c
  • 液晶显示LCD1602.c
  • 风扇驱动Motor.c
  • 烟雾传感模块MQ-2.c

main.c

#include <reg52.h>

sbit LED1 = P2^1;
sbit LED2 = P2^2;

bit flagOff = 0;
unsigned char flagOn = 0;
unsigned int preTmp1 = 40;
unsigned int preSmk1 = 20;
unsigned int preTmp2 = 60;
unsigned int preSmk2 = 30;
unsigned int bkp[2];
unsigned int smk;
unsigned int tmp;
unsigned int sum;
unsigned char RxdBuf = '4';
unsigned char flag = 0;
unsigned char cnt;
unsigned char T0RH, T0RL;

extern unsigned int getTmp();
extern unsigned int ADC0832(unsigned char);
extern void sendData();
extern void openBuzzer(unsigned int);
extern void stopBuzzer();
extern void Motor(unsigned char);
extern void InitDS18B20();
extern void Display1602(unsigned int,unsigned int,unsigned int,unsigned int);	//显示温度,烟雾值
extern void Init1602();
extern void configUART(unsigned int);
void checkSta();

void main()
{
	unsigned int i = 0;
	unsigned int j = 0;
	EA = 1;
	InitDS18B20();
	Init1602();
	configUART(9600);
	bkp[0] = getTmp();
	bkp[1] = ADC0832(1);
	for(j=0;j<33000;j++);
	while(1)						
	{
		for(cnt=0;cnt<50;cnt++)			
		{
			smk = ADC0832(1);	
			sum=sum+smk;			
		}
		smk=sum/50;				
		sum=0;
		tmp = getTmp();
		if((bkp[0]!=tmp/10)||(bkp[1]!=smk))
		{
			bkp[0] = tmp/10;
			bkp[1] = smk;
			sendData();
		}
		checkSta();
		switch(flag)
		{
			case 0:
			{
				Display1602(preTmp1, preSmk1, tmp, smk);
				stopBuzzer();
				LED1 = 1;
				LED2 = 1;
				Motor(0);
				break;
			}
			case 1:
			{
				openBuzzer(4000);
				LED1 = 0;
				LED2 = 1;
				Motor(1);
				Display1602(preTmp2, preSmk2, tmp, smk);
				break;
			}
			case 2:
			{
				openBuzzer(4000);
				LED2 = 0;
				LED1 = 1;
				Motor(2);
				Display1602(preTmp2, preSmk2, tmp, smk);
				break;
			}
			default:
				break;
		}	
		for(i=0;i<20000;i++);
	}
}

void checkSta()
{
	switch(RxdBuf)
	{
		case '0': flagOff = 1;flagOn = 0; break;
		case '1': flagOn = 1; break;
		case '2': flagOn = 2; break;
		case '3': flagOff = 0; flagOn = 0; break;
		default: break;
	}
	if(((((tmp/10)>=preTmp1)||(smk>=preSmk1))&&flagOff==0)||flagOn>0)
	{
		if(((tmp/10)>=preTmp2||smk>=preSmk2)||flagOn==2)
			flag = 2;
		else
			flag = 1;
	}
	else
		flag = 0;
}

Buzzer.c

#include <reg52.h>

sbit BUZZ = P2^5;

unsigned char T1RH = 0;
unsigned char T1RL = 0;

void openBuzzer(unsigned int frequ)
{
	unsigned int reload;
	reload = 65536 - (11059200/12)/(frequ*2);
	RCAP2H = (unsigned char)(reload>>8);
	RCAP2L = (unsigned char)reload;
	
	ET2 = 1;
	TR2 = 1;
}

void stopBuzzer()
{
	ET2 = 0;
	TR2 = 0;
	BUZZ = 1;
}

void interruptTimer2() interrupt 5
{

	TF2 = 0;
	BUZZ = ~BUZZ;
}

DS18B20.c

#include <reg52.h>

sbit DQ = P2^0;

void Delay_DS18B20(int num)
{
  while(num--) ;
}
void InitDS18B20(void)
{
  unsigned char x=0;
  DQ = 1;         
  Delay_DS18B20(8);    
  DQ = 0;         
  Delay_DS18B20(80);   
  DQ = 1;        
  Delay_DS18B20(14);
  x = DQ;          
  Delay_DS18B20(20);
}
unsigned char ReadOneChar(void)
{
  unsigned char i=0;
  unsigned char dat = 0;
  for (i=8;i>0;i--)
  {
    DQ = 0;    
    dat>>=1;
    DQ = 1;     
    if(DQ)
    dat|=0x80;
    Delay_DS18B20(4);
  }
  return(dat);
}
void WriteOneChar(unsigned char dat)
{
  unsigned char i=0;
  for (i=8; i>0; i--)
  {
    DQ = 0;
    DQ = dat&0x01;
    Delay_DS18B20(5);
    DQ = 1;
    dat>>=1;
  }
}
unsigned int ReadTemperature()
{
  unsigned char a=0;
  unsigned char b=0;
  unsigned int t=0;
  float tt=0;
  InitDS18B20();
  WriteOneChar(0xCC);  
  WriteOneChar(0x44); 
  InitDS18B20();
  WriteOneChar(0xCC);  
  WriteOneChar(0xBE);  
  a=ReadOneChar();     
  b=ReadOneChar();    
  t=b;
  t<<=8;
  t=t|a;
  tt=t*0.0625;
  t= tt*10+0.5;     
  return t;
}



unsigned int getTmp()
{
	unsigned int c;
	c=ReadTemperature()-5;	
	if(c<0) c=0;					
	if(c>=999) c=999;
	return c;
}

HC-05.c

#include <reg52.h>

extern unsigned int smk;
extern unsigned int tmp;
extern unsigned char RxdBuf;
unsigned char *ptrTxd;
unsigned char cntTxd = 0;
unsigned char NowData[] = {'T','e','m','p','e','t','u','r','e',':','0','0','.','0',
 												' ',' ','S','m','o','k','e',':','0','0','\n'};
void configUART(unsigned int);
												
void sendData()
{
	NowData[10] = tmp/100 + 48;
	NowData[11] = tmp%100/10 + 48;
	NowData[13] = tmp%10 + 48;
	NowData[22] = smk/10 + 48;
	NowData[23] = smk%10 + 48;
	
	ptrTxd = NowData;
	cntTxd = sizeof(NowData);
	TI = 1;
	
}


void configUART(unsigned int baud)
{
	SCON = 0x50;
	TMOD &= 0x0F;
	TMOD |= 0x20;
	TH1 = 256 - (11059200/12/32)/baud;
	TL1 = TH1;
	ET1 = 0;
	ES = 1;
	TR1 = 1;
}

void interruptUART() interrupt 4
{
	if(RI)
	{
		RI = 0;
		RxdBuf = SBUF;
	}
	if(TI)
	{
		TI = 0;
		if(cntTxd > 0)
		{
			SBUF = *ptrTxd;
			cntTxd--;
			ptrTxd++;
	  }
  }
}

LCD1602.c

#include <reg52.h>

sbit LCDRS = P1^0;
sbit LCDEN= P1^1;
unsigned char code Init1[]="SET T:00   E:000";
unsigned char code Init2[]="NOW T:00.0 E:000";


void LCDdelay(unsigned int z)
{
  unsigned int x,y;
  for(x=z;x>0;x--)
    for(y=10;y>0;y--);
}


void write_com(unsigned char com)
{
  LCDRS=0;
  P0=com;
  LCDdelay(5);
  LCDEN=1;
  LCDdelay(5);
  LCDEN=0;
}

void write_data(unsigned char date)
{
  LCDRS=1;
  P0=date;
  LCDdelay(5);
  LCDEN=1;
  LCDdelay(5);
  LCDEN=0;
}

void Init1602()
{
  unsigned char i=0;
  write_com(0x38);
  write_com(0x0c);
  write_com(0x06);
  write_com(0x01);
  write_com(0x80);

  for(i=0;i<16;i++)
  {
		write_data(Init1[i]);
  }
  write_com(0x80+0x40);
  for(i=0;i<16;i++)
  {
		write_data(Init2[i]);
  }
}

void Display1602(unsigned int preTmp, unsigned int preSmk,
									unsigned int tmp, unsigned int smk)
{
	write_com(0x80+6);
	write_data(0x30+preTmp/10);
	write_data(0x30+preTmp%10);

	write_com(0x80+13);
	write_data(0x30+preSmk/100);
	write_data(0x30+preSmk%100/10);
	write_data(0x30+preSmk%10);

	write_com(0x80+0x40+6);
	write_data(0x30+tmp/100);
	write_data(0x30+tmp%100/10);
	write_data('.');
	write_data(0x30+tmp%10);

	write_com(0x80+0x40+13);
	write_data(0x30+smk/100);
	write_data(0x30+smk%100/10);
	write_data(0x30+smk%10);
}

Motor.c

#include <reg52.h>

sbit MOTOR = P3^5;

unsigned char HighRH, HighRL, LowRH, LowRL;

void configPWM(unsigned int fre, unsigned char dc)
{
	unsigned high, low;
	unsigned long tmp;
	
	tmp = (11059200/12)/fre;
	high = (tmp*dc)/100;
	low = tmp - high;
	high = 65536 - high +12;
	low = 65536 - low + 12;
	HighRH = (unsigned char)(high>>8);
	HighRL = (unsigned char)(high);
	LowRH = (unsigned char)(low>>8);
	LowRL = (unsigned char)(low);
	
	TMOD &= 0xF0;
	TMOD |= 0x01;
	TH0 = HighRH;
	TL0 = HighRL;
	ET0 = 1;
	TR0 = 1;
}

void closePWM()
{
	ET0 = 0;
	TR0 = 0;
	MOTOR = 1;
}
void Motor(unsigned char sta)
{
	switch(sta)
	{
		case 0: {closePWM(); break;}
		case 1:	{configPWM(200, 40); break;}
		case 2: {closePWM(); MOTOR = 0; break;}
		default: break;
	}
}


void interruptTimer0() interrupt 1 
{
	if(MOTOR == 1)
	{
		TH0 = LowRH;
		TL0 = LowRL;
		MOTOR = 0;
	}
	else
	{
		TH0 = HighRH;
		TL0 = HighRL;
		MOTOR = 1;
	}
}

MQ-2.c

#include <reg52.h>
#include <intrins.h>

sbit CS = P1^4;
sbit Clk = P1^2;
sbit DATI = P1^3;
sbit DATO = P1^3;

unsigned int ADC0832(unsigned char CH)
{
     unsigned int i,test,adval,dat1;
     adval = 0x00;
     test = 0x00;
     Clk = 0;      
     DATI = 1;
    _nop_();
    CS = 0;
    _nop_();
    Clk = 1;
   _nop_();


   if ( CH == 0x00 )     
   {
       Clk = 0;
       DATI = 1;      
       _nop_();
      Clk = 1;
        _nop_();
        Clk = 0;
      DATI = 0;      
      _nop_();
      Clk = 1;
      _nop_();
    } 
    else
    {
       Clk = 0;
    DATI = 1;      
      _nop_();
      Clk = 1;
      _nop_();
      Clk = 0;
      DATI = 1;      
    _nop_();
     Clk = 1;
     _nop_();
   }

      Clk = 0;
      DATI = 1;
   for( i = 0;i < 8;i++ )     
    {
       _nop_();
       adval <<= 1;
       Clk = 1;
       _nop_();
       Clk = 0;
       if (DATO)
          adval |= 0x01;
      else
          adval |= 0x00;
    }
      for (i = 0; i < 8; i++)      
      {
           test >>= 1;
           if (DATO)
              test |= 0x80;
           else 
              test |= 0x00;
          _nop_();
          Clk = 1;
          _nop_();
          Clk = 0;
      }
      //if (adval == test)     
       dat1 = test;
       nop_();
       CS = 1;       
       DATO = 1;
       Clk = 1;
       return dat1;
}

整个项目的所有源码文件均在我的github上,感兴趣的帮点个star~

附带说明文档和营销方案

github:https://github.com/YWonchall/fire-alarm-device