51单片机入门_江协科技_29~30_OB记录的自学笔记_DS18B20温度传感器

news2025/2/6 19:02:06

29. DS18B20温度传感器

  • 29.1. DS18B20介绍
    •DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点
    •测温范围:-55°C 到 +125°C
    •通信接口:1-Wire(单总线)
    •其它特征:可形成总线结构、内置温度报警功能、可寄生供电(2个供电引脚,1个数据引脚,一个数据线+一个GND也可以实现工作)
    •热敏电阻就是模拟温度传感器,通过AD采集芯片,将模拟的电压值转换为温度,需要AD转换读取温度;
    •DS18B20集成了上述所有模拟温度传感器和电路,以及AD转换,应用更简单;
    在这里插入图片描述

  • 29.2. 引脚及应用电路
    在这里插入图片描述

  • 29.3. 内部结构框图
    •PARASITE POWER CIRCUIT 寄生供电电路,可以省Vdd,如果用寄生供电,需要给Vpu给一个强上拉,以达到内部供电稳定,开发板不涉及这部分内容;
    •64-BIT ROM:作为器件地址,用于总线通信的寻址
    •SCRATCHPAD(暂存器RAM):用于总线的数据交互
    •EEPROM:用于保存温度触发阈值和配置参数
    •TEMPERATURE SENSOR温度传感器
    •ALARM HIGH TRIGGER高温报警
    •ALARM LOW TRIGGER低温报警
    •CONFIGURATION REGISTER配置寄存器,掉电不丢失,精度修改等
    •8BIT CRC GENERATOR校验码生成器

在这里插入图片描述

  • 29.4. 存储器结构
    • 下图与上图对应

在这里插入图片描述

  • 29.5. 单总线介绍
    •单总线(1-Wire BUS)是由Dallas公司开发的一种通用数据总线
    •一根通信线:DQ
    •异步、半双工
    •单总线只需要一根通信线即可实现数据的双向传输,当采用寄生供电时,还可以省去设备的VDD线路,此时,供电加通信只需要DQ和GND两根线
    •以下照片是单总线的传感器,右侧为温湿度传感器;
    在这里插入图片描述

  • 29.6. 单总线电路规范
    •设备的DQ均要配置成开漏输出模式,根据经验判断,同I2C
    •DQ添加一个上拉电阻,阻值一般为4.7KΩ左右,同I2C
    •若此总线的从机采取寄生供电,则主机还应配一个强上拉输出电路
    在这里插入图片描述

  • 29.7. 单总线时序结构
    •初始化:主机将总线拉低至少480us,然后释放总线,等待1560us后,存在的从机会拉低总线60240us以响应主机,之后从机将释放总线
    •黑色粗线表示主机将总线拉低的时间480us,弯曲的细黑线表示电阻弱上拉,表示拉高有时间的,不是立即拉高,浅灰色表示从机拉低;
    •在从机拉低的时候需要读取拉低的状态,判断从机响应;
    在这里插入图片描述

  • 29.8. 单总线时序结构
    •发送一位:主机将总线拉低60120us,然后释放总线,表示发送0;主机将总线拉低115us,然后释放总线,表示发送1。从机将在总线拉低30us后(典型值)读取电平,整个时间片应大于60us
    在这里插入图片描述

  • 29.9. 单总线时序结构
    •接收一位:主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),读取为低电平则为接收0,读取为高电平则为接收1 ,整个时间片应大于60us
    在这里插入图片描述

  • 29.10. 单总线时序结构
    在这里插入图片描述

  • I2C总线高位在前;

  • 29.11. DS18B20操作流程
    •初始化:从机复位,主机判断从机是否响应
    •ROM操作:ROM指令+本指令需要的读写操作
    •功能操作:功能指令+本指令需要的读写操作

ROM指令功能指令
SEARCH ROM [F0h]CONVERT T [44h]
READ ROM [33h]WRITE SCRATCHPAD [4Eh]
MATCH ROM [55h]READ SCRATCHPAD [BEh]
SKIP ROM [CCh]COPY SCRATCHPAD [48h]
ALARM SEARCH [ECh]RECALL E2 [B8h]
READ POWER SUPPLY [B4h]
  • 29.12. DS18B20数据帧
    在这里插入图片描述

  • 29.13. 温度存储格式
    在这里插入图片描述

30. DS18B20温度读取&温度报警器

  • 30.1. Proteus中建立仿真环境(依旧基于之前的版本基础上改为2.11版)
    在元器件库中搜索DS18B20并加入到图纸中,DQ接P37口与开发板一致
    在这里插入图片描述

    此处的开关需要拨动到ON,因为需要LCD1602进行温度显示;
    在这里插入图片描述

  • 30.2. 大体的编程思路
    需要写2个模块,一个OneWire单总线模块;
    单总线模块包括初始化,写一个位,读一个位,写一个字节,读一个字节
    一个DS18B20模块;
    包括温度转换模块,温度读取模块

  • 30.3. OneWire.c单总线模块程序如下:

#include <REGX52.H>

sbit OneWire_DQ=P3^7;
/*温度初始化*/
unsigned char OneWire_Init()
{	
	unsigned char i,AckBit;
	OneWire_DQ=1;				//不确定DQ状态,所以先拉高
	OneWire_DQ=0;				//再拉低DQ
	i = 247;while (--i);		//delay 500us
	OneWire_DQ=1;
	i = 32;while (--i);		    //delay 70us
	AckBit=OneWire_DQ;
	i = 247;while (--i);		//delay 500us
	return AckBit;				//返回AckBit,初始化结束
}
/*发送一位*/
void OneWire_SendBit(unsigned char Bit)	//发送一位数据,省去if判断
{
	unsigned char i;
	OneWire_DQ=0;
	i = 4;while (--i);		//delay 10us,数据源自STC ISP
	OneWire_DQ=Bit;
	i = 24;while (--i);		//delay 50us
	OneWire_DQ=1;			//上述所有delay时间合计60us
}
/*读取或接收一位*/
unsigned char OneWire_ReceiveBit(void)	//接收一位数据
{
	unsigned char i;
	unsigned char Bit;
	OneWire_DQ=0;
	i = 2;while (--i);		//delay 5us
	OneWire_DQ=1;
	i = 2;while (--i);		//delay 5us
	Bit=OneWire_DQ;			//采样
	i = 24;while (--i);		//delay 50us
	return Bit;				//上述所有delay时间合计60us
}
/*发送一个字节*/
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;
}

OneWire.h单总线程序如下

#ifndef _ONEWIRE_H_  
#define _ONEWIRE_H_  

unsigned char OneWire_Init(void);			//单总线初始化
void OneWire_SendBit(unsigned char Bit);	//发送一位数据,省去if判断
unsigned char OneWire_ReceiveBit(void);	//接收一位数据
void OneWire_SendByte(unsigned char Byte);	//发送一个字节
unsigned char OneWire_ReceiveByte(void);	//接收一个字节

#endif
  • 30.4. DS18B20.c与DS18B20.h程序:
#include <REGX52.H>
#include "OneWire.h"
#include "LCD1602.h"

#define DS18B20_SKIP_ROM 	0xcc		//跳过ROM地址
#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(void)
{
	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();			//上限温度
	LCD_ShowBinNum(1,1,TMSB,8);			//测试用
	LCD_ShowBinNum(1,9,TLSB,8);			//测试用
	Temp=(TMSB<<8)|TLSB;				//高低8位合并
	T=Temp/16.0;
	return T;
}
#ifndef _DS18B20_H_  
#define _DS18B20_H_  

void DS18B20_ConvertT(void);
float DS18B20_ReadT(void);

#endif

主程序main.c为:

#include <REGX52.h>
#include "LCD1602.h"
#include "delay_xms.h"
#include "DS18B20.h"

float T;

void main()
{
	DS18B20_ConvertT();		//先转化温度
	delay_xms(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);
	}
	
}

Proteus测试没有问题
在这里插入图片描述

  • 30.5. 需要在上述程序基础上衍生一个程序,要求如下

    • 可以设定最高&最低温度,温度的上下限;
    • 需用用独立按键对最高和最低温度的上下限进行调节;
    • S1温度上限提高
    • S2温度上限降低
    • S3温度下限提高
    • S4温度下限降低
    • 当温度超过上限时,LCD1602右上角显示OV:H
    • 当温度低于下线时,LCD1602右上角显示OV:L
    • 当温度在设定上下限温度中间位置,显示OV:
    • 温度的上下限不超过传感器测温范围-40~125摄氏度
    • 同时应考虑独立按键的扫描使用之前修改的中断扫描方式,同时在单总线操作的时候应关闭中断(否则中断干扰了单总线数据传输),温度出错;
    • 独立按键用delay扫描同样的问题;
    • 上下限温度判断涉及逻辑判断,首先是上限温度高于125,则一直置于125,下限低于-40,则置于-40,如果上限温度低于等于下限温度,则上限温度不可减小了,对于下限温度反之一样;
    • 总结:中断扫描用于按键这种实际要求精度不高的场合可以应用,如果是秒表的计时中断+按键中断扫描会影响计时精度,需要注意;
    • 设定好的上下限温度存储于AT24C02中,开机直接调取;
  • 30.6. 基于上述判断,主程序如下:

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

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

void main()
{
	DS18B20_ConvertT();
	delay_xms(1000);
	THigh=AT24C02_ReadByte(0);
	TLow=AT24C02_ReadByte(1);
	if(THigh>125 || TLow<-55 || THigh<=TLow)
	{
		THigh=20;
		TLow=15;
	}
	LCD_Init();
	LCD_ShowString(1,1,"T:");
	LCD_ShowString(2,1,"TH:");
	LCD_ShowString(2,9,"TL:");
	Timer0_Init();
	while(1)
	{
		KeyNum=Key();
		/*温度读取及显示*/
		DS18B20_ConvertT();
		T=DS18B20_ReadT();
		if(T<0)
		{
			LCD_ShowChar(1,3,'-');
			TShow=-T;
		}
		else
		{
			LCD_ShowChar(1,3,'+');
			TShow=T;		//如果没有这句开机温度为零,TShow没赋值
		}
		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)
			{
				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){THigh=-55;}
			}		
		}

		LCD_ShowSignedNum(2,4,THigh,3);
		LCD_ShowSignedNum(2,12,TLow,3);
		AT24C02_WriteByte(0,THigh);
		delay_xms(5);
		AT24C02_WriteByte(1,TLow);
		delay_xms(5);
		/*OVH,OVL显示*/
		if(T>THigh)
			{
				LCD_ShowString(1,13,"OV:H");
			}
			else if(T<TLow) //注意T<TLow负数情况出问题
			{
				LCD_ShowString(1,13,"OV:L");
			}
			else
			{
				LCD_ShowString(1,13,"OV: ");
			}
	}
}

/*会打断主循环的延时进程*/
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=20)	//定时器扫描按键还行,秒表的话会受影响,单总线的问题
	{
		T0Count=0;
		Key_Loop();
	}
}

  • 需要调用的函数如左侧图片,同时其他函数模块参考之前项目
    在这里插入图片描述

  • proteus测试如下
    在这里插入图片描述
    Proteus文件百度网盘分享:
    链接:https://pan.baidu.com/s/1Brq-m9xH_PJgocxsRE5mPw
    提取码:6666

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1598598.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

k8s的service为什么不能ping通?——所有的service都不能ping通吗

点击阅读原文 前提&#xff1a;kube-proxy使用iptables模式 Q service能不能ping通&#xff1f; A: 不能&#xff0c;因为k8s的service禁止了icmp协议 B: 不能&#xff0c;因为clusterIP是一个虚拟IP&#xff0c;只是用于配置netfilter规则&#xff0c;不会实际绑定设备&…

腾讯EdgeOne产品测评体验—Web服务全能一体化服务,主打一步到位

前言 现在网络Web攻击真的防不胜防啊&#xff0c;相信有很多独狼开发者自己建站&#xff0c;租个云服务器&#xff0c;一部署自己的服务&#xff0c;每隔一段时间内测和网站总有一个要崩。自己感觉难受不说&#xff0c;网站稍微有点要出头的时候&#xff0c;数不清的访问攻击就…

汽车车灯用肖特基二极管,选什么型号好?

肖特基二极管种类繁多&#xff0c;有低压降肖特基二极管、通用型肖特基二极管、快速恢复型肖特基二极管、高功率肖特基二极管、汽车级肖特基二极管等等&#xff0c;其中低压降肖特基二极管和汽车级肖特基二极管是二极管厂家东沃电子的核心优势产品。关于东沃电子推出的低压降肖…

FFmpeg: 自实现ijkplayer播放器--05ijkplayer–连接UI界面和ffplay.c

文章目录 ijkplayer时序图消息循环--回调函数实现播放器播放时状态转换播放停止ijkmediaPlay成员变量成员函数ijkplayer时序图 stream_open: frame_queue_init packet_queue_init init_clock 创建read_thread线程 创建video_refresh_thread线程 消息循环–回调函数实现 ui 和…

Spectral Adversarial MixUp for Few-Shot Unsupervised Domain Adaptation论文速读

文章目录 Spectral Adversarial MixUp for Few-Shot Unsupervised Domain Adaptation摘要方法Domain-Distance-Modulated Spectral Sensitivity (DoDiSS&#xff09;模块Sensitivity-Guided Spectral Adversarial Mixup (SAMix)模块 实验结果 Spectral Adversarial MixUp for F…

在线教程|低门槛部署!SUPIR 专治各种图片模糊,还能理解文本描述进行精修

家庭相册中泛黄的老照片&#xff0c;历史档案中尘封的影像资料&#xff0c;科研实验中沉淀下的图片资源…… 图像作为一种重要的信息载体&#xff0c;不仅承载了消逝的时光与故事&#xff0c;也记录着人类对历史的探索和传承。然而&#xff0c;由于早期保存条件的限制&#xf…

Go 编译构建的一些细节

Go 编译构建的一些细节 发现自己竟然没有怎么认真研究过 go 的编译构建命令。 结论前置 go run 专门用来运行命令源码文件的命令&#xff0c;一般用来运行单个文件go build 主要是用于测试编译。编译某个包或者项目&#xff0c;在当前目录下生成可执行文件go install 编译并…

(4)步态识别论文研读——用于步态识别的分层时空表示学习

论文题目Hierarchical Spatio-Temporal Representation Learning for Gait Recognition 论文地址 https://arxiv.org/abs/2307.09856 1.摘要 步态识别是一种生物特征技术&#xff0c;通过其独特的行走方式识别个体&#xff0c;适用于无约束环境&#xff0c;具有广泛的应用。…

链表OJ1——删除链表中等于给定值 val 的所有节点

题目 力扣OJ链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 解法 我们来看看这个题目啊&#xff0c;怎么做呢&#xff1f; 有两种解法 三指针法 我们完全可以定义三个指针来进行这个删除操作 假设我们要移除的是2 这样子就完成了 特殊情况 开头——假设我们…

一文速览铁威马TOS 6全新“文件管理”

TOS 6 Beta已经上线一段时间了&#xff0c;各位铁粉用着怎么样呢&#xff1f;今天就和大家分享&#xff0c;TOS 6全新文件管理。 为了向用户提供更流畅、更便捷的文件管理体验&#xff0c;铁威马的研发团队积极借鉴了Windows OS和Mac OS在文件管理方面的优点&#xff0c;投入巨…

系统学c#:2、基础语法(关键字、标识符、数据类型、变量、常量、字面量、运算符、类型转换)

关键字&#xff1a; 关键字是编程语言中具有特殊含义的单词或符号&#xff0c;它们通常被编程语言用于表示特定的语法结构、操作或约定。在C#中&#xff0c;关键字具有特定的语法和功能&#xff0c;用于定义语言的基本结构和规则。 以下是一些C#中常用的关键字及其功能&#xf…

使用colab进行yolov5小demo练习

输入一张动物的图片进行目标检测和分类 !pip install yolov5 import torch from PIL import Image from torchvision import transforms from yolov5.models.experimental import attempt_load from yolov5.utils.general import non_max_suppression# 加载YOLOv5模型 device …

Gradle 构建自动化工具入门

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1. 前言 2. 简介 3. 常见的项目构建工具 4. 安装 4.1. 安装说明 4.2. 下载…

【小风扇/移动电源升压芯片方案】FP6291是一款异步内置MOS管升压恒压芯片 小封装(SOT23-6)设计简单外围器件少

芯片概述 FP6291是一款异步内置MOS管升压恒压芯片&#xff0c;与肖特基和电感形成回路组成升压架构&#xff1b; 工作电压2.6-5.5V&#xff0c;可适用已单节电池和5V供电升压&#xff1b; 恒压基准&#xff08;VFB&#xff09;为0.6V2%&#xff0c;误差小提高输出的准确度&…

前端开发攻略---用JavaScript将数字转换为中文。支持万亿以下的正整数;深入解析:JavaScript 函数详解数字转换为中文的实现原理与流程

1、演示 2、实现思路 函数名为 toChineseNumber&#xff0c;它的作用是将一个数字转换成对应的中文表示形式。这个函数是一个自定义的实现&#xff0c;通过一系列步骤将数字转换成中文。我会逐步解释每一部分&#xff0c;以确保您对代码的理解清晰明了。 首先&#xff0c;让我们…

2024第十五届蓝桥杯 C/C++ B组 参赛经历分享(以及部分题解)

前言 emmmmmm&#xff0c;dp杯居然不考dp了&#xff0c;蓝桥一直没怎么出过的高精度居然也考了&#xff08;当时居然因为没太复习那块知识直接模拟混分了&#xff09;&#xff0c;题量也改了&#xff0c;总的来说反而简单了&#xff1f;。。。还好天津竞赛弱省&#xff0c;但愿…

STM32学习和实践笔记(12):蜂鸣器实验

蜂鸣器主要分为两种&#xff0c;一种是压电式的无源蜂鸣器&#xff0c;一种是电磁式的有源蜂鸣器。 有源和无源是指其内部有没有振荡器。 无源的没有内部振荡器&#xff0c;需要输入1.5-5KHZ的音频信号来驱动压电蜂鸣片发声。 有源的内部有振荡器&#xff0c;因此只需要供给…

Jackson 2.x 系列【24】Spring Web 集成

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 前言2. Spring Web3. Jackson2ObjectMapperBuilder4. Jackson2ObjectMapperFa…

STL —— priority_queue

博主首页&#xff1a; 有趣的中国人 专栏首页&#xff1a; C专栏 本篇文章主要讲解 priority_queue 的相关内容 目录 1. 优先级队列简介 基本操作 2. 模拟实现 2.1 入队操作 2.2 出队操作 2.3 访问队列顶部元素 2.4 判断优先队列是否为空 2.5 获取优先队列的大小 …

分布式向量数据库-安装部署

下载 GitHub - pgvector/pgvector: Open-source vector similarity search for Postgres 源码编译 ##文件解压缩 unzip pgvector-0.6.2.zip ##编译 make && make install 功能验证 #安装扩展CREATE EXTENSION vector;#创建测试表CREATE TABLE items (id bigseri…