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数据从左到右是从高位到低位,单总线从左到右是从低位到高位。
  • 本案例为避免定时器影响单总线的延时判断逻辑,采用了延时判断时关闭一切中断的做法,对定时器有一定的影响,在其他程序中使用需注意。
  • 这个温度传感器的温度转换即转变为可接收的值的过程需要一定的时间,如果不延时等待会显示一个默认值。
  • 由于温度数据最后四位为小数位,返回值和显示值时要注意移位。
相关推荐
沐欣工作室_lvyiyi1 小时前
基于单片机的智能电表设计(论文+源码)
单片机·嵌入式硬件·电能表·数字电能表
半导体老登2 小时前
新能源汽车核心元件揭秘:二极管、三极管结构与工作原理解析(2/2)
人工智能·单片机·嵌入式硬件·汽车
猿~~~4 小时前
STM32的HAL库开发---多通道ADC采集(DMA读取)实验
stm32·单片机·嵌入式硬件
Freak嵌入式5 小时前
开源一款I2C电机驱动扩展板-FreakStudio多米诺系列
嵌入式硬件·嵌入式·智能硬件·开源硬件·micropython·电机驱动·电子模块
曾浩轩5 小时前
51单片机学习之旅——C语言小知识
c语言·学习·51单片机
kongba0076 小时前
Cursor提示词模板,开发GD32,C语言开发GD32 ARM单片机编程规范提示词 大厂风格代码规范
c语言·arm开发·单片机
LaoZhangGong1236 小时前
STM32的“Unique device ID“能否修改?
c语言·经验分享·stm32·单片机·嵌入式硬件
1101 11018 小时前
STM32-心知天气项目
stm32·单片机·嵌入式硬件
Ronin-Lotus8 小时前
嵌入式硬件篇---数字电子技术中的触发器
嵌入式硬件·fpga开发·触发器·数字电子技术·上位机知识
Ronin-Lotus8 小时前
嵌入式硬件篇---数字电子技术中的时序逻辑
单片机·嵌入式硬件·蓝桥杯·时序分析·数字电子技术