DS18B20温度传感器

文章目录


一、介绍DS18B20

了解DS18B20

引脚及电路图


完整电路 (引脚名称不同、功能一样)

内部结构框图

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

存储器结构

单总线(1 wire bus)介绍

单总线电路规范

单总线时序结构

初始化

发送一个数据

接收一位数据

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

DS18B20操作流程


所要使用的数据帧

温度存储格式


例子

二、实现温度检测

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

OneWire.c

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

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

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数据从左到右是从高位到低位,单总线从左到右是从低位到高位。
  • 本案例为避免定时器影响单总线的延时判断逻辑,采用了延时判断时关闭一切中断的做法,对定时器有一定的影响,在其他程序中使用需注意。
  • 这个温度传感器的温度转换即转变为可接收的值的过程需要一定的时间,如果不延时等待会显示一个默认值。
  • 由于温度数据最后四位为小数位,返回值和显示值时要注意移位。
相关推荐
星辰pid1 小时前
STM32控制四自由度机械臂(SG90舵机)(硬件篇)(简单易复刻)
stm32·单片机·嵌入式硬件·机械臂
威桑2 小时前
STM32 专有名词缩写整合
stm32·单片机·嵌入式硬件
星源~3 小时前
tree 命令集成到 Git Bash:可视化目录结构的指南
git·单片机·物联网·嵌入式·项目开发
SKYDROID云卓小助手4 小时前
无人设备遥控器之自动调整编码技术篇
人工智能·嵌入式硬件·算法·自动化·信号处理
所念皆星海9114 小时前
图灵完备之路(数电学习三分钟)----数据选择器与总线
嵌入式硬件·通信·数电
智者知已应修善业6 小时前
【51单片机节日彩灯控制器设计】2022-6-11
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
开-悟6 小时前
嵌入式编程-使用AI查找BUG的启发
c语言·人工智能·嵌入式硬件·bug
许白掰8 小时前
【stm32】HAL库开发——CubeMX配置RTC,单片机工作模式和看门狗
stm32·单片机·嵌入式硬件·学习·实时音视频
DIY机器人工房9 小时前
0.96寸OLED显示屏 江协科技学习笔记(36个知识点)
笔记·科技·stm32·单片机·嵌入式硬件·学习·江协科技
国科安芯10 小时前
【AS32系列MCU调试教程】SPI调试的常见问题解析
单片机·嵌入式硬件·性能优化·硬件架构·硬件工程