目录

  • 一、DS18B20
    • 1.1 DS18B20介绍
    • 1.2 引脚及应用电路
    • 1.3 内部结构框图
    • 1.4 存储器结构
  • 二、单总线
    • 2.1 单总线介绍
    • 2.2 单总线电路规范
    • 2.3 单总线时序结构
  • 三、DS18B20操作流程
    • 四、DS18B20数据帧
  • 五、温度存储格式
  • 六、代码演示
    • 6.1 温度读取
    • 6.2 温度报警器
    • 注意:一定要看

一、DS18B20

1.1 DS18B20介绍

DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点
测温范围:-55°C 到 +125°C
通信接口:1-Wire(单总线)
其它特征:可形成总线结构、内置温度报警功能、可寄生供电

1.2 引脚及应用电路

1.3 内部结构框图


64-BIT ROM:作为器件地址,用于总线通信的寻址
SCRATCHPAD(暂存器):用于总线的数据交互
EEPROM:用于保存温度触发阈值和配置参数

1.4 存储器结构

二、单总线

2.1 单总线介绍

单总线(1-Wire BUS)是由Dallas公司开发的一种通用数据总线
一根通信线:DQ
异步、半双工
单总线只需要一根通信线即可实现数据的双向传输,当采用寄生供电时,还可以省去设备的VDD线路,此时,供电加通信只需要DQ和GND两根线

2.2 单总线电路规范

设备的DQ均要配置成开漏输出模式
DQ添加一个上拉电阻,阻值一般为4.7KΩ左右
若此总线的从机采取寄生供电,则主机还应配一个强上拉输出电路


2.3 单总线时序结构

初始化:主机将总线拉低至少480us,然后释放总线,等待15-60us后,存在的从机会拉低总线60-240us以响应主机,之后从机将释放总线

发送一位:主机将总线拉低60-120us,然后释放总线,表示发送0;主机将总线拉低1-15us,然后释放总线,表示发送1。从机将在总线拉低30us后(典型值)读取电平,整个时间片应大于60us

接收一位:主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),读取为低电平则为接收0,读取为高电平则为接收1 ,整个时间片应大于60us

发送一个字节:连续调用8次发送一位的时序,依次发送一个字节的8位(低位在前)

接收一个字节:连续调用8次接收一位的时序,依次接收一个字节的8位(低位在前)

三、DS18B20操作流程

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

四、DS18B20数据帧

温度变换:初始化→跳过ROM →开始温度变换

温度读取:初始化→跳过ROM →读暂存器→连续的读操作

五、温度存储格式


六、代码演示

6.1 温度读取

main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "Delay.h"float T;void main()
{DS18B20_ConvertT();        //上电先转换一次温度,防止第一次读数据错误Delay(1000);           //等待转换完成LCD_Init();LCD_ShowString(1,1,"Temperature:");while(1){DS18B20_ConvertT();    //转换温度T=DS18B20_ReadT();   //读取温度if(T<0)                //如果温度小于0{LCD_ShowChar(2,1,'-');  //显示负号T=-T;            //将温度变为正数}else              //如果温度大于等于0{LCD_ShowChar(2,1,'+');   //显示正号}LCD_ShowNum(2,2,T,3);        //显示温度整数部分LCD_ShowChar(2,5,'.');      //显示小数点LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);//显示温度小数部分}
}

DS18B20.c

#include <REGX52.H>
#include "OneWire.h"//DS18B20指令
#define DS18B20_SKIP_ROM            0xCC
#define DS18B20_CONVERT_T           0x44
#define DS18B20_READ_SCRATCHPAD     0xBE/*** @brief  DS18B20开始温度变换* @param  无* @retval 无*/
void DS18B20_ConvertT(void)
{OneWire_Init();OneWire_SendByte(DS18B20_SKIP_ROM);OneWire_SendByte(DS18B20_CONVERT_T);
}/*** @brief  DS18B20读取温度* @param  无* @retval 温度数值*/
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();Temp=(TMSB<<8)|TLSB;T=Temp/16.0;return T;
}

OneWire.c

#include <REGX52.H>//引脚定义
sbit OneWire_DQ=P3^7;/*** @brief  单总线初始化* @param  无* @retval 从机响应位,0为响应,1为未响应*/
unsigned char OneWire_Init(void)
{unsigned char i;unsigned char AckBit;EA=0;OneWire_DQ=1;OneWire_DQ=0;i = 247;while (--i);       //Delay 500usOneWire_DQ=1;i = 32;while (--i);         //Delay 70usAckBit=OneWire_DQ;i = 247;while (--i);        //Delay 500usEA=1;return AckBit;
}/*** @brief  单总线发送一位* @param  Bit 要发送的位* @retval 无*/
void OneWire_SendBit(unsigned char Bit)
{unsigned char i;EA=0;OneWire_DQ=0;i = 4;while (--i);            //Delay 10usOneWire_DQ=Bit;i = 24;while (--i);            //Delay 50usOneWire_DQ=1;EA=1;
}/*** @brief  单总线接收一位* @param  无* @retval 读取的位*/
unsigned char OneWire_ReceiveBit(void)
{unsigned char i;unsigned char Bit;EA=0;OneWire_DQ=0;i = 2;while (--i);          //Delay 5usOneWire_DQ=1;i = 2;while (--i);            //Delay 5usBit=OneWire_DQ;i = 24;while (--i);         //Delay 50usEA=1;return Bit;
}/*** @brief  单总线发送一个字节* @param  Byte 要发送的字节* @retval 无*/
void OneWire_SendByte(unsigned char Byte)
{unsigned char i;for(i=0;i<8;i++){OneWire_SendBit(Byte&(0x01<<i));}
}/*** @brief  单总线接收一个字节* @param  无* @retval 接收的一个字节*/
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;
}

6.2 温度报警器

main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "Delay.h"
#include "AT24C02.h"
#include "Key.h"
#include "Timer0.h"float T,TShow;
char TLow,THigh;
unsigned char KeyNum;void main()
{DS18B20_ConvertT();        //上电先转换一次温度,防止第一次读数据错误Delay(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:");LCD_ShowSignedNum(2,4,THigh,3);LCD_ShowSignedNum(2,12,TLow,3);Timer0_Init();while(1){KeyNum=Key();/*温度读取及显示*/DS18B20_ConvertT(); //转换温度T=DS18B20_ReadT();   //读取温度if(T<0)                //如果温度小于0{LCD_ShowChar(1,3,'-');  //显示负号TShow=-T;        //将温度变为正数}else              //如果温度大于等于0{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按键,THigh自增{THigh++;if(THigh>125){THigh=125;}}if(KeyNum==2)   //K2按键,THigh自减{THigh--;if(THigh<=TLow){THigh++;}}if(KeyNum==3)   //K3按键,TLow自增{TLow++;if(TLow>=THigh){TLow--;}}if(KeyNum==4)  //K4按键,TLow自减{TLow--;if(TLow<-55){TLow=-55;}}LCD_ShowSignedNum(2,4,THigh,3); //显示阈值数据LCD_ShowSignedNum(2,12,TLow,3);AT24C02_WriteByte(0,THigh);      //写入到At24C02中保存Delay(5);AT24C02_WriteByte(1,TLow);Delay(5);}if(T>THigh)          //越界判断{LCD_ShowString(1,13,"OV:H");}else if(T<TLow){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调用一次按键驱动函数}
}

AT24C02.c

#include <REGX52.H>
#include "I2C.h"#define AT24C02_ADDRESS       0xA0/*** @brief  AT24C02写入一个字节* @param  WordAddress 要写入字节的地址* @param  Data 要写入的数据* @retval 无*/
void AT24C02_WriteByte(unsigned char WordAddress,Data)
{I2C_Start();I2C_SendByte(AT24C02_ADDRESS);I2C_ReceiveAck();I2C_SendByte(WordAddress);I2C_ReceiveAck();I2C_SendByte(Data);I2C_ReceiveAck();I2C_Stop();
}/*** @brief  AT24C02读取一个字节* @param  WordAddress 要读出字节的地址* @retval 读出的数据*/
unsigned char AT24C02_ReadByte(unsigned char WordAddress)
{unsigned char Data;I2C_Start();I2C_SendByte(AT24C02_ADDRESS);I2C_ReceiveAck();I2C_SendByte(WordAddress);I2C_ReceiveAck();I2C_Start();I2C_SendByte(AT24C02_ADDRESS|0x01);I2C_ReceiveAck();Data=I2C_ReceiveByte();I2C_SendAck(1);I2C_Stop();return Data;
}

注意:一定要看

千万不要直接复制代码,因为是模块化编写,模块的代码没有往上复制(模块的代码在以往的文章中可以找到),大家一定要自己动手!!!!!

MCU-51:单片机DS18B20温度报警器相关推荐

  1. 51单片机DS18B20温度报警器proteus仿真设计_可调上下限

    51单片机DS18B20温度报警器proteus仿真设计_可调上下限 (仿真+源码+原理图+报告) 原理图:Altium Designer 仿真版本:proteus 7.8 程序编译器:keil 4/ ...

  2. 51单片机DS18B20温度报警器

    主要是对主函数逻辑的编写,主要有两个注意点: ①将按键换成定时器扫描,要注意,单总线进行传输时,要关闭定时器中断,传输结束后再打开定时器,所有的单总线都得这样.因为单总线中必须要进行延时操作.如果在延 ...

  3. 51单片机DS18B20+lcd1602温度报警器( Proteus仿真程序)

    51单片机DS18B20+lcd1602温度报警器( Proteus仿真程序) AT89C52.DS18B20和lcd1602 温度报警器按键设置报警上下限. Proteus仿真程序 器件 实例代码 ...

  4. matlab ds18b20 单片机,基于51单片机ds18b20温度检测————设计报告.doc

    基于51单片机ds18b20温度检测----设计报告 课程名称: 微机原理课程设计 题 目: 温度检测课程设计 摘要 随着时代的进步和发展,单片机技术已经普及到我们生活,工作,科研,各个领域,已经成为 ...

  5. 基于51单片机的温度报警器设计

    目 录 前言.............................................................................................. ...

  6. 51单片机+DS18B20+数码管显示+串口通讯+Proteus仿真

    51单片机+DS18B20+数码管显示+串口通讯+Proteus仿真 本实验通过51单片机读取DS18B20温度传感器的温度,然后通过数码管显示,并通过串口,将读取到的温度数据发送出去. 本案例需要使 ...

  7. 51单片机DS18B20与中断冲突解决方式

    51单片机DS18B20与中断冲突解决方式 应用场所 在使用51单片机DS18B20的过程中,总会遇到中断(这里的中断主要是指定时器中断和串口中断)与其时序产生冲突,从而导致读取不稳定的情况发生. 问 ...

  8. 51单片机~DS18B20温度传感器

    51单片机~DS18B20温度传感器 (一)简介说明: (二)接线: 1. 内部结构: 正温度前五位是0. 负温度前五位是1. 由LS,MS组成的四位十六进制数,和16位二进制数.(先MS后LS) 结 ...

  9. 51单片机DS18B20温度传感器及数码管显示温度

    51单片机DS18B20温度传感器及数码管显示温度 大家好,今天给大家带来的代码及原理解释是,在51单片机在接收DS18B20温度传感器数据,并且在数码管上实时显示温度 DS18B20及数码管显示温度 ...

  10. S0011基于51单片机DS18B20温控风扇仿真设计

    基于51单片机DS18B20温控风扇仿真设计 (仿真+原理图+源码+设计报告) 原理图:Altium Designer 仿真原版本:proteus 7.8 程序编译器:keil 4/keil 5 编程 ...

最新文章

  1. BZOJ1901Zju2112 Dynamic Rankings——树状数组套主席树
  2. hpe服务器有哪些型号,HPE ProLiant DL80 Gen9 服务器 - 惠普服务器配置参数
  3. Linux系统root密码重置教程
  4. 顶层const和底层const的区别
  5. Levmar使用小结
  6. 在服务器上导出dmp文件,远程在服务器上导出dmp文件
  7. matlab2016限制内存,matlab
  8. 带薪休假,运维汪的春天来了?
  9. vue的h函数_Vue中render中的h箭头函数
  10. Bochs使用简单教程
  11. linux搜狗输入法16.04,Unbuntu16.04安装搜狗拼音输入法的图文教程
  12. Sniffer Pro
  13. python一阶差分_Python使用pandas对数据进行差分运算的方法
  14. OSChina 周一乱弹 —— 程序猿到底是多有才?
  15. 说说橡胶软接头安装的误区
  16. reid 比赛(全国人工智能大赛)
  17. php webshell 木马,消灭php webshell与一句话木马
  18. 转:(记录)C语言中的itoa()函数的用法解析
  19. [siggraph17]decima engine的光照和aa技术
  20. Jenkins+git+docker构建持续化集成环境

热门文章

  1. 数据仓库架构的技术选型
  2. Oracle数据库逻辑备份与恢复(3)——数据泵(expdp、impdp)
  3. 群、环、域基础与例子
  4. 【填坑日记】list集合的remove方法移除不了?!
  5. opencv-python 绘制图像直方图及直方图均衡化
  6. 遍历Python字典
  7. Python for循环遍历字典(dict)的方法
  8. TCP与UDP的区别!
  9. JS点击事件和延迟处理
  10. phpize使用方法