壹拾玖:DS18B20的温度读取

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_17017545/article/details/82120467

DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。
1.DS18B20产品的特点
(1)自要求一个端口即可实现通信。
(2)在DS18B20中的每个器件都有独一无二的序列号。
(3)实际应用中不需要外部任何元器件即可实现测温。
(4)测量温度范围在-55℃到+125℃之间。
(5)数字温度计的分辨率用户可以从9位到12位选择。
(6)内部有温度上、下限告警设置。

由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。
DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序。
所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。
数据和命令的传输都是地位在线。

1、复位时序
这里写图片描述

2、写时序
对于DS18B20的写时序仍然分为写0时序和写1时序两个过程。对于DS18B20写0时序和写1时序的要求不同:
当要求写0时序时,单总线要被拉低至少60us,保证DS18B20能够在15us到45us之间能够正确地采用IO总线上的“0”电平;
当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。
这里写图片描述

3、读时序
对于DS18B20的读时序分为读0时序和读1时序两个过程。
对于DS18B20的读间隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。DS18B20在完成一个读时序过程,至少需要60us才能完成。

这里写图片描述
#4、操作程序

延时与复位实例

延时实例
复位实例

读位与写位实例

读位实例
写位实例

读字节与写字节实例

读字节实例
写字节实例

#实验
这里写图片描述

#代码

	
*   【课程20】 ****DS18B20温度的读取***********
*
*   【说  明】 ****
*		
*   【描  述】 ****读取环境温度
*
******************************************************************/ 
#include<reg51.h>  
#include <intrins.h>

//---------常用的两个宏定义-------------- 
#define uint8	unsigned char
#define uint16  unsigned int 

//--------1602的控制引脚定义-------------
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;

sbit DQ = P3^3;

//----------液晶模块的声明---------------
bit BUSY(void);
void Write_cmd(uint8 cmd);
void Write_dat(uint8 dat);
void LCD_Init(void);

//---------DS18B20的函数声明-----------
void DelayUs(uint16 time);
void Init_Ds18b20(void);
void WriteByte(uint8 date);
uint8 ReadTemperature(void);

//-----------函数的声明------------------
void DelayMS(uint16 dly);


//------------------------------------
void main(void)
{
	uint8 temp,temp1,temp2;
	LCD_Init();
	Init_Ds18b20();
	while(1)
	{
		temp = 	ReadTemperature();
		temp1 = temp/10;
		temp2 = temp%10;

		Write_cmd(0x80);
		Write_dat(temp1+0x30);
		Write_dat(temp2+0x30);
		Write_dat(0xdf);
		Write_dat(0x43);
		 		
	}
}



/********************************************************
** 名称 :void DelayMS(uint16 dly)
** 功能 :毫秒级延时(12M的晶振)
** 入口参数 :dly
					用户的延时参数   
** 出口参数 :无   
*********************************************************/
void DelayMS(uint16 dly)
{
	uint16 x,y;
	for(x=dly;x>0;x--)
		for(y=124;y>0;y--);
}

/********************************************************
** 名称 :bit BUSY(void)
** 功能 :检测LCD1602是否处于忙状态;
** 入口参数 :无   
** 出口参数 :bit Bit
						返回1,则BUSY
						返回0,则OK   
*********************************************************/
bit BUSY(void)
{
	bit Bit;
	RS = 0;
	RW = 1;
	EN = 1;
	DelayMS(1);
	Bit = (bit)(P0 & 0x80);	//最高位为忙信号位	
	EN = 0;
	return Bit;				
}

/********************************************************
** 名称 :void Write_cmd(uint8 cmd)
** 功能 :写命令
** 入口参数 :cmd
					控制命令   
** 出口参数 :无   
*********************************************************/
void Write_cmd(uint8 cmd)
{
	while(BUSY());			//测忙
	RS = 0;
	RW = 0;
	EN = 0;	
	P0 = cmd;
	EN = 1;
	DelayMS(1);
	EN = 0;			
}

/********************************************************
** 名称 :void Write_dat(uint8 dat)
** 功能 :写数据
** 入口参数 :dat
					要显示的数据  
** 出口参数 :无   
*********************************************************/
void Write_dat(uint8 dat)
{
	while(BUSY());			//测忙
	RS = 1;
	RW = 0;
	EN = 0;	
	P0 = dat;
	EN = 1;
	DelayMS(1);
	EN = 0;			
}

/********************************************************
** 名称 :void LCD_Init(void)
** 功能 :液晶的初始化
** 入口参数 :无 
** 出口参数 :无   
*********************************************************/
void LCD_Init(void)
{
	Write_cmd(0x38);			//功能设置
	DelayMS(1);
	Write_cmd(0x0c);			//显示开关控制
	DelayMS(1);
	Write_cmd(0x06);			//输入方式设置
	DelayMS(1);
	Write_cmd(0x01);			//清除LCD的显示内容
	DelayMS(1);
}

/**************************************
**Function Name:void DelayUs(uint time)
**Description:delay  US
**Input:Time
**Output:None
**Return: None
**************************************/
void DelayUs(uint16 time)
{
	while(time--);
}

/**************************************
**Function Name:void Init_Ds18b20(void)
**Description:DS18B20的初始化
**Input :None
**Output:None
**Return: None
**************************************/
void Init_Ds18b20(void)
{
	uint8 i;
	DQ=1;			//首先DQ是高电平
	DelayUs(15);		//延时,等DQ稳定
	DQ=0;			//拉低
	DelayUs(75);	//延时大概600US
	DQ=1;			//拉高(释放)
	DelayUs(15);		//15US左右
	i=DQ;			//开始采样
	DelayUs(7);		//延时		(这个延时在仿真时很重要)
//	return i		//返回0, 说明总线上有器件响应
					//返回1, 说明总线上没有器件响应
}

/**************************************
**Fuction Name:void WriteByte(uchar date)
**Description:写一个字节
**Input:Write Data Byte
**Output:None
**Return: None
**************************************/
void WriteByte(uint8 date)
{
	uint8 i;
	for(i=0;i<8;i++)
	{
		DQ=0;				
		DQ=date&0x01;
		DelayUs(7);
		DQ=1;
		date>>=1;	
	}
	DelayUs(7);	
}

/**************************************
**Function Name:uchar ReadByte(void)
**Description:读一个字节
**Input:None
**Output:Read Data Byte
**Return: Read Data Byte
**************************************/
uint8 ReadByte(void)
{
	uint8 i,value;
	for(i=0;i<8;i++)
	{
		DQ=0;
		value>>=1;
		DQ=1;
		if(DQ)
		{
			value|=0x80;	
		}
		DelayUs(7);	
	}
	return value;
}

/**************************************
**Function Name:uchar ReadTemperature(void)
**Description:读出温度值
**Input:None
**Output:Read Temperature
**Return: Read Temperature
**************************************/
uint8 ReadTemperature(void)
{
	uint8 a,b;
	Init_Ds18b20();			//初始化
	WriteByte(0xcc);		//跳过ROM
	WriteByte(0x44);		//启动转换
	DelayUs(350);
	
	Init_Ds18b20();		//初始化
	WriteByte(0xcc);	//跳过ROM
	WriteByte(0xbe);	//准备读取
	a=ReadByte();
	b=ReadByte();
	b<<=4;				//读温度的整数部分
	b+=(a&0xf0)>>4;
	return b;
				
}

猜你喜欢

转载自blog.csdn.net/qq_17017545/article/details/82120467