基于51单片机的温度声光报警器

在日常生活中温度在我们身边无时不在,温度的控制和应用在各个领域都有重要的作用。很多行业中都有大量的用电加热设备,和温度控制设备,如用于报警的温度自动报警系统,热处理的加热炉,用于融化金属的坩锅电阻炉及各种不同用途的温度箱等,这些都采用单片机技术,利用单片机语言程序对它们进行控制。而单片机技术具有控制和操作使用方便、结构简单便于修改和维护、灵活性大且具有一定的智能性等特点,可以精确控制技术标准,提高了温控指标,也大大的提高了产品的质量和性能。

由于单片机技术的优点突出,智能化温度控制技术正被广泛地采用。本文介绍了基于单片机STC89C52 的温度控制系统的设计方案与软硬件实现。采用温度传感器DS18B20 采集温度数据,7段数码管显示温度数据,按键设置温度上下限,当设置为低于下降报警时,当温度低于设定的下限时,点亮发光二极管同时继电器工作,启动加热设备,当温度上升到上限时,断开继电器,停止加热设备工作,如此循环。当设置为高于上限报警时,当温度高于设定的上限时,点亮发光二极管同时继电器工作,启动制冷设备,当温度下降到下限时,熄灭LED,同时断开继电器,使制冷设备停止工作,使温度控制在上下限范围内。上限报警或者是下限报警可以设置,上限和下限温度也可以设置,同时设置的数据掉电后可以存储。给出了系统总体框架、程序流程图和Protel 原理图,并在硬件平台上实现了所设计功能。

温度传感器是DS18B20,显示模块是LCD1602或者数码管都可以,JLC的原理图PCB是数码管,AD的原理图PCB是LCD1602,原理图PCB和下载程序我都放在附件中,供大家参考或者使用

PCB:

AD:

JLC:

原理图:

AD:

JLC:

材料清单:

单片机:STC89C52             1片    
传感器:DS18B20              1只    
晶振:  11.0592MHz            1只    
电容:  33pf                   2个
        22uf电解电容           1个
电阻:  10k                    1个
        4.7k                    1个
         1k                    1个
排阻:  4.7k   9脚             1排
PNP三极管:9012或者8550或者5401   1只
蜂鸣器:                        1个
轻触按钮:5个
四位一体共阴极数码管:1个
红色发光二极管:      1个
万用板:              1块
导线:                若干

代码比较长,但是愿意花心思去理解的话不会难的,下载程序我放在附件供大家下载使用

#include<reg52.h>
#include"stdio.h"

typedef unsigned char uint8;
typedef unsigned int uint16;

/***************************************************/

sbit RS =P2^6;       //LCD1602的数据命令选择
sbit RW = P2^5;
sbit EN_LCD =P2^7;   //LCD1602的使能信号

sbit BUZZER = P2^0;

sbit K1	  = P1^0;	//右
sbit K2   =	P1^1;	//加
sbit K3   = P1^2;	//减


/****************DS18B20引脚**********************/
sbit DS18B20 = P1^3;  //DS18B20数据端
/***********************************************************/
/******************************************************/

void delay(uint16 time);        // 延时函数(6us单位)		
void lcd_ini(); 		        // LCD1602的初始化
void lcd_order(uint8 date);		// 向LCD1602的写1个指令
void lcd_data(uint8 date);		// 向LCD1602的写1个指令

void xie1602(uint8 add,uint8 daa); //写数据

void xianshi1();//显示温度

uint8 ds18_ini();        //ds18B20初使化函数
void ds18_write(uint8 date);   //功能向DS18B20中写入一个数据
uint8 ds18_read();			   //功能从DS18B20中读出一个数据并返回。
void ds18_check();			   //起动DS18B20行进温度采集,并返回当前温度(tmp)
void xiugai();                 //修改报警范围

long  tmp=0;      //储存温度值
long  t_h=37, t_l=10;	  // 温度的上限和下限


bit tmp_hb = 0;  tmp_lb = 0;     //温度上下限调节指示变量

void panduan();		   //判断报警
uint8 hodometer[]= "  H:00   L: 00  ";
uint8 temp[]=	   "  wendu:00.00   ";
uint16 ji = 0;
uint8 ku=0;	 //biaozhiwei

void main()
{
	lcd_ini();
	ds18_ini();        //ds18B20初使化
   	ds18_write(0xcc);  //跳过序列号
  	 ds18_write(0x44);  //启动温度转换
	 xie1602(4,t_h);
	 xie1602(12,t_l);
	while(1)
	{
		ds18_check();  //从DS18B20中读出温度
		xianshi1();
		xiugai();
		panduan();		
	}
}

void xie1602(uint8 add,uint8 daa)
{
	lcd_order(0x80+add);
	lcd_data(0x30+daa/10);
	lcd_data(0x30+daa%10);
}

//判断是否在报警范围内
void panduan()
{
	if(tmp<(t_l*1000)||tmp>(t_h*1000)&&t_l>=0)
	{
		BUZZER = 0;
		delay(10);
	}
	else if(t_l<0&&tmp>(t_h*1000))
	{
		BUZZER = 1;	
	}
	else
		BUZZER = 1;
}


//选择修改的内容
void xiugai()
{	uint8 jj;
	uint8 i = 0;
	BUZZER = 1;
	
	if(K1==0)
	{
		while(!K1);
		while(1)
		{
			lcd_order(0x0f);  //开启光标显示
			lcd_order(0x80+5);//光标显示位置
			if(K2 == 0)			//判断加按键按下
			{
				while(K2 == 0);		  //等待按键释放
					t_h++;			 //温度上限加1
					xie1602(4,t_h);	  //将温度上限显示出来
			}
			if(K3 == 0)				   //判断减按键按下
			{
				while(K3 == 0);			//等待按键释放
				if(t_h>t_l)				//判断 温度上限大于温度下限
					t_h--;
				xie1602(4,t_h);			 //将温度上限显示出来
			}
			if(K1 == 0)			   //后面的注释类似
			{
				while(K1 == 0);
				while(1)
				{
					lcd_order(0x0f);
					lcd_order(0x80+13);	
					if(K2 == 0)
					{
						while(K2 == 0);
						if(t_l<t_h&&t_l>=0)
						{
							lcd_order(0x80+11);
							lcd_data(' ');
							t_l++;
							xie1602(12,t_l);
						}
						else {
							t_l++;
							jj = ~t_l;
							xie1602(12,jj);
						}
					}
					if(K3 == 0)
					{
						while(K3 == 0);
						if(t_l>(-50))
						{
							t_l--;
							if(t_l<0)
								jj = ~t_l;
						}
						if(t_l>=0)
						{
							lcd_order(0x80+11);
							lcd_data(' ');
							xie1602(12,t_l);
						}
						if(t_l<0)
						{	
							xie1602(12,jj);
							lcd_order(0x80+11);
							lcd_data('-');
						}
					}
					if(K1 == 0)
					{
						while(K1 == 0);
						goto loop;
					}		
				}
			}
		}				
	}
	loop:BUZZER = 1;	
}

/**********************************************
函数名:delay
行参  :time 延时基数
功能  :用while延时
************************************************/
// 延时函数(1ms单位)
void delay(uint16 time)
{
	while(time--);
}
/**********************************************
函数名:lcd_ini
功能  :LCD1602的初始化
************************************************/
void lcd_ini() 
 {
 	uint8 i;
 		RW = 0;
	  lcd_order(0x38);	  //设置1602的显示光标功能
	  delay(100);		  
	  lcd_order(0x0e);	  //显示开及光标设置 
	  delay(100);
	  lcd_order(0x06);	  //显示光标移动设置
	  delay(100);
	  lcd_order(0x01);	  //显示清屏
	  delay(100);
	  lcd_order(0x80);
	  	for(i = 0;i<16;i++)
			lcd_data(hodometer[i]);
  }


/**********************************************
函数名:lcd_order
行参  :date 要定入的指令
功能  :向LCD1602的写1个指令
************************************************/
void lcd_order(uint8 date)
{
  RS=0;		  //选择写指令  
  EN_LCD=0;	  //使能初使化
  P0=date;	  //发送指令
  EN_LCD=1;	  //开使能
  delay(100);	  //延时
  EN_LCD=0;	  //关使能
}
/**********************************************
函数名:lcd_order
行参  :date 要定入的指令
功能  :向LCD1602的写1个指令
************************************************/
void lcd_data(uint8 date)
{
  RS=1;		  //选择写数据  
  EN_LCD=0;	  //使能初使化
  P0=date;	  //发送指令
  EN_LCD=1;	  //开使能
  delay(100);	  //延时
  EN_LCD=0;	  //关使能
}

/*************************************************************
    					  DS18B20
**************************************************************/
/****************************************
函数名:    ds18_ini
功能:      对DS18B20进行初使化,
            若DS18B20是好的则返回1
			若DS18B20是环的则返回0
****************************************/
//ds18B20初使化函数,可根据资料上的时序来写
uint8 ds18_ini()
{
  uint8 ans;
  DS18B20 = 1;
  delay(1);
  DS18B20 = 0;
  delay(100);
  DS18B20 = 1;
  delay(6);
  ans = DS18B20;
  delay(100);
   if(!ans)
     return 1;
  else
     return 0;
}

/**********************************
函数名:    ds18_write
函数行参:  date(向ds18b20写入的数据)
功能:      功能向DS18B20中写入一个数据
***********************************/
void ds18_write(uint8 date)
{
  uint8 i;
  DS18B20=1;
  delay(1);
  for(i=0;i<8;i++)	//根据时序将数据从低到高一位一位发送出来
       {
	   	 DS18B20 = 0;
		 if(date&0x01) //从低到高取出数据的每位
		 DS18B20 = 1;
		 else
		 DS18B20 = 0;
		 delay(10);
		 DS18B20 = 1;
		 date>>=1;
		 delay(1);
		 
	   }


} 
 
/*************************************************
函数名:    ds18_read
函数返回值:rate(从ds18b20中读出的数据)
功能:      功能从DS18B20中读出一个数据并返回。
*************************************************/
uint8 ds18_read()
{
  uint8 i,date = 0;
  DS18B20 = 1;		  //释放总线
  delay(1);
  for(i = 0;i < 8;i ++)	  //根据时序将数据从低到高一位一位接收
       {  
	      
	      DS18B20 = 0;
		  date >>= 1;
		  DS18B20 = 1;
		  if(DS18B20)
		     date |= 0x80;	 //将date的一位置1
		  delay(8);
		  DS18B20 = 1;
		  delay(1);
	   
	   }
   return date;			  //返回读出的数
}
/************************************************************
函数名:     ds18_check
函数返回值: tmp(当前温度)
功能:       起动DS18B20行进温度采集,并返回当前温度(tmp)
*************************************************************/
void ds18_check()
{
  uint8 date1,date2;
  float ta;
  if(ds18_ini())
    {
	  
	  ds18_write(0xcc);	  //跳过序列号
	  ds18_write(0x44);	  // 启动温度转换
	  ds18_ini();		  // 复位
	  ds18_write(0xcc);	  //跳过序列号
	  ds18_write(0xbe);	  // 启动读取温度
	  date1 = ds18_read();   //读取两个温度字节
	  date2 = ds18_read();
	  tmp=date2;
	  tmp<<=8;
	  tmp=tmp|date1;
	  ta=tmp*0.0625;
	  tmp=ta*1000;
	}
 

}

void xianshi1()
{
	uint8 i;
	temp[8]=0x30+tmp/10000;
	temp[9]=0x30+tmp/1000%10;
	temp[11]=0x30+tmp/100%10;
	temp[12]=0x30+tmp/10%10;
	temp[13]=0x30+tmp%10;
	lcd_order(0x80+0x40);
	for(i = 0;i<16;i++)
		lcd_data(temp[i]);	
}

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值