DS18B20.docx
《DS18B20.docx》由会员分享,可在线阅读,更多相关《DS18B20.docx(16页珍藏版)》请在冰豆网上搜索。
DS18B20
数字温度传感器DS18B20中文资料(含读写程序)-
DS18B20特点
1.单线结构,只需一根信号线和CPU相连。
2.不需要外部元件,直接输出串行数据。
3.可不需要外部电源,直接通过信号线供电,电源电压范围为3.3V~5V。
4.测温精度高,测温范围为:
一55℃~+125℃,在-10℃~+85℃范围内,精度为±O.5℃。
5.测温分辨率高,当选用12位转换位数时,温度分辨率可达0.0625℃。
6.数字量的转换精度及转换时间可通过简单的编程来控制:
9位精度的转换时间为93.75ms:
10位精度的转换时间187.5ms:
12位精度的转换时间750ms。
7.具有非易失性上、下限报警设定的功能,用户可方便地通过编程修改上、下限的数值。
8.可通过报警搜索命令识别哪片DS18820采集的温度超越上、下限。
DS18B20引脚及管脚功能介绍
DS18B20的常用封装有3脚、8脚等几种形式,如图1所示。
各脚含义如下:
DQ:
数字信号输入/输出端。
GND:
电源地端。
VDD:
外接供电电源输入端(在寄生电源接线时此脚应接地)。
DS18B20内部结构简要介绍:
DS18820的内部结构如图3所示:
主要有64位光刻ROM、温度传感器、非易失性温度报警触发器TH和TL、配置寄存器等组成。
1.64位光刻ROM是生产厂家给每一个出厂的DS18820命名的产品序列号,可以看作为该器件的地址序列号。
其作用是使每一个出厂的DS18820地址序列号都各不相同,这样,就可以实现一根总线上挂接多个DS18820的目的。
2.DS18820中的温度传感器完成对温度的测量,输出格式为:
16位符号扩展的二进制补码。
当测温精度设置为12位时,分辨率为O.0625℃,即O.0625℃/LSB。
其二进制补码格式如图2所示。
其中,S为符号位,S=1,表示温度为负值;S=0,表示温度为正值。
例如+125℃的数字输出为07D0H,-55℃的数字输出为FC90H。
一些温度值对应的数字输出如图4所示。
3.DS18820中的低温触发器TL、高温触发器TH,用于设置低温、高温的报警数值。
DS18820完成一个周期的温度测量后,将测得的温度值和TL、TH相比较,如果小于TL,或大于TH,则表示温度越限,将该器件内的告警标志位置位,并对主机发出的告警搜索命令作出响应。
需要修改上、下限温度值时,只需使用一个功能命令即可对TL、TH写入,十分方便。
4.DS18820中的高速暂存器是一个9字节的存储器,其含意如图5所示。
开始两个字节为被测温度的数字量,其含义如图2所示。
第3、4、5字节分别为TH、TL、配置寄存器的复制,每一次上电复位时被重写。
配置寄存器有R0、R1组成,其值决定温度转换的精度位数、转换时间等,含义如图6所示。
第7字节为测温计数的剩余值。
第8字节为测温时每度的计数值。
第9字节读出的是前8个字节的CRC校验码,通过此码,可判断通讯是否正确。
DS18B20的读写操作介绍
(一)ROM操作命令:
1.读命令(33H):
通过该命令主机可以读出DS18820的ROM中的8位系列产品代码、48位产品序列号和8位CRC校验码。
该命令仅限于单个DS18B20在线的情况。
2.选择定位命令(55H):
当多片DS18820在线时,主机发出该命令和一个64位数,DS18820内部ROM与主机一致者,才响应命令。
该命令也可用于单个DS18820的情况。
3.查询命令(0F0H):
该命令可查询总线上DS18B20的数目及其64位序列号。
4.跳过ROM序列号检测命令(OCCH):
该命令允许主机跳过ROM序列号检测而直接对寄存器操作,该命令仅限于单个DS18820在线的情况。
5.报警查询命令(0ECH):
只有报警标志置位后,DS18B20才相应该命令。
(二)存储器操作命令:
1.写入命令(4EH):
该命令可写入寄存器的第2、3、4字节,即高低温寄存器和配置寄存器。
复位信号发出之前,三个字节必须写完。
2.读出命令(0BEH):
该命令可读出寄存器中的内容,复位命令可终止读出。
3.开始转换命令(44H):
该命令使DS18B20立即开始温度转换,当温度转换正在进行时,主机这时读总线将收到O;当温度转换结束时,主机这时读总线将收到1。
若用信号线给DS18820供电,则主机发出转换命令后,必须提供至少相应于分辨率的温度转换时间的上拉电平。
4.回调命令(088H):
该命令把EEROM中的内容写到寄存器TH、TL及配置寄存器中。
DS18820上电时能自动写入。
5.复制命令(48H):
该命令把寄存器TH、TL及配置寄存器中的内容写到EEROM中。
6读电源标志命令(084H):
主机发出该命令后,DS18B20将进行响应,发送电源标志,信号线供电发O,外接电源发1。
(三)DS18820的复位及读写时序:
1.复位:
对DS18B20操作之前,首先要将它复位。
复位时序为:
(1)主机将信号线置为低电平,时间为480~960μS。
(2)主机将信号线置为高电平,时间为15~60μS。
(3)DS18B20发出60~240μS的低电平作为应答信号。
主机收到此信号后,才能对DS18820作其它操作。
2.写操作:
主机将信号线从高电平拉至低电平,产生写起始信号。
从信号线的下降沿开始,在15~60μS的时间内DS18820对信号线检测,如信号线为高电平,则写1,如信号线为O,则写0,从而完成了一个写周期。
在开始另一个写周期前,必须有1μS以上的高电平恢复期。
3.读操作:
主机将信号线从高电平拉低至低电平1μS以上,再使数据线升为高电平,产生读起始信号。
从主机将信号线从高电平拉低至低电平起15~60μS的时间内,DS18820将数据放到信号线上,供主机读取。
从而完成了一个读周期。
在开始另一个读周期前,必须有1μS以上的高电平恢复期。
是LCD1602显示的.
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit DQ = P3^3; //定义DS18B20端口DQ
sbit BEEP=P3^7 ; //蜂鸣器驱动线
bit presence ;
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
uchar code cdis1[ ] = {" DS18B20 OK "};
uchar code cdis2[ ] = {" "};
uchar code cdis3[ ] = {" DS18B20 ERR0R "};
uchar code cdis4[ ] = {" PLEASE CHECK "};
unsigned char data display[2] = {0x00,0x00};
unsigned char data RomCode[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char Temp;
unsigned char crc;
void beep();
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
/*******************************************************************/
void delay1(int ms)
{
unsigned char y;
while(ms--)
{
for(y = 0; y<250; y++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/******************************************************************/
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。
lcd-busy为0时,闲,可写指令与数据。
*/
/* */
/******************************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/*******************************************************************/
/* */
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
*/
/* */
/*******************************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/*******************************************************************/
/* */
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。
*/
/* */
/*******************************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/*******************************************************************/
/* */
/* LCD初始化设定 */
/* */
/*******************************************************************/
void lcd_init()
{
delay1(15);
lcd_wcmd(0x01); //清除LCD的显示内容
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay1(5);
lcd_wcmd(0x38);
delay1(5);
lcd_wcmd(0x38);
delay1(5);
lcd_wcmd(0x0c); //显示开,关光标
delay1(5);
lcd_wcmd(0x06); //移动光标
delay1(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay1(5);
}
/*******************************************************************/
/* */
/* 设定显示位置 */
/* */
/*******************************************************************/
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80); //数据指针=80+地址变量
}
/*******************************************************************/
/* */
/*us级延时函数 */
/* */
/*******************************************************************/
void Delay(unsigned int num)
{
while( --num );
}
/*******************************************************************/
/* */
/*初始化ds1820 */
/* */
/*******************************************************************/
Init_DS18B20(void)
{
DQ = 1; //DQ复位
Delay(8); //稍做延时
DQ = 0; //将DQ拉低
Delay(90); //精确延时 大于 480us
DQ = 1; //拉高总线
Delay(8);
presence = DQ; //读取存在信号
Delay(100);
DQ = 1;
return(presence); //返回信号,0=presence,1= no presence
}
/*******************************************************************/
/* */
/* 读一位(bit) */
/* */
/*******************************************************************/
uchar read_bit(void)
{
unsigned char i;
DQ = 0; //将DQ 拉低开始读时间隙
DQ = 1; // then return high
for (i=0; i<3; i++); // 延时15μs
return(DQ); // 返回 DQ 线上的电平值
}
/*******************************************************************/
/* */
/* 读一个字节 */
/* */
/*******************************************************************/
ReadOneChar(void)
{
unsigned char i = 0;
unsigned char dat = 0;
//for (i = 8; i > 0; i--)
// {
// read_bit();
// DQ = 0; // 给脉冲信号
// dat >>= 1;
// DQ = 1; // 给脉冲信号
for (i=0;i<8;i++)
{ // 读取字节,每次读取一个字节
if(read_bit()) dat|=0x01<
// if(DQ)
// dat |= 0x80;
Delay(4);
}
return (dat);
}
/*******************************************************************/
/* */
/* 写一位 */
/* */
/*******************************************************************/
void write_bit(char bitval) {
DQ = 0; // 将DQ 拉低开始写时间隙
if(bitval==1) DQ =1; // 如果写1,DQ 返回高电平
Delay(5); // 在时间隙内保持电平值,
DQ = 1; // Delay函数每次循环延时16μs,因此delay(5) = 104μs
}
/*******************************************************************/
/* */
/* 写一个字节 */
/* */
/*******************************************************************/
WriteOneChar(unsigned char dat)
{
un