DS18B20温度传感器使用简介
DS18xx系列温度传感器是数字式温度传感器,相对于传统温度传感器精度高、稳定性好、电路简单、控制方便,在这里以DS18B20为例做简单应用介绍。详细资料请参阅芯片手册。
一、特性:
(1)应用中不需要外部任何元器件即可实现测温电路。
(2)测温范围-55~+125℃,最大精度0.0625℃。
(3)只通过一条数据线即可实现通信。
(4)每个DS1820器件上都有独一无二的序列号,所以一条数据线上可以挂接很多该传感器。
(5)内部有温度上、下限告警功能。
二、操作简介
DS18B20工作时需要接收特定的指令来完成相应功能(指令,可以简单的理解为可以被识别并有相应意义的一系列高低电平信号),它的指令可分为ROM指令和RAM指令;ROM指令主要对其内部的ROM进行操作,如查所使用DS18B20的序列号等,如果只使用一个DS18B20,ROM操作一般就可以直接跳过了;RAM指令主要是完成对其内RAM中的数据进行操作,如让其开始进行数据采集、读数据等。DS18B20数字温度传感器是单总线器件,数据的读写只通过一条数据线进行并且这一条线上允许挂很多该传感器;这样对器件进行读写指令时就会麻烦一些,必须应用特定时序来识别高低电平信号(如写高电平1,并不是把数据线直接拉高,而是用有一定时序关系的高低电平来代表写1),所以指令表中的0、1在写给DS18B20时就得变成代表0、1电平的时序段序列。同样,从DS18B20读数据时,也是由特定的时序来完成数据读取。
对DS18B20进行读写的时序图如下:
硬件连接方式有两种,一种是由单独电源供电(3~5V);第二种是由数据线为DS18B20供电(工作速度相对较慢)。
单独电源供电方式
数据线为DS1820供电方式
三、DS1820的工作过程:
- 复位操作
- 执行ROM操作的5条指令之一:1)读ROM,2)匹配ROM,3)搜索ROM,4)跳过ROM,5)报警搜索。
- 存储器操作命令:温度转换、读取温度、设定上下限温度值等指令
- 读取温度数据:主机读取温度数据后进行数据处理。
可以初始化数据精度,按芯片手册写入固定指令。数据位数可设置成9、10、11、12位,其中7位为温度整数部分,1位表示温度正负,其余位数为小数。如9位数据时,有1位为小数,精度为0.5。
四、指令功能介绍:
(1)ROM操作指令:
1. 读ROM指令 :Read ROM [33h]
这个命令允许总线控制器读到DS1820 的8 位系列编码、唯一的序列号和8 位CRC 码。只有在总线上存在单只DS1820 的时候才能使用这个命令。如果总上有不止一个从机,当所有从机试图同时传送信号时就会发生数据冲突(漏极开路连在一起开成相与的效果)。
2. 匹配ROM指令 :Match ROM [55h]
匹配ROM 命令,后跟64 位ROM 序列,让总线控制器在多点总线上定位一只特定的DS1820。只有和64 位ROM 序列完全匹配的DS1820 才能响应随后的存储器操作命令。所有和64 位ROM序列不匹配的从机都将等待复位脉冲。这条命令在总线上有单个或多个器件时都可以使用。
3. 跳过ROM指令:Skip ROM [CCh]
这条命令允许总线控制器不用提供64 位ROM 编码就使用存储器操作命令,在单点总线情况下右以节省时间。如果总线上不止一个从机,在Skip ROM 命令之后跟着发一条读命令,由于多个从机同时传送信号,总线上就会发生数据冲突(漏极开路下拉效果相当于相与)。
4. 搜索ROM指令:Search ROM [F0h]
当一个系统初次启动时,总线控制器可能并不知道单线总线上有多少器件或它们的64 位ROM编码。搜索ROM 命令允许总线控制器用排除法识别总线上的所有从机的64 位编码。
5. 报警搜索指令:Alarm Search [ECh]
这条命令的流程图和Search ROM 相同。然而,只有在最近一次测温后遇到符合报警条件的情况,DS18B20 才会响应这条命令。报警条件定义为温度高于TH 或低于TL。只要DS18B20 不掉电,报警状态将一直保持,直到再一次测得的温度值达不到报警条件。
(2)存储器操作指令:
五、复位时序:
DS18B20 需要严格的协议以确保数据的完整性。协议包括几种单线信号类型:复位脉冲、存在脉冲、写0、写1、读0 和读1。所有这些信号,除存在脉冲外,都是由总线控制器发出的。和DS18B20 间的任何通讯都需要以初始化序列开始,初始化序列见上图。一个复位脉冲跟着一个存在脉冲表明DS18B20 已经准备好发送和接收数据(适当的ROM 命令和存储器操作命令)。
六、数据处理:
下面以9位温度数据格式为例。
DS18B20 内部对此计算的结果可提供0.5℃的分辨力。温度以16位带符号位扩展的二进制补码形式读出,表1 给出了温度值和输出数据的关系。数据通过单线接口以串行方式传输。DS1820 测温范围-55℃~+125℃,以0.5℃递增。如用于华氏温度,必须要用一个转换因子查找表。读取数据时需要读取前16位数据,低字节在前,高字节为符号为。
DS1820 内温度表示值为1/2℃LSB,如下所示9位格式:
表1 温度值和输出数据的关系
七、应用实例:数字电子温度计
硬件为:单片机、数码管、温度传感器DS18B20
功能:显示当前温度值,可显示正和负温度值
程序:
#include<reg52.h>
/*------SEG PORT-----*/
#define LEDADDR P2
#define LED_port P0
/*------DS18B20 PORT-----*/
sbit DB_B20=P0^0;
/*-----COMMON FUNCTION----*/
void delay_us(unsigned int time);
/*-----SEG FUNCTION-------*/
unsigned char seg_val[6];
unsigned char ledcode[12] = {0XC0,0XF9,0XA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0xff};//共阳极数码管0,1,2,3,4,5,6,7,8,9,-,null
unsigned char currled=0;
unsigned char led_en=0x04;//
void display(void);
void display_tem(void);
/*--- DS18B20 FUNCTION-----*/
unsigned char tem_pnt;
unsigned char tem_num;
bit tem_sign;
bit reset_B20(void);
unsigned char read_b20_byte(void);
void write_b20_byte(unsigned char);
void convert_cmd_b20(void);
void read_cmd_b20(void);
void data_convert_b20(void);
/*--- TIME FUNCTION-----*/
unsigned char times;
void times_init(void);
/*-----------------------*/
main()
{
times_init();
while(1)
{
display_tem();
display();
}
}
/*-----COMMON FUNCTION----*/
void delay_us(unsigned int us)
{
while(us--);//for(;us>0;us--);//while(time--);
}
/*-----SEG FUNCTION-------*/
void display(void)
{
LEDADDR=0xff;
LED_port=(LED_port&0x03)|led_en;
led_en<<=1;
if(currled==1)
LEDADDR=ledcode[seg_val[currled]]& 0x7f;
else
LEDADDR=ledcode[seg_val[currled]];
currled++;
if(currled==6)
{
currled=0;
led_en=0x04;
}
delay_us(300);
}
void display_tem(void)
{
unsigned char n;
unsigned char p;
if(tem_sign==0)
{
n=~(tem_num-1);
p=~(tem_pnt-1);
}
else
{
n=tem_num;
p=tem_pnt;
}
seg_val[5]=11;
seg_val[4]=11;
seg_val[3]=n/100;
n=n%100;
seg_val[2]=n/10;
if(seg_val[3]==0)
{
seg_val[3]=11;
if(seg_val[2]==0)
seg_val[2]=11;
}
seg_val[1]=n%10;
seg_val[0]=p;
if(seg_val[2]==11 && seg_val[3]==11 && tem_sign==0)
seg_val[2]=10;
else if(seg_val[3]==11 && tem_sign==0)
seg_val[3]=10;
else if(tem_sign==0)
seg_val[4]=10;
}
/*--- DS18B20 FUNCTION-----*/
bit reset_B20(void)
{
bit state;
DB_B20=0;
delay_us(29);//>480us 29
DB_B20=1;
delay_us(3);//15---60us 3
state=DB_B20;
delay_us(25);//480us 25
return state;
}
void write_b20_byte(unsigned char cmd)
{
unsigned char i;
for(i=0;i<8;i++)
{
DB_B20=0;
DB_B20=cmd&0x01;
delay_us(5);
DB_B20=1;
cmd>>=1; //6
}
delay_us(5);
}
unsigned char read_b20_byte(void)
{
unsigned char rbyte=0;
unsigned char i;
for(i=0;i<8;i++)
{
rbyte>>=1;
DB_B20=0;
DB_B20=1;
//delay_us(1);
if(DB_B20)
rbyte |= 0x80;
delay_us(6); //6
}
return rbyte;
}
void convert_cmd_b20(void)
{
reset_B20();
write_b20_byte(0xcc);
write_b20_byte(0x44);
}
void read_cmd_b20(void)
{
reset_B20();
write_b20_byte(0xcc);
write_b20_byte(0xbe);
}
void data_convert_b20(void)
{
unsigned char a;
unsigned char b;
int point;
a=read_b20_byte();
b=read_b20_byte();
point=(a & 0x0f)*625+500;
tem_pnt=point/1000;
tem_num=a>>4 | b<<4;
if(tem_num & 0x80)
tem_sign=0;
else
tem_sign=1;
}
/*--- TIME FUNCTION-----*/
void times_init(void)
{
times=29;
TMOD=0X01;
TH0=0X3C;
TL0=0XB0;
EA=1;
ET0=1;
TR0=1;
}
void time0(void) interrupt 1
{
if(times==19)
convert_cmd_b20();
else if(times==9)
read_cmd_b20();
else if(times==0)
{
data_convert_b20();
times=29;
}
times--;
TH0=0X3C;
TL0=0XB0;
}
/*---------------------*/
截图: