51单片机个人学习笔记12(DS18D20温度传感器)

前言

本篇文章属于STC89C52单片机(以下简称单片机)的学习笔记,来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记,只能做参考,细节方面建议观看视频,肯定受益匪浅。

[1-1] 课程简介_哔哩哔哩_bilibili

一、 DS18B20介绍

简单介绍

DS18B20内部集成了模拟温度传感器,只需读取数字信号即可。

 引脚及应用电路

  

R1为上拉电阻 

 内部结构框图

存储器结构 

二、单总线介绍 

简单介绍

单总线电路规范 

 上面的电路是没有采用寄生供电的电路,下面的电路是采用了寄生供电的电路。

单总线的时序结构 

从机复位+主机判断从机是否响应 

发送一位 

 从机最终读到的就是总线当前所处的电平

接受一位 

从机随时会因为自身原因把总线释放掉,所以总机要及时读取数据 

发送和接受一个字节

注意:发送和接受都是低位在前,而I2C总线是高位在前 

三、DS18B20操作流程 

基本流程和一系列指令

DS18B20数据帧 

 温度存储格式

高位的前五位是符号位,全0表示正数,全1表示负数,低位的后四位是存储小数的位。

负数在计算机中是以补码的形式存储的。 

四、实例一(DS18B20温度读取) 

主要分为三个模块OneWire.c和DS18B20.c和main.c

OneWire.c

#include <REGX52.H>

sbit OneWire_DQ=P3^7;

unsigned char OneWire_Init(void)
{
	unsigned char i;
	unsigned char Ackbit;
	OneWire_DQ=1;
	OneWire_DQ=0;	
	i = 227;while (--i);		//Delay 500us
	OneWire_DQ=1;
	i = 29;while (--i);			//Delay 70us
	Ackbit=OneWire_DQ;
	i = 227;while (--i);		//Delay 500us
	return Ackbit;
}

void OneWire_SendBit(unsigned char Bit)
{
	unsigned char i;
	OneWire_DQ=0;
	i = 4;while (--i);			//Delay 10us
	OneWire_DQ=Bit;
	i = 27;while (--i);			//Delay 60us
	OneWire_DQ=1;
}

unsigned char OneWire_ReceiveBit(void)
{
	unsigned char i,Bit;
	OneWire_DQ=0;
	i = 2;while (--i);			//Delay 5us
	OneWire_DQ=1;
	i = 2;while (--i);			//Delay 5us
	Bit=OneWire_DQ;
	i = 27;while (--i);			//Delay 60us
	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(void)
{
	unsigned char i;
	unsigned char Byte=0x00;
	for (i=0;i<8;i++)
	{
		if(OneWire_ReceiveBit()) {Byte|=(0x01<<i);}
	}
	return Byte;
}

根据单总线的时序结构,写出单总线初始化,发送、接受一个比特位或一个字节的代码

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(void)
{
	OneWire_Init();
	OneWire_SendByte(DS18B20_SKIP_ROM);
	OneWire_SendByte(DS18B20_CONVERT_T);
}

float DS18B20_ReadT(void)
{
	unsigned char TLSB,TMSB;
	int Temp;
	float T;
	OneWire_Init();
	OneWire_SendByte(DS18B20_SKIP_ROM);
	OneWire_SendByte(DS18B20_READ_SCRATCHPAD);
	TLSB=OneWire_ReceiveByte();     //温度的低8位
	TMSB=OneWire_ReceiveByte();     //温度的高8位
	Temp=(TMSB<<8)|TLSB;            //合起来变为16位
	T=Temp/16.0;                    //最低位的位权是2的-4次方,所以要转换一下
	return T;
}

DS18B20_SKIP_ROM是ROM指令,DS18B20_CONVERT_T和DS18B20_READ_SCRATCHPAD是功能指令,两个函数分别位温度转换和温度读取

 main.c

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

float T;

void main()
{
	DS18B20_ConvertT();        //上电先进行温度转换
	Delay(1000);                //延时1s,等待温度转换完成
	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);        //小数部分
	}
}

注意,上电后先进行温度转换,不然刚开始显示的是初始值85摄氏度,这时温度还没有转换好

五、实例二(DS18B20温度报警器) 

主要是main.c模块 

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

float T,TShow;
char THigh,TLow;
unsigned char KeyNum;

void main()
{
		DS18B20_ConvertT();
		Delay(1000);
		THigh=AT24C02_ReadByte(0);
		TLow=AT24C02_ReadByte(1);
		if(THigh>125 || TLow<-55 || THigh<=TLow)
		{
			THigh=20;
			TLow=10;
		}
		LCD_Init();
		LCD_ShowString(1,1,"T:");
		LCD_ShowString(2,1,"TH:");
		LCD_ShowString(2,9,"TL:");
		LCD_ShowSignedNum(2,4,THigh,3);
		LCD_ShowSignedNum(2,12,TLow,3);
		while(1)
		{	
			/*温度读取及显示*/
			DS18B20_ConvertT();
			T=DS18B20_ReadT();
			if(T<0)
			{
				LCD_ShowChar(1,3,'-');
				TShow=-T;
			}
			else
			{
				LCD_ShowChar(1,3,'+');
				TShow=T;
			}
			LCD_ShowNum(1,4,TShow,3);
			LCD_ShowChar(1,7,'.');
			LCD_ShowNum(1,8,(unsigned long)(TShow*100)%100,2);
			
			/*阈值判断及显示*/
			KeyNum=Key();
			if(KeyNum)
			{
				if(KeyNum==1)
				{
					THigh++;
					if(THigh>125){THigh=125;}
				}
				if(KeyNum==2)
				{
					THigh--;
					if(THigh<=TLow){THigh++;}
				}
				if(KeyNum==3)
				{
					TLow++;
					if(TLow>=THigh){TLow--;}
				}
				if(KeyNum==4)
				{
					TLow--;
					if(TLow<-55){TLow=-55;}
				}
				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,"    ");				
			}
		}
}
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值