STC89C52R控制 实现单总线温度传感器DS18b20的温度读取
- 1 概述
- 1.1 介绍
- 1.2 特点
- 1.3 应用领域
- 2 DS18B20原理详解
- 2.1 内部机理
- 2.2 读写时序
- 2.3 DS18B20操作代码程序
- 3 演示
- 4 总结
配套演示例程
1 概述
DS18B20是一款数字温度传感器,由Maxim Integrated(美信集成)公司生产。它采用单总线数据通信协议,使得与微处理器的接口非常简单。以下是关于DS18B20的一些介绍
1.1 介绍
DS18B20基于数字式温度转换技术,能够直接将温度转换为数字信号输出。它内置了温度传感器和模数转换器,可以提供高精度的温度测量结果。
1.2 特点
数字输出:DS18B20输出为数字格式,便于微处理器读取和处理。
精度:具有高精度的温度测量能力,可达到±0.5°C的精度范围。
单总线通信:采用单总线通信协议,只需要一个GPIO引脚即可完成数据通信。
多功能性:DS18B20可以在不同分辨率下进行温度测量,并支持多个传感器在同一总线上工作。
低功耗:在待机模式下功耗非常低,适合用于电池供电的应用。
1.3 应用领域
工业应用:用于工业自动化、温度监测和控制系统。
家用电器:如温度控制器、恒温器等。
电子设备:如电脑、服务器等设备的温度监测。
接口:DS18B20通过3个引脚进行连接,分别为VCC(供电)、GND(地)和DQ(数据引脚)。
总的来说,DS18B20作为一款数字温度传感器,具有精度高、接口简单、多功能性强等特点,广泛应用于各种需要温度监测的场合。
2 DS18B20原理详解
2.1 内部机理
DS1820S(16 脚 SSOP):所有上表中未提及的引脚都无连接。 概览 图 1 的方框图示出了 DS1820 的主要部件。DS1820 有三个主要数字部件:1)64 位激光 ROM, 2)温度传感器,3)非易失性温度报警触发器 TH 和 TL。器件用如下方式从单线通讯线上汲 取能量:在信号线处于高电平期间把能量储存在内部电容里,在信号线处于低电平期间消耗 电容上的电能工作,直到高电平到来再给寄生电源(电容)充电。DS1820 也可用外部 5V 电 源供电。
DS1820 依靠一个单线端口通讯。在单线端口条件下,必须先建立 ROM 操作协议,才能进行存 储器和控制操作。因此,控制器必须首先提供下面 5 个 ROM 操作命令之一:1)读 ROM,2) 匹配 ROM,3)搜索 ROM,4)跳过 ROM,5)报警搜索。这些命令对每个器件的激光 ROM 部分 进行操作,在单线总线上挂有多个器件时,可以区分出单个器件,同时可以向总线控制器指 明有多少器件或是什么型号的器件。成功执行完一条 ROM 操作序列后,即可进行存储器和控 制操作,控制器可以提供 6 条存储器和控制操作指令中的任一条。 一条控制操作命令指示 DS1820 完成一次温度测量。测量结果放在 DS1820 的暂存器里,用一 条读暂存器内容的存储器操作命令可以把暂存器中数据读出。温度报警触发器 TH 和 TL 各由 一个 EEPROM 字节构成。如果没有对 DS1820 使用报警搜索命令,这些寄存器可以做为一般用 途的用户存储器使用。可以用一条存储器操作命令对 TH 和 TL 进行写入,对这些寄存器的读 出需要通过暂存器。所有数据都是以最低有效位在前的方式进行读写。 寄生电源 寄生电源的方框图见图 1。这个电路会在 I/O 或 VDD 引脚处于高电平时“偷”能量。当有特 定的时间和电压需求时(见节标题“单线总线系统”),I/O 要提供足够的能量。寄生电源 有两个好处:1)进行远距离测温时,无需本地电源,2)可以在没有常规电源的条件下读 ROM。 要想使 DS1820 能够进行精确的温度转换,I/O 线必须在转换期间保证供电。由于 DS1820 的 工作电流达到 1mA,所以仅靠 5K 上拉电阻提供电源是不行的,当几只 DS1820 挂在同一根 I/O 线上并同时想进行温度转换时,这个问题变得更加尖锐。 有两种方法能够使 DS1820 在动态转换周期中获得足够的电流供应。第一种方法,当进行温度 转换或拷贝到 E 2 存储器操作时,给 I/O 线提供一个强上拉。用 MOSFET 把 I/O 线直接拉到电源 上就可以实现,见图 2。在发出任何涉及拷贝到 E 2 存储器或启动温度转换的协议之后,必须 在最多 10μs 之内把 I/O 线转换到强上拉。使用寄生电源方式时,VDD 引脚必须接地。
另一种给 DS1820 供电的方法是从 VDD 引脚接入一个外部电源,见图 3。这样做的好处是 I/O 线上不需要加强上拉,而且总线控制器不用在温度转换期间总保持高电平。这样在转换期间 可以允许在单线总线上进行其他数据往来。另外,在单线总线上可以挂任意多片 DS1820,而 且如果它们都使用外部电源的话,就可以先发一个 Skip ROM 命令,再接一个 Convert T 命令, 让它们同时进行温度转换。注意当加上外部电源时,GND 引脚不能悬空。
温度高于 100℃时,不推荐使用寄生电源,因为 DS1820 在这种温度下表现出的漏电流比较大, 通讯可能无法进行。在类似这种温度的情况下,强烈推荐使用 DS1820 的 VDD 引脚。 对于总线控制器不知道总线上的 DS1820 是用寄生电源还是用外部电源的情况,DS1820 预备 了一种信号指示电源的使用意图。总线控制器发出一个 Skip ROM 协议,然后发出读电源命令, 这条命令发出后,控制器发出读时间隙,如果是寄生电源,DS1820 在单线总线上发回“0”, 如果是从 VDD 供电,则发回“1”,这样总线控制器就能够决定总线上是否有 DS1820 需要强 上拉。如果控制器接收到一个“0”,它就知道必须在温度转换期间给 I/O 线提供强上拉。这 个命令协议详见“存储器操作命令”节。
2.2 读写时序
2.3 DS18B20操作代码程序
配套演示例程
//main.c文件
#include "includes.h"
/******************************************************************/
/* 微秒延时函数 //10us */
/******************************************************************/
void delay_us(unsigned int us)//delay us
{
while(us--)
{
}
}
/******************************************************************/
/* 微秒延时函数 */
/******************************************************************/
void delay_ms(unsigned int Ms)//delay us
{
while(Ms--)
{
delay_us(100);
}
}
/*------------------------------------------------
主函数
------------------------------------------------*/
#define uchar unsigned char
#define uint unsigned int;
/******************************************************************/
/* 定义端口 */
/******************************************************************/
sbit seg1=P2^0;
sbit seg2=P2^1;
sbit seg3=P2^2;
sbit DQ=P1^3;//ds18b20 端口
sfr dataled=0x80;//显示数据端口
/******************************************************************/
/* 全局变量 */
/******************************************************************/
uint temp;
uchar flag_get,count,num,minute,second;
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//7段数码管段码表共阳
uchar str[6];
/******************************************************************/
/* 函数声明 */
/******************************************************************/
void delay1(uchar MS);
unsigned int ReadTemperature(void);
void Init_DS18B20(void);
unsigned char ReadOneChar(void);
void WriteOneChar(unsigned char dat);
void delay(unsigned int i);
/******************************************************************/
/* 主函数 */
/******************************************************************/
main()
{
unsigned char TempH,TempL;
TMOD|=0x01;//定时器设置
TH0=0xef;
TL0=0xf0;
IE=0x82;
TR0=1;
P2=0x00;
count=0;
while(1)
{
str[5]=0x39; //显示C符号
str[1]=tab[TempH/100]; //十位温度
str[2]=tab[(TempH%100)/10]; //十位温度
str[3]=tab[(TempH%100)%10]|0x80; //个位温度,带小数点
str[4]=tab[TempL];
if(flag_get==1) //定时读取当前温度
{
temp=ReadTemperature();
if(temp&0x8000)
{
str[0]=0x40;//负号标志
temp=~temp; // 取反加1
temp +=1;
}
else
str[0]=0;
TempH=temp>>4;
TempL=temp&0x0F;
TempL=TempL*6/10;//小数近似处理
flag_get=0;
}
}
}
/******************************************************************/
/* 定时器中断 */
/******************************************************************/
void tim(void) interrupt 1 using 1//中断,用于数码管扫描和温度检测间隔
{
TH0=0xef;//定时器重装值
TL0=0xf0;
num++;
if (num==50)
{num=0;
flag_get=1;//标志位有效
second++;
if(second>=60)
{second=0;
minute++;
}
}
count++;
if(count==1)
{P2=0;
dataled=str[0];}//数码管扫描
if(count==2)
{P2=1;
dataled=str[1];}
if(count==3)
{ P2=2;
dataled=str[2];
}
if(count==4)
{ P2=3;
dataled=str[3];
}
if(count==5)
{ P2=4;
dataled=str[4];
}
if(count==6)
{ P2=5;
dataled=str[5];
count=0;}
}
/******************************************************************/
/* 延时函数 */
/******************************************************************/
void delay(unsigned int i)//延时函数
{
while(i--);
}
/******************************************************************/
/* 初始化 */
/******************************************************************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay(10);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(5);
}
/******************************************************************/
/* 读一个字节 */
/******************************************************************/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay(5);
}
return(dat);
}
/******************************************************************/
/* 写一个字节 */
/******************************************************************/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat>>=1;
}
delay(5);
}
/******************************************************************/
/* 读取温度 */
/******************************************************************/
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned int b=0;
unsigned int t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay(200);
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //低位
b=ReadOneChar(); //高位
b<<=8;
t=a+b;
return(t);
}
3 演示
(1)实物测试
(2)Proteus仿真
配套演示例程
4 总结
DS18B20在实际应用中具有重要的价值,主要体现在以下方面:
- 高精度温度测量:DS18B20以其高精度的温度测量能力(±0.5°C),可用于对温度精度要求较高的应用场景,如医疗设备、实验室仪器等。
- 数字输出便捷性:由于DS18B20输出为数字格式,与微处理器的接口简单,便于数据处理和集成到各种数字化系统中。
- 灵活性和多功能性:DS18B20支持不同分辨率的温度测量,允许多个传感器在同一总线上工作,提供了灵活性和多样化的应用选择。
- 节能环保:DS18B20在待机模式下功耗很低,适合电池供电的应用,有助于节约能源和延长设备使用时间。
- 应用广泛:DS18B20被广泛应用于工业控制系统、家用电器、汽车电子、气象站、数据中心等领域,为各种温度监测和控制任务提供可靠的解决方案。
- 成本效益:相对于一些其他高精度温度传感器,DS18B20的成本较低,提供了一种经济实惠的温度测量解决方案。
总的来说,DS18B20作为一款可靠、高性能且成本效益高的数字温度传感器,提供了精准、便捷、节能的温度监测解决方案,对于许多行业和领域的温度控制和监测具有重要的应用价值。
配套演示例程