基于stc15芯片的温度传感器DS18B20的使用

/***************************************************
	File name:						温度传感器DS18B20的使用
	Main Function:				通过温度传感器DS18B20检测温度,
												转换后上传至串口助手
	Last modified Date:  	2017-10-28
	Created by:          	Zhang Zhihao
****************************************************/

#ifndef _DS18B20_H
#define _DS18B20_H

#include<STC15W4K.h>

#define uchar unsigned char
#define uint  unsigned int

sbit DQ = P3^7;			//DS1820数据线IO口
bit nflag;				  //温度正负标志
sbit test = P5^5;

/*****************************************************
	延时函数:延时1us
******************************************************/
void delayus(uint i)
{
	while(i--);
}

/*****************************************************
	功能:			延时,最小单位为ms(晶振为11.0592
	计算方法:一个for循环 = 8个指令周期 = 8*12个机器周期
						= 8*12*1/11.0592 = 0.0086ms
						xms = 0.0086 * 110 = 0.946 ms
******************************************************/
void delayms(uint xms)
{
	uint i,j;
	for(i=xms;i>0;i--)			
		for(j=110;j>0;j--);
}

/*****************************************************
	DS18B20复位函数:
	1 数据线拉低,延时480us
	2 数据线拉高,延时480us
******************************************************/
void ds1820rst()	    
{

	DQ = 1;			  	//初始状态
	delayus(4);   	
	DQ = 0;			  	//拉低
	delayus(480); 	//延时480us
	DQ = 1;			  	//拉高
	delayus(480);  
}


/****************************************************
	18b20读数据:由低位到高位,重复八次,读一个字节
	1 数据线拉低,延时4us
	2 数据线拉高,延时10us
	3 读数据线状态一位,处理数据,延时45us
	4 重复步骤1-3
*****************************************************/
uchar ds1820rd()
{
	uchar i = 0;
	uchar dat = 0;
	for(i=8;i>0;i--)
	{
		DQ = 0; 		//拉低数据线
		delayus(4);
		dat>>=1;		//空出第一位
		DQ = 1; 		//拉高数据线
		delayus(10);
		if(DQ)  		//若为高电平,则最高位置一
			dat|=0x80;
		delayus(45);//延时45us
	}
	return(dat);
}


/**************************************************
	18b20写数据:由低位到高位,重复八次,写一个字节
	1 数据线拉低,延时15us
	2 送一位数据到数据线,延时60us
	3 数据线拉高
	4 重复步骤1-3
**************************************************/
void ds1820wr(uchar wdata)
{
	uchar i = 0;
	for (i=8; i>0; i--)
	{
		DQ = 0;			 		 //数据线拉低
		delayus(15);
		DQ = wdata&0x01; //将数据最低位送入数据线
		delayus(60); 		 //延时10us
		DQ = 1;			 		 //数据线拉高
		wdata>>=1;		 	 //字节右移一位
	}
}


/*****************************************************
	读温度并转换,根据RAM命令表写命令
		0xcc:				不读取序列地址
		0x44:				启动温度转换
		0xbe:				读取温度
******************************************************/
uint read_temp()   
{
	uchar TL,TH;										//TL:低八位 TH:高八位
	uchar wd;												//最终温度的绝对值
	
	ds1820rst();   		 							//先复位
	ds1820wr(0xcc);		  						//不读取64位地址,因为总线上只有一个DB1820,单片工作
	ds1820wr(0x44);		 						  //启动温度转换
	
	delayus(125);
	
	ds1820rst();
	ds1820wr(0xcc);		  						//跳过读序列号
	ds1820wr(0xbe);		  						//读取温度
	
	TL = ds1820rd();								//读低八位
	TH = ds1820rd();								//读高八位
	
	wd = TL/16+TH*16;
//	tvalue = TH;   		  						//tvalue为16位
//	tvalue = (tvalue<<8)+TL;
//	if((tvalue&0xf800) == 0xf800)		//判断负温度
//	{
//		tvalue=~tvalue+1;		 					//补码=反码+1
//		nflag = 0;										//置标志位为0
//	}
//	else
//		nflag = 1;
//	
//	wd = tvalue*0.625;							//计算温度值
	return(wd);											//返回温度值
}


/*****************************************************
	串口初始化函数:
******************************************************/
void init()
{				
	P1M0 = 0;P1M1 = 0;
	SCON = 0x40;
	T2L	 = 0xe0;
	T2H	 = 0xfe;
	AUXR = 0x14;
	AUXR |= 0x01;
	TI = 1;
}


/*****************************************************
	串口通讯函数:发送两个字节,首字节为正负标志位,
								第二个字节为温度值
******************************************************/
void comm(uchar temper)
{

//	while(!TI == 1);
//	{
//		TI = 0;
//		SBUF = nflag;
//	}
	while(!TI == 1);
	{
		TI = 0;
		SBUF = temper;
	}
}


#endif


#include "function.h"

void main()
{
	uchar temp;						//临时变量存储温度
	init();								//串口的初始化
	test = 0;							//蓝色的led,测试使用
	while(1)
	{
		temp=read_temp();		//读取温度
		delayms(500);				//延时0.5s
		comm(temp);					//发送至上位机
	}
} 


猜你喜欢

转载自blog.csdn.net/qq_24282081/article/details/78410294