基于温度传感器的智能热水器

目录

 热水器水温显示器


 

一、设计目的

1. 了解DS18B20温度传感器工作原理及引脚功能。

2. 理解DS18B20温度传感器的单总线工作时序。

3. 学会使用DS18B20温度传感器采集温度信号。

4. 了解继电器工作原理及引脚功能。

5. 学会使用面包板搭建外部电路

6. 会使用八段数码管显示温度值。

 

二、项目设计要求

使用51单片机控制DS18B20温度传感器检测热水器水温,并将水温值显示在八段数码管显示模块上,当温度处于35-45度之间时绿灯亮,否则红灯亮,并且蜂鸣器发出报警声。

三、系统实现图

 四、代码实现

DS18b20温度传感器 代码实现:

#include <ds18b20.h> 

sbit ds=P2^2;     //温度传感器信号线 
  
void dsreset()    //18B20复位,初始化函数
{
  u16 i;
  ds=0;
  i=103;
  while(i>0)i--; //延时
  ds=1;
  i=4;
  while(i>0)i--;   //延时
}

bit tempreadbit()   //读1位函数
{
   u16 i;
   bit dat;
   ds=0;i++;          //i++ 起延时作用
   ds=1;i++;i++;
   dat=ds;
   i=8;while(i>0)i--;	//延时
   return(dat);
}

u8 tempread()   //读1个字节
{
  u8 i,j,dat;
  dat=0;
  for(i=1;i<=8;i++)
  {
    j=tempreadbit();
    dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好一个字节在DAT里
  }
  return(dat);
}

void tempwritebyte(u8 dat)   //向18B20写一个字节数据
{
  u16 i;
  u8 j;
  bit testb;
  for(j=1;j<=8;j++)
  {
    testb=dat&0x01;
    dat=dat>>1;
    if(testb)     //写 1
    {
      ds=0;
      i++;i++;	 //延时
      ds=1;
      i=8;while(i>0)i--;  //延时长
    }
    else
    {
      ds=0;       //写 0
      i=8;while(i>0)i--;   //延时长
      ds=1;
      i++;i++;			//延时
    }

  }
}

void tempchange()  //DS18B20 开始获取温度并转换
{
  dsreset();
  delay_ms(1);
  tempwritebyte(0xcc);  // 写跳过读ROM指令
  tempwritebyte(0x44);  // 写温度转换指令
}

float get_temp()         //读取寄存器中存储的温度数据
{
  u8 a,b;
  u16 t;
  int temp;
  float f_temp;
  dsreset();
  delay_ms(1);
  tempwritebyte(0xcc);// 写跳过读ROM指令
  tempwritebyte(0xbe);// 发读数据指令
  a=tempread();         //读低8位
  b=tempread();         //读高8位
  if(b&0x08) b=b|0xf0;
  t=b;
  t*=256;            //两个字节组合为1个字
  t=t|a;  							 
  temp=t;
  f_temp=temp*0.0625;      //温度在寄存器中为12位 分辨率位0.0625°
  return  f_temp; 
} 
//数码管代码实现:

#include <shumaguan.h>
sbit DX=P2^6;
sbit WX=P2^7;
u8 code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00}; //共阴数码管编码

void Print_u32_LED(u32 n)//输出6位无符号整数(0-999999)到6位数码管,不足6位时,前面不显示
{u8 t=0xdf;
 while(n)
 {	P0=0xff; //消影
	WX=1;//允许更新位码
	P0=t; //送位码
	WX=0;//锁存位码
	   
	P0=0x00; //消影
	DX=1;//允许更新段码
	P0=table[n%10]; //送段码
	DX=0;//锁存段码
	  		 	   
    n=n/10;
	t=_cror_(t,1);
	delay_ms(3);
 }
}
void Print_str_LED(u8 *f)//输出数字串到数码管
{
 u8 t=0xdf,i;
 i=strlen(f);
 while(i)
 {	P0=0xff; //消影
	WX=1;//允许更新位码
	P0=t; //送位码
	WX=0;//锁存位码
	   
	P0=0x00; //消影
	DX=1;//允许更新段码
	switch(f[i-1])
	{
	case '.':i--;P0=table[f[i-1]-'0']|0x80;break;
	case '-':P0=0x40;break;
	case ' ':P0=0x00;break;
	default:P0=table[f[i-1]-'0']; 
	} //送段码
	DX=0;//锁存段码
	  		 	   
    i--;
	t=_cror_(t,1);
	delay_ms(3);
 }
 }

void Print_float_LED(float n,u8 x)//输出小数(有效数字不超过6位)到6位数码管,保留x(0-3)位小数
{
 u8 prtstr[10];
 switch(x)
 {
 case 0:sprintf(prtstr,"%.0f",n);break;
 case 1:sprintf(prtstr,"%.1f",n);break;
 case 2:sprintf(prtstr,"%.2f",n);break;
 case 3:sprintf(prtstr,"%.3f",n);break;
 } 
 Print_str_LED(prtstr);

}
main函数实现:

#include <reg51.h>
#include <config.h>
#include <stdio.h>
#include <1602.h>
#include <shumaguan.h>
#include <uart.h>
#include <ds18b20.h>
#include <12864.h>
#define	N 25
  float n;
sbit FM=P2^3;
//u8 print[N];//输出缓冲区
//u8 print2[N];//输出缓冲区
//sbit SW=P1^0;
sbit RL=P2^0;
int k=0;
void delay_ms(u16 x)//毫秒延时函数
{u16 i,j;
for(i=0;i<x;i++)
    for(j=0;j<115;j++);
}


void main()
{
	// unsigned int  kk;
    
      u8 i,j;
	 FM=1;
	 TMOD=0X10;
	 TL0=(8192-1000)%32;
	 TH0=(8192-1000)/32;
	 TL1=(65536-10000)%256;
	 TH1=(65536-10000)/256;
	 EA=1; //总中断
	 IT0=1;	// 外部中断0为1下降触发
	 IT1=1;//外部中断1为电平触发方式
	 EX0=1;//  外部中断0允许
	// EX1=1;	//	外部中断1允许
	 ET0=1;//	定时、计数器T0允许
	// ET1=1;	 //	定时,计数T1允许
	 TR0=0;//TR0=1启动定时器工作
 
 //init_com(); //串口初始化
//LCD1602_Init(); //1602初始化
//lcd12864_init();//12864初始化
 while(1)
 {    
	//kk=SW;
	//RL=kk;
      tempchange();	//启动温度变换
      n=get_temp();  //读取温度
	 for(i=50;i>0;i--)	  print_float_LED(n,2);	//输出到数码管  
	 if(n>=15&&n<=45)
	 {
		// SW=1;
		 RL=0;
		 TR0=1;//报警
		
	 }
	 else
	 {
		// SW=0;
		 RL=1;
		 TR0=0;//不报警
		 
	//  sprintf(print,"Temp: %.1f",n); print_str_uart(print);delay_ms(800);//输出到串口
	//	  sprintf(print,"Temp: %.1f",n);LCD1602pos(0,0); LCD1602disstr(print); delay_ms(800); //输出到1602
	//     sprintf(print,"温度:%.1f",n);
	  //i=0;while(i<6){print2[i]=print[i];i++;}
	  //j=6;while(print[i]){print2[j]=0xa3;j++;print2[j]=print[i]+0x80;i++;j++;} print2[j]='\0';	 //半角转全角
	  //lcd12864_pos(0,0);LCD12864disp(print2); delay_ms(800);//输出到12864
	 // sprintf(print2,"温度:%.1f",n);
	}
}
}
void time0() interrupt 1//发声中断  
{
	
	TL0=(6500)%32;
	TH0=(6500)/32;
	FM=~FM;
   
}

 五、效果实现及总结

达到了预期实验效果,使用51单片机控制DS18B20温度传感器检测热水器水温,并将水温值显示在八段数码管显示模块上,当温度处于35-45度之间时绿灯亮,否则红灯亮,并且蜂鸣器发出报警声。不足之处各位码友多多指教,多多关注互相交流。

 

猜你喜欢

转载自blog.csdn.net/qq_37037348/article/details/86558205