51单片机 DS18B20温度传感器的使用

说明
平台:Windows 10教育版64位
工具:普中科技 HC6800-ES V2.0,keil uVision2

原理

B站视频(里面详细讲有,代码怎么写):
温度传感器使用原理
文档:普中科技官方文档

重点

对于单片机来说,知道I/O口以及他们的工作方式,就很容易能编写出代码来控制他们按照自己的意愿来行动。

对于温度传感器来说,最重要的是要根据时序来写代码,按照时序来写代码就能很轻松的实现功能。对于我个人而言,在看到普中科技的官方文档的长篇解释的时候,我内心是有一种抵触感去看它的,它的长度给我一种很难和很麻烦的感觉。但事实上并没有我想的那么难,如果不想看这么长的文字,建议可以去B站看视频,里面讲的还是挺详细的。

工作时序

一、初始化

在这里要对温度传感器的个数和好坏进行检测,因为开发板只有一个温度传感器,所以就只检测温度传感器是否是好的就可以了。

51单片机 DS18B20温度传感器的使用_第1张图片

二、写数据

51单片机 DS18B20温度传感器的使用_第2张图片

三、读数据

51单片机 DS18B20温度传感器的使用_第3张图片
这里添加一个数据转换的原理:
51单片机 DS18B20温度传感器的使用_第4张图片

步骤

1.初始化
2.写入温度转换指令
3.写入读取温度指令
4.保存读取出来的数据
5.对读取出来的数据进行处理
6.显示

代码

#include
#define uchar unsigned char

sbit temperature = P3^7;	//温度传感器接口
sbit LSA = P2^2;	//数码管位选
sbit LSB = P2^3;
sbit LSC = P2^4;
uchar Data_dis[6];	//温度各个位数,包括负号
uchar code number[] = 
{
	0x3f,0x06,0x5b,0x4f,
	0x66,0x6d,0x7d,0x07,
	0x7f,0x6f,0x77,0x7c,
	0x39,0x5e,0x79,0x71
};	//数码管显示0F的数组
void delay1ms(uchar );
uchar init();
void WriteByte(uchar );
uchar ReadByte();
void TransformTemperature();
void ReadTemperatureCom();
int ReadTemperature();
void dataprocess(int );
void DigDisplay();

void main()
{
	init();
	delay1ms(1);
	while(1)
	{
		dataprocess(ReadTemperature());
		DigDisplay();		
	}
}

void delay1ms(uchar t)
{
	uchar t1;
	for(;t>0;t--)
		for(t1 = 110;t1>0;t1--);
}

uchar init()
{
	uchar i = 70;
	temperature = 0;	//数据线拉低
	while(i--);	//延时642us
	temperature = 1;	//数据线拉高
	i = 0;

//检测温度传感器是否存在
	while(temperature)	
	{
		delay1ms(1);
		i++;
		if(i>5)
		{
			return 0;	//等待5ms后认为不能用,返回0
		}
	}
	return 1;	//存在返回1
}
void WriteByte(uchar dat)
{
	uchar i,j;
	for(j=8;j>0;j--)
	{//串行传输,每次只传输1位
		temperature = 0;	//数据线拉低
		i++;	//用执行指令的方式延时
		temperature = dat&0x01;	//取最后一位
		i = 6;
		while(i--);	//延时68us
		dat = dat >> 1;	
	}
}

uchar ReadByte()
{
	uchar i,j;
	uchar b,byte;
	for(j = 8;j>0;j--)
	{	
		temperature = 0;
		i++;	//延时
		temperature = 1;
		i++;	//延时
		i++;
		b = temperature;
		byte = (byte >> 1)|(b << 7);
		i = 4;	//延时
		while(i--);	
	}	
	return byte;
}
void TransformTemperature()
{
/*	init();
	delay1ms(1);*/
	WriteByte(0xcc);	//跳过指令,因为只有一个从机
	WriteByte(0x44);	//温度转换指令
}

void ReadTemperatureCom()
{
/*	init();
	delay1ms(1);*/
	WriteByte(0xcc);	//跳过指令,因为只有一个从机
	WriteByte(0xbe);	//读取温度指令
}
int ReadTemperature()
{
	int temp;	//16位
	uchar tempH,tempL;	//8位
	TransformTemperature();
	ReadTemperatureCom();
	tempH = ReadByte();
	tempL = ReadByte();
	temp = tempH;
	temp <<= 8;
	temp |= tempL;
	return temp;	
}
void dataprocess(int temp)
{
	float tp;
	if(temp<0)
	{
		Data_dis[0] = 0x40;	//负号
		temp = temp -1;
		temp = ~temp;
		tp = temp;
		temp = tp*0.0625*100+0.5;
	}
	else
	{
		Data_dis[0] = 0;
		tp = temp;
		temp = tp*0.0625*100+0.5;
	}
		//分离各个位数以便于在数码管显示
		Data_dis[1] = number[temp/10000];
		Data_dis[2] = number[temp%10000/1000];
		Data_dis[3] = number[temp%10000%1000/100] |0x80;
		Data_dis[4] = number[temp%100/10];
		Data_dis[5] = number[temp%100%10];
}
void DigDisplay()
{
	uchar i;
	for(i = 0;i<6;i++)
	{
		switch(i)
		{	//通过高速刷新的方式让多个数码管同时显示数据
			case 0 : 
				LSA = 0;LSB = 0;LSC = 0;break;
			case 1 : 
				LSA = 1;LSB = 0;LSC = 0;break;
			case 2 : 
				LSA = 0;LSB = 1;LSC = 0;break;
			case 3 : 
				LSA = 1;LSB = 1;LSC = 0;break;
			case 4 : 
				LSA = 0;LSB = 0;LSC = 1;break;
			case 5 : 
				LSA = 1;LSB = 0;LSC = 1;break;
		}
		P0 = Data_dis[5-i];
		delay1ms(1);
		P0 = 0X00;	//消影
	}	
}

你可能感兴趣的:(51单片机)