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

news/2024/12/23 7:21:16/

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;				//再拉低DQi = 247;while (--i);		//delay 500usOneWire_DQ=1;i = 32;while (--i);		    //delay 70usAckBit=OneWire_DQ;i = 247;while (--i);		//delay 500usreturn AckBit;				//返回AckBit,初始化结束
}
/*发送一位*/
void OneWire_SendBit(unsigned char Bit)	//发送一位数据,省去if判断
{unsigned char i;OneWire_DQ=0;i = 4;while (--i);		//delay 10us,数据源自STC ISPOneWire_DQ=Bit;i = 24;while (--i);		//delay 50usOneWire_DQ=1;			//上述所有delay时间合计60us
}
/*读取或接收一位*/
unsigned char OneWire_ReceiveBit(void)	//接收一位数据
{unsigned char i;unsigned char Bit;OneWire_DQ=0;i = 2;while (--i);		//delay 5usOneWire_DQ=1;i = 2;while (--i);		//delay 5usBit=OneWire_DQ;			//采样i = 24;while (--i);		//delay 50usreturn 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.ppmy.cn/news/1424060.html

相关文章

通过实例学C#之ArrayList

介绍 ArrayList对象可以容纳若干个具有相同类型的对象&#xff0c;那有人说&#xff0c;这和数组有什么区别呢。其区别大概可以分为以下几点&#xff1a; 1.数组效率较高&#xff0c;但其容量固定&#xff0c;而且没办法动态改变。 2.ArrayList容量可以动态增长&#xff0c;但…

顶顶通呼叫中心中间件(mod_cti基于FreeSWITCH)-解决方案:运行了 Freeswitch 的服务器攻击问题

文章目录 前言联系我们攻击实例解决方案安装 fail2ban编辑jail.conf设置日志文件权限设置filterfail2ban 操作 前言 运行在公网的 Freeswitch 服务器&#xff0c;每天都会接收到很多恶意的呼叫请求和注册请求&#xff0c;从而尝试盗打电话。每天大量的攻击&#xff0c;会导致 …

OpenHarmony多媒体-mp4parser

简介 一个读取、写入操作音视频文件编辑的工具。 编译运行 1、通过IDE工具下载依赖SDK&#xff0c;Tools->SDK Manager->Openharmony SDK 把native选项勾上下载&#xff0c;API版本>10 2、开发板选择RK3568&#xff0c;ROM下载地址. 选择开发板类型是rk3568&#xf…

数字乡村创新实践探索农业现代化与乡村振兴新路径:科技赋能农村全面振兴与农民福祉新纪元

目录 引言 一、数字乡村与农业现代化新路径 1、智慧农业引领农业现代化 2、农业产业链的数字化转型 二、数字乡村与乡村振兴新路径 1、农村信息化水平的提升 2、农村治理模式的创新 三、科技赋能农村全面振兴与农民福祉新纪元 1、提升农业生产效益与农民收入 2、促进…

docker 容器中安装cron,却无法启动定时任务

问题描述&#xff1a; 当我是在Dockerfile配置安装cron RUN apt-get update && apt-get install -y cron 或者进入容器中安装cron apt-get install -y cron 都会有个问题就是cron服务正常启动&#xff0c;但是加入到/etc/con.d下的任务&#xff0c;或者crontab -…

对比实验系列:Efficientdet环境配置及训练个人数据集

一、源码下载 可以通过下方链接下载Efficientdet源码 GitHub - zylo117/Yet-Another-EfficientDet-Pytorch: The pytorch re-implement of the official efficientdet with SOTA performance in real time and pretrained weights.The pytorch re-implement of the official …

thinkphp 框架封装curl请求

tp6 或者 tp8框架 在框架的app/common.php 文件里加一些方法就可以 app\common.php 在这个文件里加 以下代码 就可以实现基于 curl的请求方法 (记得要开启 php的curl扩展) 查看方法 cmd里输入 php -m if (!function_exists(get)) {/*** 发送get请求* param string $url 请求…

开发语言漫谈-kotlin

程序的运行环境包括移动设备、服务端、浏览器&#xff0c;服务器又分为window、linux等&#xff0c;不同的环境使用不同的开发语言。为了解决这个问题&#xff0c;开发IDE大拿JetBrains开发了kotlin。 Kotlin是一个岛屿的名字&#xff0c;全称是Kotlin Island。这个小岛位于俄罗…