基于51单片机的无线火灾报警仿真

基于51单片机的无线火灾报警

(仿真+程序)

功能介绍

具体功能:

1.两块单片机分为主机和从机;

2.两个模块通过串口模拟无线通讯;

3.主机检测温度(0-25°C)和烟雾值,从机用LCD1602显示;

4.DS18B20检测温度,滑动变阻器模拟mq-2;

添加图片注释,不超过 140 字(可选)

程序

#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "stdio.h"
#include "intrins.h"											   
/***微信公众号:木子单片机********/
#define     u8  			unsigned char
#define     u16   		unsigned int
#define     uchar  		unsigned char
#define     uint   		unsigned int
#define 		false     1
#define     true      0
#define     N         2

uint wendu; 									//温度值全局变量
uchar yanwu;					 				//用于读取ADC数据
uchar table[2];

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

/***********************************************************************************************************
ADC0832相关函数
***********************************************************************************************************/
sbit ADCS 	=P1^1; //ADC0832 片选
sbit ADCLK  =P1^2; //ADC0832 时钟
sbit ADDI 	=P1^3; //ADC0832 数据输入		/*因为单片机的管脚是双向的,且ADC0832的数据输入输出不同时进行,
sbit ADDO 	=P1^3; //ADC0832 数据输出		/*为节省单片机引脚,简化电路所以输入输出连接在同一个引脚上

//========================================================================
// 函数: unsigned int Adc0832(unsigned char channel)
// 应用: 		temp=Adc0832(0);
// 描述: 读取0通道的AD值
// 参数: channel:通道0和通道1选择
// 返回: 选取通道的AD值
//========================================================================
unsigned int Adc0832(unsigned char channel)
{
	uchar i=0;
	uchar j;
	uint dat=0;
	uchar ndat=0;
	uchar  Vot=0;

	if(channel==0)channel=2;
	if(channel==1)channel=3;
	ADDI=1;
	_nop_();
	_nop_();
	ADCS=0;//拉低CS端
	_nop_();
	_nop_();
	ADCLK=1;//拉高CLK端
	_nop_();
	_nop_();
	ADCLK=0;//拉低CLK端,形成下降沿1
	_nop_();
	_nop_();
	ADCLK=1;//拉高CLK端
	ADDI=channel&0x1;
	_nop_();
	_nop_();
	ADCLK=0;//拉低CLK端,形成下降沿2
	_nop_();
	_nop_();
	ADCLK=1;//拉高CLK端
	ADDI=(channel>>1)&0x1;
	_nop_();
	_nop_();
	ADCLK=0;//拉低CLK端,形成下降沿3
	ADDI=1;//控制命令结束
	_nop_();
	_nop_();
	dat=0;
	for(i=0;i<8;i++)
	{
		dat|=ADDO;//收数据
		ADCLK=1;
		_nop_();
		_nop_();
		ADCLK=0;//形成一次时钟脉冲
		_nop_();
		_nop_();
		dat<<=1;
		if(i==7)dat|=ADDO;
	}
	for(i=0;i<8;i++)
	{
		j=0;
		j=j|ADDO;//收数据
		ADCLK=1;
		_nop_();
		_nop_();
		ADCLK=0;//形成一次时钟脉冲
		_nop_();
		_nop_();
		j=j<<7;
		ndat=ndat|j;
		if(i<7)ndat>>=1;
	}
	ADCS=1;//拉
	ADCLK=0;//拉低CLK端
	ADDO=1;//拉高数据端,回到初始状态
	dat<<=8;
	dat|=ndat;

	return(dat);            //return ad data
}

/***********************************************************************************************************
DS18B20相关函数
***********************************************************************************************************/

sbit DQ = P1^0;				 //ds18b20的数据引脚



/*****延时子程序:该延时主要用于ds18b20延时*****/
void Delay_DS18B20(int num)
{
  while(num--) ;
}
/*****初始化DS18B20*****/
void Init_DS18B20(void)
{
  unsigned char x=0;
  DQ = 1;         //DQ复位
  Delay_DS18B20(8);    //稍做延时
  DQ = 0;         //单片机将DQ拉低
  Delay_DS18B20(80);   //精确延时,大于480us
  DQ = 1;         //拉高总线
  Delay_DS18B20(14);
  x = DQ;           //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
  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(void)
{
  unsigned char a=0;
  unsigned char b=0;
  unsigned int t=0;
  float tt=0;
  Init_DS18B20();
  WriteOneChar(0xCC);  //跳过读序号列号的操作
  WriteOneChar(0x44);  //启动温度转换
  Init_DS18B20();
  WriteOneChar(0xCC);  //跳过读序号列号的操作
  WriteOneChar(0xBE);  //读取温度寄存器
  a=ReadOneChar();     //读低8位
  b=ReadOneChar();    //读高8位
  t=b;
  t<<=8;
  t=t|a;
  tt=t*0.0625;
  t= tt*10+0.5;     //放大10倍输出并四舍五入
  return(t);
}

/*****校准温度*****/
u16 check_wendu(void)
{
	u16 c;
	c=ReadTemperature();  			//获取温度值并减去DS18B20的温漂误差
//	if(c<1) c=0;
//	if(c>=999) c=999;
	return c;
}

void main (void)
{
	u8 SmokeFlag = false;
	u8 yanwu_cashe;
	u8 TempFlag = false;
	u16 wendu_cashe;
	u8 IntrudeFlag = false;
	uchar j=0; 
	SCON = 0X50;		//设置为工作方式1
	TMOD = 0X20;		//设置计数器工作方式2
	PCON &= 0XEF;		//波特率加倍
	TH1  = 0XFD;		//计数器初始值设置,注意波特率是9600的
	TL1  = 0XFD;
	IE = 0X00;
	TR1  = 1;			//打开计数器
	wendu=check_wendu();		  //初始化时调用温度读取函数 防止开机85°C
	delay_ms(1000);
	wendu=check_wendu();		  //初始化时调用温度读取函数 防止开机85°C
	while (1)        					//主循环
	{
		yanwu=Adc0832(0);				//读取烟雾值
		wendu=check_wendu();	  //读取温度值
		
		 if(yanwu_cashe != yanwu){
				yanwu_cashe = yanwu;
				SmokeFlag = false;
			}
			if(SmokeFlag == false)
				{
					table[0]=yanwu*1000;
					SmokeFlag = true;
			}
		
			if(wendu_cashe != wendu)
			{
				wendu_cashe = wendu;
				TempFlag = false;
			}
			if(TempFlag == false)
			{
				table[1]=wendu;	//发送一个字符
				TempFlag = true;
			}
			table[2]=10;
			for(j=0;j<3;j++)                       
			{
				SBUF=table[j];
				while(!TI);
				TI=0;
				delay_ms(500);
			}
			j=0;                                           
	}
} 

硬件设计

使用元器件:

单片机:AT89C52;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

设计资料

01仿真图

本设计使用proteus8.9版本设计!具体如图!

添加图片注释,不超过 140 字(可选)

02程序

本设计使用软件keil5版本编程设计!具体如图!

添加图片注释,不超过 140 字(可选)

03设计资料

全部资料包括程序(含注释)、仿真源文件等。具体内容如下,全网最全!!

添加图片注释,不超过 140 字(可选)

资料获取请观看前面演示视频!

点赞分享一起学习成长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值