DS18B20温度传感器


一、介绍DS18B20

了解DS18B20

在这里插入图片描述

引脚及电路图

在这里插入图片描述
完整电路(引脚名称不同、功能一样)
在这里插入图片描述
在这里插入图片描述

内部结构框图

使用寄生电源时,由于上拉电阻电阻较大,需要给这个电源高电压(强上拉)才能使DS18B02工作,本次案例不用使用。

在这里插入图片描述

存储器结构

在这里插入图片描述

单总线(1 wire bus)介绍

在这里插入图片描述

单总线电路规范

在这里插入图片描述

单总线时序结构

初始化

在这里插入图片描述

发送一个数据

在这里插入图片描述

接收一位数据

在这里插入图片描述

发送一个字节与接收一个字节

在这里插入图片描述

DS18B20操作流程

在这里插入图片描述
在这里插入图片描述

所要使用的数据帧

在这里插入图片描述

温度存储格式

在这里插入图片描述
例子
在这里插入图片描述

二、实现温度检测

根据单总线时序结构配置初始化、写入数据、读取数据函数

OneWire.c

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

// 定义接口
sbit OneWire_IO = P3^7;
// 初始化单总线
unsigned char OneWire_Init(){
   
	unsigned char i,ACK;
	// 关闭中断,以免影响温度传感器读取数据(影响延时)
	EA = 0;
	OneWire_IO = 1;
	OneWire_IO = 0; // 把总线拉低
	_nop_();i = 227;while (--i);		// 延时500us
	OneWire_IO = 1;	// 释放总线
	_nop_();i = 29;while (--i);			// 延时70us
	ACK = OneWire_IO;	// 返回从机的响应
	_nop_();i = 227;while (--i);		// 延时500us
	EA = 1;
	return ACK;
}
// 发送一位数据
void OneWire_SendBit(unsigned char Bit){
   
	unsigned char i;
	EA = 0;
	OneWire_IO = 0;
	i = 3;while (--i);		// 延时10us
	OneWire_IO = Bit;
	i = 24;while (--i);		// 延时50us
	EA = 1;
	OneWire_IO = 1;				// 释放总线
}
// 接收一位数据
unsigned char OneWire_ReceiveBit(){
   
	unsigned char i,Bit;
	EA = 0;
	OneWire_IO = 0;
	i = 2;while (--i);		// 延时5us
	OneWire_IO = 1;
	i = 2;while (--i);		// 延时5us
	Bit = OneWire_IO;
	i = 24;while (--i);		// 延时50us
	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,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 SKIP_ROM  				0xCC	// 跳过ROM
#define CONVERT_T   			0x44	// 温度交换
#define READ_SCRATCHPAD   		0xBE	// 读取RAM

// 温度变换
void DS18B20_CovertT(){
   
	OneWire_Init();
	OneWire_SendByte(SKIP_ROM);
	OneWire_SendByte(CONVERT_T);
}

// 温度读取
float DS18B20_ReadT(){
   
	unsigned char TLSB,TMSB;
	int Temp;
	float T;
	OneWire_Init();
	OneWire_SendByte(SKIP_ROM);
	OneWire_SendByte(READ_SCRATCHPAD);
	TLSB = OneWire_ReceiveByte();	// 高八位
	TMSB = OneWire_ReceiveByte();	// 低八位
	Temp = (TMSB<<8) | TLSB;
	T = Temp/16.0;	// 右移四位
	return T;
}

显示温度传感器并配置阈值警报

main.c

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

float T,TShow;
char TL,TH;
unsigned char KeyNum;

void main()
{
   
	DS18B20_CovertT();		//上电先转换一次温度,防止第一次读数据错误
	Delayms(1000);			//等待转换完成
	TH=AT24C02_ReadByte(0);	//读取温度阈值数据
	TL=AT24C02_ReadByte(1);
	if(TH>125 || TL<-55 || TH<=TL)
	{
   
		TH=20;			//如果阈值非法,则设为默认值
		TL=15;
	}
	LCD_Init();
	LCD_ShowString(1,1,"T:");
	LCD_ShowString(2,1,"TH:");
	LCD_ShowString(2,9,"TL:");
	LCD_ShowSignedNum(2,4,TH,3);
	LCD_ShowSignedNum(2,12,TL,3);
	Time0_Init();
	
	while(1)
	{
   
		KeyNum=Key();
		
		/*温度读取及显示*/
		DS18B20_CovertT();	//转换温度
		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);//显示温度小数部分
		
		/*阈值判断及显示*/
		if(KeyNum)
		{
   
			if(KeyNum==1)	//K1按键,TH自增
			{
   
				TH++;
				if(TH>125){
   TH=125;}
			}
			if(KeyNum==2)	//K2按键,TH自减
			{
   
				TH--;
				if(TH<=TL){
   TH++;}
			}
			if(KeyNum==3)	//K3按键,TL自增
			{
   
				TL++;
				if(TL>=TH){
   TL--;}
			}
			if(KeyNum==4)	//K4按键,TL自减
			{
   
				TL--;
				if(TL<-55){
   TL=-55;}
			}
			//显示阈值数据
			LCD_ShowSignedNum(2,4,TH,3);	
			LCD_ShowSignedNum(2,12,TL,3);
			//写入到At24C02中保存
			AT24C02_WriteByte(0,TH);		
			Delayms(5);
			AT24C02_WriteByte(1,TL);
			Delayms(5);
		}
		//越界判断
		if(T>TH)			
		{
   
			LCD_ShowString(1,13,"OV:H");
		}
		else if(T<TL)
		{
   
			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();	//每20ms调用一次按键驱动函数
	}
}


注意

  • 单总线与I2C总线发送接收数据不同,I2C数据从左到右是从高位到低位,单总线从左到右是从低位到高位。
  • 本案例为避免定时器影响单总线的延时判断逻辑,采用了延时判断时关闭一切中断的做法,对定时器有一定的影响,在其他程序中使用需注意。
  • 这个温度传感器的温度转换即转变为可接收的值的过程需要一定的时间,如果不延时等待会显示一个默认值。
  • 由于温度数据最后四位为小数位,返回值和显示值时要注意移位。

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-28 21:20:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-28 21:20:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-28 21:20:02       82 阅读
  4. Python语言-面向对象

    2024-01-28 21:20:02       91 阅读

热门阅读

  1. 7-2 求二叉树的叶子结点个数

    2024-01-28 21:20:02       52 阅读
  2. 微服务面试题

    2024-01-28 21:20:02       59 阅读
  3. 言传身留:NLP技术引领机器翻译革新

    2024-01-28 21:20:02       40 阅读
  4. Python Appium组件使用详解

    2024-01-28 21:20:02       52 阅读
  5. 更新最近可以使用的 ip归属地免费api

    2024-01-28 21:20:02       54 阅读
  6. 软考 系统分析师系列知识点之范围管理(1)

    2024-01-28 21:20:02       55 阅读
  7. leetcode-移除链表元素

    2024-01-28 21:20:02       52 阅读
  8. leetcode-2846、560、239、76

    2024-01-28 21:20:02       53 阅读
  9. C 练习实例46-宏#define命令练习

    2024-01-28 21:20:02       57 阅读
  10. Python类变量和实例变量

    2024-01-28 21:20:02       49 阅读
  11. CCF-CSP 202309-1 坐标变换(其一)

    2024-01-28 21:20:02       50 阅读
  12. C++继承

    C++继承

    2024-01-28 21:20:02      57 阅读
  13. 用cityscapes fine tune yolov8-seg

    2024-01-28 21:20:02       55 阅读