51综合程序02-温度传感器

温度传感器

一、温度传感器DS18B20

DS18B20介绍

DS18B20是一款数字温度传感器,是一种高精度、数字输出的温度传感器,被广泛用于各种应用场景,特别是需要测量温度并将数据数字化输出的情况。

以下是DS18B20的一些主要特点和特性:

  1. 数字输出: DS18B20以数字形式输出温度数据,使用1-Wire总线协议进行通信,这使得多个DS18B20传感器可以通过同一根总线进行连接。

  2. 高精度: DS18B20提供高精度的温度测量,通常在±0.5摄氏度范围内。这使得它适用于对温度精度要求较高的应用。

  3. 范围广泛: DS18B20的温度测量范围较广,通常在-55摄氏度到+125摄氏度之间。

  4. 电源和信号共用: 这个传感器通过单一的数据线同时提供电源和传输温度数据,使其在布线上更为简单。

  5. 可编程分辨率: DS18B20允许用户选择不同的温度分辨率,以平衡精度和测量速度之间的需求。

  6. 防水版本: DS18B20也有防水版本,使其适用于需要在潮湿或液体环境中测量温度的应用。

DS18B20广泛应用于温度监测系统、气象站、家用电器、工业自动化等领域。由于其数字输出和方便的接口,它易于集成到各种数字系统中。

二、DS18B20驱动程序

芯片引脚连接图
在这里插入图片描述

DS18B20.h

#ifndef __DS18B20_H_
#define __DS18B20_H_


void Delay1ms(unsigned int y);  //1ms延时
void Delay480us();  //480us延时
unsigned char Ds18b20Init();	//初始化DS18B20
void Ds18b20WriteByte(unsigned char dat);	 //写字节
unsigned char Ds18b20ReadByte();   //读字节
void  Ds18b20ChangTemp();   //温度转换
void  Ds18b20ReadTempCom();  //发送读取温度命令
int Ds18b20ReadTemp();	 //读取温度


#endif

DS18B20.c

#include "DS18B20.h"

sbit DQ=P3^7;

/*1ms延时*/
void Delay1ms(unsigned int y)	
{
	unsigned int x;
	for( ; y>0; y--)
	{
		for(x=110; x>0; x--);
	}
}

/*480us延时*///@11.0592MHz
void Delay480us()		
{
	unsigned char i, j;
	i = 6;
	j = 38;
	do
	{
		while (--j);
	} while (--i);
}

/*DS18B20初始化*/
unsigned char Ds18b20Init()   
{
	DQ = 0;	//将总线拉低480us~960us
	Delay480us();   //480us的延时
	DQ = 1;			//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
	while(DQ)	//等待DS18B20拉低总线
	{
		Delay1ms(5);
		if(DQ==1)//等待>5MS
		{
			return 0;//初始化失败
		}
	}
	return 1;//初始化成功
}

/*写字节函数*/
void Ds18b20WriteByte(unsigned char dat)   
{
	unsigned char i,j;
	for(j=0; j<8; j++)
	{
		DQ = 0;	     	  //每写入一位数据之前先把总线拉低1us
		i++;
		DQ = dat & 0x01;  //然后写入一个数据,从最低位开始
		i=6;
		while(i--); //延时68us,持续时间最少60us
		DQ = 1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
		dat >>= 1;
	}
}

/*读取字节函数*/
unsigned char Ds18b20ReadByte()	  
{
	unsigned char byte, bi;
	unsigned int i, j;	
	for(j=8; j>0; j--)
	{
		DQ = 0;//先将总线拉低1us
		i++;
		DQ = 1;//然后释放总线
		i++;
		i++;//延时6us等待数据稳定
		bi = DQ;	 //读取数据,从最低位开始读取
		/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
		byte = (byte >> 1) | (bi << 7);						  
		i = 4;		//读取完之后等待48us再接着读取下一个数
		while(i--);
	}				
	return byte;
}

/*让18b20开始转换温度*/
void  Ds18b20ChangTemp()  
{
	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc);		//跳过ROM操作命令		 
	Ds18b20WriteByte(0x44);	    //温度转换命令 
}

/*发送读取温度命令*/
void  Ds18b20ReadTempCom()   
{	
	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc);	 //跳过ROM操作命令
	Ds18b20WriteByte(0xbe);	 //发送读取温度命令
}

/*读取温度*/
int Ds18b20ReadTemp()	 
{
	int temp = 0;
	unsigned char tmh, tml;
	Ds18b20ChangTemp();	//先写入转换命令
	Ds18b20ReadTempCom();  //然后等待转换完后发送读取温度命令
	tml = Ds18b20ReadByte();  //读取温度值共16位,先读低字节
	tmh = Ds18b20ReadByte();  //再读高字节
	temp = tmh;
	temp <<= 8;
	temp |= tml;
	return temp;
}

三、使用数码管显示

数码管电路引脚连接图
在这里插入图片描述

main.c

#include "reg51.h"			 
#include"DS18B20.h"	

sbit LSA=P2^2;   //数码管位选
sbit LSB=P2^3;
sbit LSC=P2^4;

unsigned char num=0;
unsigned char DisplayData[8];
unsigned char code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};	 //数码管段选

/*延时函数*/
void delay(unsigned int i)	  
{
	while(i--);	
}

/*温度读取处理转换函数*/	
void datapros(int temp)  
{
   	float tp;  
	if(temp<0)				//当温度值为负数
  	{
		DisplayData[0] = 0x40; 	  //   -
		temp=temp-1;
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;	
  	}
 	else
  	{			
		DisplayData[0] = 0x00;
		tp=temp;     //因为数据处理有小数点所以将温度赋给一个浮点型变量
		temp=tp*0.0625*100+0.5;	
	}
	DisplayData[1] = smgduan[temp/10000];
	DisplayData[2] = smgduan[temp/1000%10];
	DisplayData[3] = smgduan[temp/100%10] | 0x80;
	DisplayData[4] = smgduan[temp/10%10];
	DisplayData[5] = smgduan[temp % 10];
}

/*数码管显示函数*/
void DigDisplay()	 
{
	unsigned char i;
	for(i=0;i<6;i++)
	{
		switch(i)	 //位选,选择点亮的数码管,
		{
			case(0):
				LSA=0;LSB=0;LSC=0; break;//显示第0位
			case(1):
				LSA=1;LSB=0;LSC=0; break;//显示第1位
			case(2):
				LSA=0;LSB=1;LSC=0; break;//显示第2位
			case(3):
				LSA=1;LSB=1;LSC=0; break;//显示第3位
			case(4):
				LSA=0;LSB=0;LSC=1; break;//显示第4位
			case(5):
				LSA=1;LSB=0;LSC=1; break;//显示第5位	
		}
		P0=DisplayData[5-i];//发送数据
		delay(100); //间隔一段时间扫描	
		P0=0x00;//消隐
	}		
}

void main()
{	
	while(1)
	{
		datapros(Ds18b20ReadTemp());	 //数据处理函数
		DigDisplay();//数码管显示函数		
	}		
}

四、使用LCD1602显示

LCD1602电路引脚连接图
在这里插入图片描述

LCD1602.h

#ifndef __LCD1602_h
#define __LCD1602_h

#include<reg51.h>

void delay(unsigned int n);
void WriteStruction(unsigned char date);
void WriteData(unsigned char dat);
void LCDInitiate();


#endif

LCD1602.c

#include "LCD1602.h"


sbit RS=P2^6;  //寄存器选择位
sbit RW=P2^5;  //读写选择位
sbit EN=P2^7;  //使能信号位

/*延时函数*/
void delay(unsigned int n)	    
{
	int i,j;
	for (i=n;i>0;i--)
	for (j=10;j>0;j--);
}

/*LCD写指令函数*/
void WriteStruction(unsigned char date)	
{
	RS=0;	  //选择指令
	RW=0;	  //选择写入
	EN=0;	  //使能端初始化

	P0=date;  //写指令

	delay(1);
	EN=1;	    //写时序,置高电平
	delay(1);
	EN=0;	   //液晶屏出现由1到0的负跳变,使液晶模块开始工作
}

/*LCD写数据函数*/
void WriteData(unsigned char dat)  
{
	RS=1;	   //选择数据
	RW=0;	   //选择写入
	EN=0;	   //初始化使能端

	P0=dat;	   //写数据

	delay(1);
	EN=1;	   //写时序
	delay(1);
	EN=0;	   //液晶屏出现由1到0的负跳变,使液晶模块开始工作
}

/*LCD初始化函数*/
void LCDInitiate()    
{
	WriteStruction(0x38);  //功能设定指令,DL->8位   N->2行  F->5x7
	WriteStruction(0x0c);  //显示开关指令,DCB=100,整体显示,关光标,不闪烁
	WriteStruction(0x06);  //进入模式设置指令,设定输入方式,增量不移位	
	WriteStruction(0x01);  //清屏指令,清除屏幕显示
}

main.c

#include <reg51.h>			 
#include "DS18B20.h"	
#include "LCD1602.h"


unsigned DisplayData[8];
unsigned char code digit[]="0123456789";
unsigned char code D1[]="    Temp:        C";

/*延时函数*/
void delay_us(unsigned int i)	  
{
	while(i--);	
}

/*温度读取处理转换函数*/
void datapros(int temp) 	 
{
   	float tp;  
	if(temp<0)				//当温度值为负数
  	{
		WriteStruction(0x80+0x05);
		WriteData('-'); //   -
		temp=temp-1;
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;	
  	}
 	else
  	{			
		WriteStruction(0x80+0x05);
		WriteData('+');
		tp=temp;     //因为数据处理有小数点所以将温度赋给一个浮点型变量
		temp=tp*0.0625*100+0.5;	
	}
	DisplayData[1] = digit[temp/10000];
	DisplayData[2] = digit[temp/1000%10];
	DisplayData[3] = digit[temp/100%10];
	DisplayData[4] = digit[temp/10%10];
	DisplayData[5] = digit[temp % 10];
}

/*正确显示函数*/
void display_right()   
{
	unsigned char i;
	LCDInitiate();  

	WriteStruction(0x80+0x00);
	i=0;
	while(D1[i]!='\0')
	{
		WriteData(D1[i]);
		i++;	
	}
	WriteStruction(0x80+0x0c);
	WriteData(0xdf);
}

/*LCD1602显示温度*/
void display_temp()
{
	WriteStruction(0x80+0x06);
	WriteData(DisplayData[1]);

	WriteStruction(0x80+0x07);
	WriteData(DisplayData[2]);

	WriteStruction(0x80+0x08);
	WriteData(DisplayData[3]);

	WriteStruction(0x80+0x09);
	WriteData('.');

	WriteStruction(0x80+0x0a);
	WriteData(DisplayData[4]);

	WriteStruction(0x80+0x0b);
	WriteData(DisplayData[5]);
}

void main()
{
	display_right();	
	
	while(1)
	{
		datapros(Ds18b20ReadTemp());	 //数据处理函数
		display_temp();
		delay_us(1000);	
	}		
}

五、使用LCD12864显示

LCD12864电路引脚连接图
在这里插入图片描述
LCD12864.h

#ifndef __LCD12864_H
#define __LCD12864_H


# include <reg51.h>


/*接口定义模块*/
#define LCD12864_DATAPORT P0	  //数据IO口

sbit LCD12864_RS  =  P2^6;             //(数据命令)寄存器选择输入 
sbit LCD12864_RW  =  P2^5;             //液晶读/写控制
sbit LCD12864_EN  =  P2^7;             //液晶使能控制
sbit LCD12864_PSB =  P3^2;             //串/并方式控制
sbit LCD12864_RST =  P3^4;			   //复位端
	
	
/*函数声明模块*/
void LCD12864_Delay1ms(unsigned int c);	//延时函数		
void LCD12864_WriteCmd(unsigned char cmd);	//写指令函数
void LCD12864_WriteData(unsigned char dat);	//写数据函数
void LCD12864_Init();  //12864初始化函数					
void LCD12864_SetWindow(unsigned char x, unsigned char y);  //坐标函数


#endif

LCD12864.c

#include"lcd12864.h"


/*延时函数*/
void LCD12864_Delay1ms(unsigned int c)   
{
	unsigned int a,b;
	for(; c>0; c--)
	{
	    for(b=199; b>0; b--)
		{
	        for(a=1; a>0; a--);	
		}
	}
}

/*写指令函数*/
void LCD12864_WriteCmd(unsigned char cmd)	 
{	
	LCD12864_RS = 0;     //选择命令
	LCD12864_RW = 0;     //选择写入
	LCD12864_EN = 0;     //初始化使能端

	LCD12864_DATAPORT = cmd;   //放置数据

	LCD12864_EN = 1;		   //写时序
	LCD12864_Delay1ms(5);
	LCD12864_EN = 0;    					
}

/*写数据函数*/
void LCD12864_WriteData(unsigned char dat)	  
{
	LCD12864_RS = 1;     //选择数据
	LCD12864_RW = 0;     //选择写入
	LCD12864_EN = 0;     //初始化使能端

	LCD12864_DATAPORT = dat;   //放置数据

	LCD12864_EN = 1;		   //写时序
	LCD12864_Delay1ms(5);				   
	LCD12864_EN = 0;    								
}

/*初始化函数*/
void LCD12864_Init()	
{
	LCD12864_PSB = 1;	  //选择并行输入
	LCD12864_RST = 1;	  //复位
	LCD12864_WriteCmd(0x30);  //选择基本指令操作
	LCD12864_WriteCmd(0x0c);  //显示开,关光标
	LCD12864_WriteCmd(0x01);  //清除LCD12864的显示内容
}

/*在基本指令模式下设置显示坐标。注意:x是设置行,y是设置列*/
void LCD12864_SetWindow(unsigned char x, unsigned char y)	   
{
	unsigned char pos;

	if(x == 0)	   // 第一行的地址是80H
	{
		x = 0x80;
	}
		
	else if(x == 1)  //第二行的地址是90H
	{
		x = 0x90;	
	}
	
	else if(x == 2)  //第三行的地址是88H
	{
		x = 0x88;
	}
	
	else if(x == 3)
	{
		x = 0x98;
	}
	
	pos = x + y;
	LCD12864_WriteCmd(pos);
}

main.c

#include <reg51.h>			 
#include "DS18B20.h"	
#include "LCD12864.h"


unsigned DisplayData[8];
unsigned char code digit[]="0123456789";
unsigned char code D1[]="温度:           ";

void delay_us(unsigned int i)	  /*延时函数*/
{
	while(i--);	
}


/*温度读取处理转换函数*/
void datapros(int temp) 	 
{
   	float tp;  
	if(temp<0)				//当温度值为负数
  	{
		LCD12864_WriteCmd(0x80+0x00);
		LCD12864_WriteData('-'); //   -
		temp=temp-1;
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;	
  	}
 	else
  	{			
		LCD12864_WriteCmd(0x80+0x03);
		LCD12864_WriteData('+');
		tp=temp;     //因为数据处理有小数点所以将温度赋给一个浮点型变量
		temp=tp*0.0625*100+0.5;	
	}
	DisplayData[1] = digit[temp/10000];
	DisplayData[2] = digit[temp/1000%10];
	DisplayData[3] = digit[temp/100%10];
	DisplayData[4] = digit[temp/10%10];
	DisplayData[5] = digit[temp % 10];
}

/*正确显示函数*/
void display_right()   
{
	unsigned char i;
	LCD12864_Init();  

	LCD12864_SetWindow(0x80+0x00,0);
	i=0;
	while(D1[i]!='\0')
	{
		LCD12864_WriteData(D1[i]);
		i++;	
	}
}

void display_temp()
{
	LCD12864_WriteData(DisplayData[1]);
	LCD12864_WriteData(DisplayData[2]);
	LCD12864_WriteData(DisplayData[3]);
	LCD12864_WriteData('.');
	LCD12864_WriteData(DisplayData[4]);
	LCD12864_WriteData(DisplayData[5]);
	LCD12864_WriteData(' ');
	LCD12864_WriteData(0xa1);
	LCD12864_WriteData(0xe6);
}	

void main()
{
	display_right();	
	while(1)
	{
		datapros(Ds18b20ReadTemp());	 //数据处理函数
		display_temp();
		delay_us(1000);	
	}		
}
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值