17_DS18B20温度传感器

发布时间 2023-11-30 15:10:46作者: 爱吃冰激凌的黄某某

DS18B20温度传感器

介绍

image-20231119202941485

引脚及应用电路

image-20231119203400784

原理图

image-20231121194656170

内部结构框图

image-20231119203451129

存储器结构

image-20231120140220081

单总线介绍

image-20231120140737757

单总线电路规范

image-20231120141054513

单总线时序结构

image-20231120143507866

image-20231120173206417

image-20231121132932880

DS18B20操作流程

image-20231121133111096

DS18B20数据帧

image-20231121133626763

温度存储格式

image-20231121133931641

获取温度用LCD显示

OneWire.c

#include <REGX52.H>
#include <intrins.h>

sbit OneWire_DQ=P3^7;

void Delay500us(void)	//@12.000MHz
{
	unsigned char data i;

	_nop_();
	i = 247;
	while (--i);
}

void Delay70us(void)	//@12.000MHz
{
	unsigned char data i;

	_nop_();
	i = 32;
	while (--i);
}

void Delay10us(void)	//@12.000MHz
{
	unsigned char data i;

	_nop_();
	i = 2;
	while (--i);
}

void Delay50us(void)	//@12.000MHz
{
	unsigned char data i;

	_nop_();
	i = 22;
	while (--i);
}

void Delay5us(void)	//@12.000MHz
{
	_nop_();
}

unsigned char OneWire_Init()
{
	bit AckBit;
	OneWire_DQ=1;
	OneWire_DQ=0;
	Delay500us();
	OneWire_DQ=1;
	Delay70us();
	AckBit=OneWire_DQ;
	Delay500us();
	return AckBit;
}

void OneWire_SendBit(unsigned char Bit)
{
	OneWire_DQ=0;
	Delay10us();
	OneWire_DQ=Bit;
	Delay50us();
	OneWire_DQ=1;
}

unsigned char OneWrie_ReceiveBit()
{
	unsigned char Bit;
	OneWire_DQ=0;
	Delay5us();
	OneWire_DQ=1;
	Delay5us();
	Bit=OneWire_DQ;
	Delay50us();
	return Bit;
}

void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		OneWire_SendBit(Byte&(0x01<<i));
	}
}

unsigned char OneWire_ReceiveByte()
{
	unsigned char i;
	unsigned char Byte=0x00;
	for(i=0;i<8;i++)
	{
		if(OneWrie_ReceiveBit())
		{
			Byte|=(0x01<<i);
		}
	}
	return Byte;
}

OneWire.h

#ifndef __ONEWIRE_H__
#define __ONEWIRE_H__

unsigned char OneWire_Init();
void OneWire_SendBit(unsigned char Bit);
unsigned char OneWrie_ReceiveBit();
void OneWire_SendByte(unsigned char Byte);
unsigned char OneWire_ReceiveByte();

#endif

DS18B20.c

#include <REGX52.H>
#include "OneWire.h"

#define DS18B20_SKIP_ROM 			0xCC
#define DS18B20_CONVERT_T 			0x44
#define DS18B20_READ_SCRATCHPAD		0xBE

void DS18B20_ConvertT()
{
	OneWire_Init();
	OneWire_SendByte(DS18B20_SKIP_ROM);
	OneWire_SendByte(DS18B20_CONVERT_T);
}

float DS18B20_ReadT()
{
	unsigned char TLSB,TMSB;
	int Temp;
	float T;
	OneWire_Init();
	OneWire_SendByte(DS18B20_SKIP_ROM);
	OneWire_SendByte(DS18B20_READ_SCRATCHPAD);
	TLSB=OneWire_ReceiveByte();
	TMSB=OneWire_ReceiveByte();
	Temp=(TMSB<<8)|TLSB;
	T=Temp/16.0;
	return T;
}

DS18B20.h

#ifndef __DS18B20_H__
#define __DS18B20_H__

void DS18B20_ConvertT();
float DS18B20_ReadT();

#endif

main.c

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "OneWire.h"
#include "DS18B20.h"

float T;

void main()
{
	DS18B20_ConvertT();
	Delay(1000);
	LCD_Init();
	LCD_ShowString(1,1,"Temperature:");
	while(1)
	{
		DS18B20_ConvertT();
		T=DS18B20_ReadT();
		if(T<0)
		{
			LCD_ShowChar(2,1,'-');
			T=-T;
		}
		else
		{
			LCD_ShowChar(2,1,'+');
		}
		LCD_ShowNum(2,2,T,3);
		LCD_ShowChar(2,5,'.');
		LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);
	}
}

运行效果

image-20231123152036530

温度报警器

Key.c

#include <REGX52.H>
#include "Delay.h"

unsigned char Key_KeyNumber;

unsigned char Key()
{
	unsigned char Temp;
	Temp=Key_KeyNumber;
	Key_KeyNumber=0;
	return Temp;
}

unsigned char Key_GetState()
{
	unsigned char KeyNumber=0;
	if(P3_1==0){KeyNumber=1;}
	if(P3_0==0){KeyNumber=2;}
	if(P3_2==0){KeyNumber=3;}
	if(P3_3==0){KeyNumber=4;}
	return KeyNumber;
}

void Key_Loop()
{
	static unsigned char NowState,LastState;
	LastState=NowState;
	NowState=Key_GetState();
	
	if(NowState==0)
	{
		switch(LastState) //按下后松手
		{
			case 1:Key_KeyNumber=1;break;
			case 2:Key_KeyNumber=2;break;
			case 3:Key_KeyNumber=3;break;
			case 4:Key_KeyNumber=4;break;
		}
	}
}

Key.h

#ifndef __KEY_H__
#define __KEY_H__


unsigned char Key();
unsigned char Key_GetState();
void Key_Loop();

#endif

OneWire.c

#include <REGX52.H>
#include <intrins.h>

sbit OneWire_DQ=P3^7;

void Delay500us(void)	//@12.000MHz
{
	unsigned char data i;

	_nop_();
	i = 247;
	while (--i);
}

void Delay70us(void)	//@12.000MHz
{
	unsigned char data i;

	_nop_();
	i = 32;
	while (--i);
}

void Delay10us(void)	//@12.000MHz
{
	unsigned char data i;

	_nop_();
	i = 2;
	while (--i);
}

void Delay50us(void)	//@12.000MHz
{
	unsigned char data i;

	_nop_();
	i = 22;
	while (--i);
}

void Delay5us(void)	//@12.000MHz
{
	_nop_();
}

unsigned char OneWire_Init()
{
	bit AckBit;
	EA=0;
	OneWire_DQ=1;
	OneWire_DQ=0;
	Delay500us();
	OneWire_DQ=1;
	Delay70us();
	AckBit=OneWire_DQ;
	Delay500us();
	EA=1;
	return AckBit;
}

void OneWire_SendBit(unsigned char Bit)
{
	EA=0;
	OneWire_DQ=0;
	Delay10us();
	OneWire_DQ=Bit;
	Delay50us();
	OneWire_DQ=1;
	EA=1;
}

unsigned char OneWrie_ReceiveBit()
{
	unsigned char Bit;
	EA=0;
	OneWire_DQ=0;
	Delay5us();
	OneWire_DQ=1;
	Delay5us();
	Bit=OneWire_DQ;
	Delay50us();
	EA=1;
	return Bit;
}

void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		OneWire_SendBit(Byte&(0x01<<i));
	}
}

unsigned char OneWire_ReceiveByte()
{
	unsigned char i;
	unsigned char Byte=0x00;
	for(i=0;i<8;i++)
	{
		if(OneWrie_ReceiveBit())
		{
			Byte|=(0x01<<i);
		}
	}
	return Byte;
}

OneWire.h

#ifndef __ONEWIRE_H__
#define __ONEWIRE_H__

unsigned char OneWire_Init();
void OneWire_SendBit(unsigned char Bit);
unsigned char OneWrie_ReceiveBit();
void OneWire_SendByte(unsigned char Byte);
unsigned char OneWire_ReceiveByte();

#endif

DS18B20.c

#include <REGX52.H>
#include "OneWire.h"

#define DS18B20_SKIP_ROM 			0xCC
#define DS18B20_CONVERT_T 			0x44
#define DS18B20_READ_SCRATCHPAD		0xBE

void DS18B20_ConvertT()
{
	OneWire_Init();
	OneWire_SendByte(DS18B20_SKIP_ROM);
	OneWire_SendByte(DS18B20_CONVERT_T);
}

float DS18B20_ReadT()
{
	unsigned char TLSB,TMSB;
	int Temp;
	float T;
	OneWire_Init();
	OneWire_SendByte(DS18B20_SKIP_ROM);
	OneWire_SendByte(DS18B20_READ_SCRATCHPAD);
	TLSB=OneWire_ReceiveByte();
	TMSB=OneWire_ReceiveByte();
	Temp=(TMSB<<8)|TLSB;
	T=Temp/16.0;
	return T;
}

Ds18B20.h

#ifndef __DS18B20_H__
#define __DS18B20_H__

void DS18B20_ConvertT();
float DS18B20_ReadT();

#endif

main.c

#include <REGX52.H>
#include "DS18B20.h"
#include "LCD1602.h"
#include "Delay.h"
#include "Key.h"
#include "AT24C02.h"
#include "Timer0.h"

float T;
char TLow=-15,THigh=20;
unsigned char KeyNum;

void main()
{
	LCD_Init();
	Timer0_Init();
	LCD_ShowString(1,1,"T:");
	LCD_ShowString(2,1,"TH:");
	LCD_ShowString(2,9,"TL:");
	DS18B20_ConvertT();
	Delay(1000);
	THigh=AT24C02_ReadByte(0);
	TLow=AT24C02_ReadByte(1);
	if(THigh>125 || TLow<-55 || THigh<=TLow)
	{
		THigh=20;
		TLow=-15;
	}
	while(1)
	{
		//温度读取及显示
		DS18B20_ConvertT();
		T=DS18B20_ReadT();
		LCD_ShowSignedNum(1,3,T,3);
		LCD_ShowChar(1,7,'.');
		
		if(T<0)
		{
			LCD_ShowNum(1,8,(unsigned int)(-T*100)%100,2);
		}
		else
		{
			LCD_ShowNum(1,8,(unsigned int)(T*100)%100,2);
		}
		
		//阈值判断及显示
		KeyNum=Key();
		switch(KeyNum)
		{
			case 1:
				THigh++;
				if(THigh>125)
				{
					THigh=125;
				}
				break;
			case 2:
				if(THigh>TLow+1)
				{
					THigh--;
				}
				break;
			case 3:
				if(TLow<THigh-1)
				{
					TLow++;
				}
				break;
			case 4:
				TLow--;
				if(TLow<-55)
				{
					TLow=-55;
				}
				break;
		}
		LCD_ShowSignedNum(2,4,THigh,3);
		LCD_ShowSignedNum(2,12,TLow,3);
		AT24C02_WriteByte(0,THigh);
		Delay(5);
		AT24C02_WriteByte(1,TLow);
		Delay(5);
		if(T>THigh)
		{
			LCD_ShowString(1,13,"OV:H");
		}
		else if(T<TLow)
		{
			LCD_ShowString(1,13,"OV:L");
		}
		else
		{
			LCD_ShowString(1,13,"    ");
		}
	}
}

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;
	TH0 = 0xFC;
	T0Count++;
	if(T0Count>=20)
	{
		T0Count=0;
		Key_Loop();
		
	}
}

运行效果

image-20231124135050568