ds18b20资料及程序范文第1篇
1.1 DS18B20简介
DS18B20是美国DALLAS半导体公司生产的可组网数字式温度传感器. 主要由三个数据部件组成:64的激光ROM,温度灵敏原件,非易失性温度告警触发器TH和TL。 封装如图一:
图一 1.
2DS18B20的特点:
1. 独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。
2. DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现多点测温。 3. DS18B20在使用中不需要任何外围元件。
4. 测温范围-55℃~+125℃,固有测温分辨率0.5℃。 5. 测量结果以9位数字量方式串行传送。
内部结构框图如图二所示。
图二
2.1 访问温度计的协议:
(一)初始化
(二)ROM操作命令
(三)存贮器操作命令
(四)处理/数据
由热敏原件中晶振特性计算出所测的温度。 注意:复位操作如下图三
图三 必需要给DS18B20输入脉冲激活其复位功能。
DS18B20的驱动程序:
/*************************此部分为18B20的驱动程序*************************************/
#include #include sbit D18B20=P3^7; sbit error=P3^4; #define NOP() _nop_() /* 定义空指令 */ #define _Nop() _nop_() /*定义空指令*/ void TempDelay (unsigned char idata us); void Init18b20 (void); void WriteByte (unsigned char idata wr); //单字节写入 void read_bytes (unsigned char idata j); unsigned char CRC (unsigned char j); void GemTemp (void); void Config18b20 (void); void ReadID (void); void TemperatuerResult(void); bit flag; unsigned int idata Temperature; unsigned char idata temp_buff[9]; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节 unsigned char idata id_buff[8];
unsigned char idata crc_data; unsigned char code CrcTable [256]={ 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
void GetTemp() {
if(TIM==100)
{ TIM=0;
TemperatuerResult();
每隔 1000ms 读取温度。
void TemperatuerResult(void) {
p = id_buff;
ReadID();
//先确定是第几个DS18B20
Config18b20(); //配置DS18B20的报警温度和分辨度
Init18b20 ();
//复位)
WriteByte(0xcc);
//skip rom
WriteByte(0x44);
//Temperature convert
Init18b20 ();
//复位)
WriteByte(0xcc);
//skip rom
WriteByte(0xbe);
//read Temperature
p = temp_buff;
GemTemp(); //读取温度
}
void GemTemp (void) {
read_bytes (9);
if (CRC(9)==0) //校验正确
{
Temperature = temp_buff[1]*0x100 + temp_buff[0]; //
Temperature *= 0.0625;
Temperature /= 16;
TempDelay(1);
} } *Function:CRC校验 *parameter: *Return: *Modify: *************************************************************/ unsigned char CRC (unsigned char j) {
unsigned char idata i,crc_data=0;
for(i=0;i
crc_data = CrcTable[crc_data^temp_buff[i]];
return (crc_data); }
/************************************************************ *Function:向18B20写入一个字节 *parameter: *Return: *Modify:
void WriteByte (unsigned char idata wr) //单字节写入 {
unsigned char idata i;
for (i=0;i<8;i++)
{
D18B20 = 0;
_nop_();
D18B20=wr&0x01;
TempDelay(3);
//delay 45 uS //
5 _nop_();
_nop_();
D18B20=1;
wr >>= 1;
} }
/************************************************************ *Function:读18B20的一个字节 *parameter: *Return: *Modify: *************************************************************/ unsigned char ReadByte (void)
//读取单字节
unsigned char idata i,u=0;
for(i=0;i<8;i++)
{
D18B20 = 0;
u >>= 1;
D18B20 = 1;
if(D18B20==1)
u |= 0x80;
TempDelay (2);
_nop_();
}
return(u); } /************************************************************ *Function:读18B20 *parameter: *Return: *Modify: *************************************************************/ void read_bytes (unsigned char idata j) {
unsigned char idata i;
for(i=0;i
{
*p = ReadByte();
p++;
} } /************************************************************ *Function:延时处理 *parameter: *Return: *Modify: *************************************************************/ void TempDelay (unsigned char idata us) {
while(us--); } /************************************************************ *Function:18B20初始化 *parameter: *Return: *Modify: *************************************************************/ void Init18b20 (void) {
D18B20=1;
_nop_();
D18B20=0;
TempDelay(80);
//delay 530 uS//80
_nop_();
D18B20=1;
TempDelay(14);
//delay 100 uS//14
_nop_();
_nop_();
_nop_();
if(D18B20==0)
{flag = 1; error=0; }
//detect 1820 success!
else
{flag = 0; error=1; }
//detect 1820 fail!
TempDelay(20);
//20
_nop_();
_nop_();
D18B20 = 1; }
/************************************************************
向18B20写入一个字节 *parameter: *Return: *Modify: *************************************************************/ void WriteByte (unsigned char idata wr) //单字节写入 {
unsigned char idata i;
for (i=0;i<8;i++)
{
D18B20 = 0;
_nop_();
D18B20=wr&0x01;
TempDelay(3);
//delay 45 uS //5
_nop_();
_nop_();
D18B20=1;
wr >>= 1;
} }
/************************************************************
读18B20的一个字节
*/ unsigned char ReadByte (void)
//读取单字节 {
unsigned char idata i,u=0;
for(i=0;i<8;i++)
{
D18B20 = 0;
u >>= 1;
D18B20 = 1;
if(D18B20==1)
u |= 0x80;
TempDelay (2);
_nop_();
}
return(u); }
/************************************************************ 3.1.2
SPI数据线配置。
/*************************此部分为74HC595的驱动程序使用SPI总线连接*************************************/
#include #include
#define NOP()
_nop_()
/* 定义空指令 */ #define _Nop() _nop_()
/*?定义空指令*/ void HC595SendData(unsigned int SendVal);
//SPI IO sbit
MOSIO =P1^5; sbit
R_CLK =P1^6; sbit
S_CLK =P1^7; sbit
IN_PL =P3^4;
//74HC165 shift load
把数据加载到锁存器中 sbit
IN_Dat=P3^5;
//74HC165 output
数据移出 sbit
OE
=P3^6;
/********************************************************************************************************* ** 函数名称: HC595SendData ** 功能描述: 向SPI总线发送数据
*********************************************************************************************************/ void HC595SendData(unsigned int SendVal) {
unsigned char i;
for(i=0;i<16;i++)
{
if((SendVal<
else MOSIO=0;
S_CLK=0;
NOP();
NOP();
S_CLK=1;
}
R_CLK=0; //set dataline low
NOP();
NOP();
R_CLK=1; //片选
OE=0; }
3.1.
3试验数码管上显示温度
#include extern GetTemp();
//声明引用外部函数 extern unsigned int idata Temperature;
// 声明引用外部变量 void delay(unsigned int i);
sbit
LS138A=P2^2;
//管脚定义 sbit
LS138B=P2^3; sbit
LS138C=P2^4;
//此表为 LED 的字模, 共阴数码管 0-9 -
unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; unsigned long LedOut[5],LedNumVal; void system_Ini() {
TMOD|= 0x11;
TH1 = 0xD8;
//10
TL1 = 0xF0;
IE = 0x8A;
TR1 = 1 main() { unsigned char i;
system_Ini();
while(1)
{
GetTemp();
/********以下将读18b20的数据送到LED数码管显示*************/
LedNumVal=Temperature;
//把实际温度送到LedNumVal变量中
LedOut[0]=Disp_Tab[LedNumVal%10000/1000];
LedOut[1]=Disp_Tab[LedNumVal%1000/100];
LedOut[2]=Disp_Tab[LedNumVal%100/10]; //十位
LedOut[3]=Disp_Tab[LedNumVal%10];
//个位
for(i=0; i<4; i++)
{
P0 = LedOut[i] ;
switch(i)
{
//138译码
case 0:LS138A=0; LS138B=0; LS138C=0; break;
case 1:LS138A=1; LS138B=0; LS138C=0; break;
case 2:LS138A=0; LS138B=1; LS138C=0; break;
case 3:LS138A=1; LS138B=1; LS138C=0; break;
}
delay(100);
}
P0 = 0;
} }
//延时程序
void delay(unsigned int i) {
char j;
for(i; i > 0; i--)
for(j = 200; j > 0; j--); } 4.1 讨论DS18B20的自动报警功能实现。
DS18B20只是一个测温元件,所谓的报警功能要通过程序由单片机来实现。
DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的EERAM。高速暂存RAM的结构为8字节的存储器,头2个字节包含测得的温度信息,第3和第4字节TH(报警温度上限)和TL(报警温度下限)的拷贝。第5个字节,为配置寄存器,它的内容用于确定温度值的数字转换分辨率。第
6、
ds18b20资料及程序范文第2篇
2、 Match ROM[55H]
这个是匹配ROM命令,后跟64位ROM序列,让总线控制器在多点总线上定位一只特定的DS18B20。只有和64位ROM序列完全匹配的DS18B20才能响应随后的存储器操作。所有和64位ROM序列不匹配的从机都将等待复位脉冲。这条命令在总线上有单个或多个器件时都可以使用。
3、Skip ROM[0CCH]
这条命令允许总线控制器不用提供64位ROM编码就使用存储器操作命令,在单点总线情况下,可以节省时间。如果总线上不止一个从机,在Skip ROM命令之后跟着发一条读命令,由于多个从机同时传送信号,总线上就会发生数据冲突(漏极开路下拉效果相当于相“与”)
4、Search ROM[0F0H]
当一个系统初次启动时,总线控制器可能并不知道单线总线上有多个器件或它们的64位编码,搜索ROM命令允许总线控制器用排除法识别总线上的所有从机的64位编码。
5、Alarm Search[0ECH]
这条命令的流程和Search ROM相同。然而,只有在最近一次测温后遇到符合报警条件的情况,DS18B20才会响应这条命令。报警条件定义为温度高于TH或低于TL。只要DS18B20不掉电,报警状态将一直保持,知道再一次测得的温度值达不到报警条件。
6、Write Scratchpad[4EH]
这个命令向DS18B20的暂存器TH和TL中写入数据。可以在任何时刻发出复位命令来中止写入。
7、Read Scratchpad[0BEH]
这个命令读取暂存器的内容。读取将从第1个字节开始,一直进行下去,直到第9(CRC)字节读完。如果不想读完所有字节,控制器可以在任何时间发出复位命令来中止读取。
8、Copy Scratchpad[48H]
这个命令把暂存器的内容拷贝到DS18B20的E2ROM存储器里,即把温度报警触发字节存入非易失性存储器里。如果总线控制器在这条命令之后跟着发出读时间隙,而DS18B20又忙于把暂存器拷贝到E2存储器,DS18B20就会输出一个0,如果拷贝结束的话,DS18B20则输出1。如果使用寄生电源,总线控制器必须在这条命令发出后立即启动强上拉并保持10ms。
9、Convert T[44H]
这条命令启动一次温度转换而无需其他数据。温度转换命令被执行,而后DS18B20保持等待状态。如果总线控制器在这条命令之后跟着发出时间隙,而DS18B20又忙于做时间转换的话,DS18B20将在总线上输出0,若温度转换完成,则输出1,。如果使用寄生电源,总线控制必须在发出这条命令后立即启动强上拉,并保持500ms以上时间。
10、Recall E2
这条命令把报警触发器里的值拷贝回暂存器。这种拷贝操作在DS18B20上电时自动执行,这样器件一上电,暂存器里马上就存在有效的数据了。若在这条命令发出之后发出读数据隙,器件会输出温度转换忙的标识:0为忙,1为完成。
11、Read Power Supply[0B4H]
ds18b20资料及程序范文第3篇
1.1 DS18B20简介
DS18B20是美国DALLAS半导体公司生产的可组网数字式温度传感器. 主要由三个数据部件组成:64的激光ROM,温度灵敏原件,非易失性温度告警触发器TH和TL。 封装如图一:
图一 1.
2DS18B20的特点:
1. 独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。
2. DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现多点测温。 3. DS18B20在使用中不需要任何外围元件。
4. 测温范围-55℃~+125℃,固有测温分辨率0.5℃。 5. 测量结果以9位数字量方式串行传送。
内部结构框图如图二所示。
图二
2.1 访问温度计的协议:
(一)初始化
(二)ROM操作命令
(三)存贮器操作命令
(四)处理/数据
由热敏原件中晶振特性计算出所测的温度。 注意:复位操作如下图三
图三 必需要给DS18B20输入脉冲激活其复位功能。
DS18B20的驱动程序:
/*************************此部分为18B20的驱动程序*************************************/
#include #include sbit D18B20=P3^7; sbit error=P3^4; #define NOP() _nop_() /* 定义空指令 */ #define _Nop() _nop_() /*定义空指令*/ void TempDelay (unsigned char idata us); void Init18b20 (void); void WriteByte (unsigned char idata wr); //单字节写入 void read_bytes (unsigned char idata j); unsigned char CRC (unsigned char j); void GemTemp (void); void Config18b20 (void); void ReadID (void); void TemperatuerResult(void); bit flag; unsigned int idata Temperature; unsigned char idata temp_buff[9]; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节 unsigned char idata id_buff[8];
unsigned char idata crc_data; unsigned char code CrcTable [256]={ 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
void GetTemp() {
if(TIM==100)
{ TIM=0;
TemperatuerResult();
每隔 1000ms 读取温度。
void TemperatuerResult(void) {
p = id_buff;
ReadID();
//先确定是第几个DS18B20
Config18b20(); //配置DS18B20的报警温度和分辨度
Init18b20 ();
//复位)
WriteByte(0xcc);
//skip rom
WriteByte(0x44);
//Temperature convert
Init18b20 ();
//复位)
WriteByte(0xcc);
//skip rom
WriteByte(0xbe);
//read Temperature
p = temp_buff;
GemTemp(); //读取温度
}
void GemTemp (void) {
read_bytes (9);
if (CRC(9)==0) //校验正确
{
Temperature = temp_buff[1]*0x100 + temp_buff[0]; //
Temperature *= 0.0625;
Temperature /= 16;
TempDelay(1);
} } *Function:CRC校验 *parameter: *Return: *Modify: *************************************************************/ unsigned char CRC (unsigned char j) {
unsigned char idata i,crc_data=0;
for(i=0;i
crc_data = CrcTable[crc_data^temp_buff[i]];
return (crc_data); }
/************************************************************ *Function:向18B20写入一个字节 *parameter: *Return: *Modify:
void WriteByte (unsigned char idata wr) //单字节写入 {
unsigned char idata i;
for (i=0;i<8;i++)
{
D18B20 = 0;
_nop_();
D18B20=wr&0x01;
TempDelay(3);
//delay 45 uS //
5 _nop_();
_nop_();
D18B20=1;
wr >>= 1;
} }
/************************************************************ *Function:读18B20的一个字节 *parameter: *Return: *Modify: *************************************************************/ unsigned char ReadByte (void)
//读取单字节
unsigned char idata i,u=0;
for(i=0;i<8;i++)
{
D18B20 = 0;
u >>= 1;
D18B20 = 1;
if(D18B20==1)
u |= 0x80;
TempDelay (2);
_nop_();
}
return(u); } /************************************************************ *Function:读18B20 *parameter: *Return: *Modify: *************************************************************/ void read_bytes (unsigned char idata j) {
unsigned char idata i;
for(i=0;i
{
*p = ReadByte();
p++;
} } /************************************************************ *Function:延时处理 *parameter: *Return: *Modify: *************************************************************/ void TempDelay (unsigned char idata us) {
while(us--); } /************************************************************ *Function:18B20初始化 *parameter: *Return: *Modify: *************************************************************/ void Init18b20 (void) {
D18B20=1;
_nop_();
D18B20=0;
TempDelay(80);
//delay 530 uS//80
_nop_();
D18B20=1;
TempDelay(14);
//delay 100 uS//14
_nop_();
_nop_();
_nop_();
if(D18B20==0)
{flag = 1; error=0; }
//detect 1820 success!
else
{flag = 0; error=1; }
//detect 1820 fail!
TempDelay(20);
//20
_nop_();
_nop_();
D18B20 = 1; }
/************************************************************
向18B20写入一个字节 *parameter: *Return: *Modify: *************************************************************/ void WriteByte (unsigned char idata wr) //单字节写入 {
unsigned char idata i;
for (i=0;i<8;i++)
{
D18B20 = 0;
_nop_();
D18B20=wr&0x01;
TempDelay(3);
//delay 45 uS //5
_nop_();
_nop_();
D18B20=1;
wr >>= 1;
} }
/************************************************************
读18B20的一个字节
*/ unsigned char ReadByte (void)
//读取单字节 {
unsigned char idata i,u=0;
for(i=0;i<8;i++)
{
D18B20 = 0;
u >>= 1;
D18B20 = 1;
if(D18B20==1)
u |= 0x80;
TempDelay (2);
_nop_();
}
return(u); }
/************************************************************ 3.1.2
SPI数据线配置。
/*************************此部分为74HC595的驱动程序使用SPI总线连接*************************************/
#include #include
#define NOP()
_nop_()
/* 定义空指令 */ #define _Nop() _nop_()
/*?定义空指令*/ void HC595SendData(unsigned int SendVal);
//SPI IO sbit
MOSIO =P1^5; sbit
R_CLK =P1^6; sbit
S_CLK =P1^7; sbit
IN_PL =P3^4;
//74HC165 shift load
把数据加载到锁存器中 sbit
IN_Dat=P3^5;
//74HC165 output
数据移出 sbit
OE
=P3^6;
/********************************************************************************************************* ** 函数名称: HC595SendData ** 功能描述: 向SPI总线发送数据
*********************************************************************************************************/ void HC595SendData(unsigned int SendVal) {
unsigned char i;
for(i=0;i<16;i++)
{
if((SendVal<
else MOSIO=0;
S_CLK=0;
NOP();
NOP();
S_CLK=1;
}
R_CLK=0; //set dataline low
NOP();
NOP();
R_CLK=1; //片选
OE=0; }
3.1.
3试验数码管上显示温度
#include extern GetTemp();
//声明引用外部函数 extern unsigned int idata Temperature;
// 声明引用外部变量 void delay(unsigned int i);
sbit
LS138A=P2^2;
//管脚定义 sbit
LS138B=P2^3; sbit
LS138C=P2^4;
//此表为 LED 的字模, 共阴数码管 0-9 -
unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; unsigned long LedOut[5],LedNumVal; void system_Ini() {
TMOD|= 0x11;
TH1 = 0xD8;
//10
TL1 = 0xF0;
IE = 0x8A;
TR1 = 1 main() { unsigned char i;
system_Ini();
while(1)
{
GetTemp();
/********以下将读18b20的数据送到LED数码管显示*************/
LedNumVal=Temperature;
//把实际温度送到LedNumVal变量中
LedOut[0]=Disp_Tab[LedNumVal%10000/1000];
LedOut[1]=Disp_Tab[LedNumVal%1000/100];
LedOut[2]=Disp_Tab[LedNumVal%100/10]; //十位
LedOut[3]=Disp_Tab[LedNumVal%10];
//个位
for(i=0; i<4; i++)
{
P0 = LedOut[i] ;
switch(i)
{
//138译码
case 0:LS138A=0; LS138B=0; LS138C=0; break;
case 1:LS138A=1; LS138B=0; LS138C=0; break;
case 2:LS138A=0; LS138B=1; LS138C=0; break;
case 3:LS138A=1; LS138B=1; LS138C=0; break;
}
delay(100);
}
P0 = 0;
} }
//延时程序
void delay(unsigned int i) {
char j;
for(i; i > 0; i--)
for(j = 200; j > 0; j--); } 4.1 讨论DS18B20的自动报警功能实现。
DS18B20只是一个测温元件,所谓的报警功能要通过程序由单片机来实现。
DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的EERAM。高速暂存RAM的结构为8字节的存储器,头2个字节包含测得的温度信息,第3和第4字节TH(报警温度上限)和TL(报警温度下限)的拷贝。第5个字节,为配置寄存器,它的内容用于确定温度值的数字转换分辨率。第
6、
ds18b20资料及程序范文第4篇
1.1 DS18B20简介
DS18B20是美国DALLAS半导体公司生产的可组网数字式温度传感器. 主要由三个数据部件组成:64的激光ROM,温度灵敏原件,非易失性温度告警触发器TH和TL。 封装如图一:
图一 1.
2DS18B20的特点:
1. 独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。
2. DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现多点测温。 3. DS18B20在使用中不需要任何外围元件。
4. 测温范围-55℃~+125℃,固有测温分辨率0.5℃。 5. 测量结果以9位数字量方式串行传送。
内部结构框图如图二所示。
图二
2.1 访问温度计的协议:
(一)初始化
(二)ROM操作命令
(三)存贮器操作命令
(四)处理/数据
由热敏原件中晶振特性计算出所测的温度。 注意:复位操作如下图三
图三 必需要给DS18B20输入脉冲激活其复位功能。
DS18B20的驱动程序:
/*************************此部分为18B20的驱动程序*************************************/
#include #include sbit D18B20=P3^7; sbit error=P3^4; #define NOP() _nop_() /* 定义空指令 */ #define _Nop() _nop_() /*定义空指令*/ void TempDelay (unsigned char idata us); void Init18b20 (void); void WriteByte (unsigned char idata wr); //单字节写入 void read_bytes (unsigned char idata j); unsigned char CRC (unsigned char j); void GemTemp (void); void Config18b20 (void); void ReadID (void); void TemperatuerResult(void); bit flag; unsigned int idata Temperature; unsigned char idata temp_buff[9]; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节 unsigned char idata id_buff[8];
unsigned char idata crc_data; unsigned char code CrcTable [256]={ 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};
void GetTemp() {
if(TIM==100)
{ TIM=0;
TemperatuerResult();
每隔 1000ms 读取温度。
void TemperatuerResult(void) {
p = id_buff;
ReadID();
//先确定是第几个DS18B20
Config18b20(); //配置DS18B20的报警温度和分辨度
Init18b20 ();
//复位)
WriteByte(0xcc);
//skip rom
WriteByte(0x44);
//Temperature convert
Init18b20 ();
//复位)
WriteByte(0xcc);
//skip rom
WriteByte(0xbe);
//read Temperature
p = temp_buff;
GemTemp(); //读取温度
}
void GemTemp (void) {
read_bytes (9);
if (CRC(9)==0) //校验正确
{
Temperature = temp_buff[1]*0x100 + temp_buff[0]; //
Temperature *= 0.0625;
Temperature /= 16;
TempDelay(1);
} } *Function:CRC校验 *parameter: *Return: *Modify: *************************************************************/ unsigned char CRC (unsigned char j) {
unsigned char idata i,crc_data=0;
for(i=0;i
crc_data = CrcTable[crc_data^temp_buff[i]];
return (crc_data); }
/************************************************************ *Function:向18B20写入一个字节 *parameter: *Return: *Modify:
void WriteByte (unsigned char idata wr) //单字节写入 {
unsigned char idata i;
for (i=0;i<8;i++)
{
D18B20 = 0;
_nop_();
D18B20=wr&0x01;
TempDelay(3);
//delay 45 uS //
5 _nop_();
_nop_();
D18B20=1;
wr >>= 1;
} }
/************************************************************ *Function:读18B20的一个字节 *parameter: *Return: *Modify: *************************************************************/ unsigned char ReadByte (void)
//读取单字节
unsigned char idata i,u=0;
for(i=0;i<8;i++)
{
D18B20 = 0;
u >>= 1;
D18B20 = 1;
if(D18B20==1)
u |= 0x80;
TempDelay (2);
_nop_();
}
return(u); } /************************************************************ *Function:读18B20 *parameter: *Return: *Modify: *************************************************************/ void read_bytes (unsigned char idata j) {
unsigned char idata i;
for(i=0;i
{
*p = ReadByte();
p++;
} } /************************************************************ *Function:延时处理 *parameter: *Return: *Modify: *************************************************************/ void TempDelay (unsigned char idata us) {
while(us--); } /************************************************************ *Function:18B20初始化 *parameter: *Return: *Modify: *************************************************************/ void Init18b20 (void) {
D18B20=1;
_nop_();
D18B20=0;
TempDelay(80);
//delay 530 uS//80
_nop_();
D18B20=1;
TempDelay(14);
//delay 100 uS//14
_nop_();
_nop_();
_nop_();
if(D18B20==0)
{flag = 1; error=0; }
//detect 1820 success!
else
{flag = 0; error=1; }
//detect 1820 fail!
TempDelay(20);
//20
_nop_();
_nop_();
D18B20 = 1; }
/************************************************************
向18B20写入一个字节 *parameter: *Return: *Modify: *************************************************************/ void WriteByte (unsigned char idata wr) //单字节写入 {
unsigned char idata i;
for (i=0;i<8;i++)
{
D18B20 = 0;
_nop_();
D18B20=wr&0x01;
TempDelay(3);
//delay 45 uS //5
_nop_();
_nop_();
D18B20=1;
wr >>= 1;
} }
/************************************************************
读18B20的一个字节
*/ unsigned char ReadByte (void)
//读取单字节 {
unsigned char idata i,u=0;
for(i=0;i<8;i++)
{
D18B20 = 0;
u >>= 1;
D18B20 = 1;
if(D18B20==1)
u |= 0x80;
TempDelay (2);
_nop_();
}
return(u); }
/************************************************************ 3.1.2
SPI数据线配置。
/*************************此部分为74HC595的驱动程序使用SPI总线连接*************************************/
#include #include
#define NOP()
_nop_()
/* 定义空指令 */ #define _Nop() _nop_()
/*?定义空指令*/ void HC595SendData(unsigned int SendVal);
//SPI IO sbit
MOSIO =P1^5; sbit
R_CLK =P1^6; sbit
S_CLK =P1^7; sbit
IN_PL =P3^4;
//74HC165 shift load
把数据加载到锁存器中 sbit
IN_Dat=P3^5;
//74HC165 output
数据移出 sbit
OE
=P3^6;
/********************************************************************************************************* ** 函数名称: HC595SendData ** 功能描述: 向SPI总线发送数据
*********************************************************************************************************/ void HC595SendData(unsigned int SendVal) {
unsigned char i;
for(i=0;i<16;i++)
{
if((SendVal<
else MOSIO=0;
S_CLK=0;
NOP();
NOP();
S_CLK=1;
}
R_CLK=0; //set dataline low
NOP();
NOP();
R_CLK=1; //片选
OE=0; }
3.1.
3试验数码管上显示温度
#include extern GetTemp();
//声明引用外部函数 extern unsigned int idata Temperature;
// 声明引用外部变量 void delay(unsigned int i);
sbit
LS138A=P2^2;
//管脚定义 sbit
LS138B=P2^3; sbit
LS138C=P2^4;
//此表为 LED 的字模, 共阴数码管 0-9 -
unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; unsigned long LedOut[5],LedNumVal; void system_Ini() {
TMOD|= 0x11;
TH1 = 0xD8;
//10
TL1 = 0xF0;
IE = 0x8A;
TR1 = 1 main() { unsigned char i;
system_Ini();
while(1)
{
GetTemp();
/********以下将读18b20的数据送到LED数码管显示*************/
LedNumVal=Temperature;
//把实际温度送到LedNumVal变量中
LedOut[0]=Disp_Tab[LedNumVal%10000/1000];
LedOut[1]=Disp_Tab[LedNumVal%1000/100];
LedOut[2]=Disp_Tab[LedNumVal%100/10]; //十位
LedOut[3]=Disp_Tab[LedNumVal%10];
//个位
for(i=0; i<4; i++)
{
P0 = LedOut[i] ;
switch(i)
{
//138译码
case 0:LS138A=0; LS138B=0; LS138C=0; break;
case 1:LS138A=1; LS138B=0; LS138C=0; break;
case 2:LS138A=0; LS138B=1; LS138C=0; break;
case 3:LS138A=1; LS138B=1; LS138C=0; break;
}
delay(100);
}
P0 = 0;
} }
//延时程序
void delay(unsigned int i) {
char j;
for(i; i > 0; i--)
for(j = 200; j > 0; j--); } 4.1 讨论DS18B20的自动报警功能实现。
DS18B20只是一个测温元件,所谓的报警功能要通过程序由单片机来实现。
DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的EERAM。高速暂存RAM的结构为8字节的存储器,头2个字节包含测得的温度信息,第3和第4字节TH(报警温度上限)和TL(报警温度下限)的拷贝。第5个字节,为配置寄存器,它的内容用于确定温度值的数字转换分辨率。第
6、
ds18b20资料及程序范文第5篇
摘要:文章主要介绍有关18B20温度传感器的应用及有关注意事项,经典接线原理图。 1. 引言:
温度传感器的种类众多,在应用与高精度、高可靠性的场合时DALLAS(达拉斯)公司生产的DS18B20温度传感器当仁不让。超小的体积,超低的硬件开消,抗干扰能力强,精度高,附加功能强,使得DS18B20更受欢迎。对于我们普通的电子爱好者来说,DS18B20的优势更是我们学习单片机技术和开发温度相关的小产品的不二选择。了解其工作原理和应用可以拓宽您对单片机开发的思路。
2. DS18B20的主要特征: * 全数字温度转换及输出。 * 先进的单总线数据通信。 * 最高12位分辨率,精度可达土0.5摄氏度。 * 12位分辨率时的最大工作周期为750毫秒。 * 可选择寄生工作方式。 * 检测温度范围为–55°C ~+125°C (–67°F ~+257°F) * 内置EEPROM,限温报警功能。 * 64位光刻ROM,内置产品序列号,方便多机挂接。 * 多样封装形式,适应不同硬件系统。 3. DS18B20引脚功能:
•GND 电压地 •DQ 单数据总线 •VDD 电源电压
4. DS18B20工作原理及应用:
DS18B20的温度检测与数字数据输出全集成于一个芯片之上,从而抗干扰力更强。其一个工作周期可分为两个部分,即温度检测和数据处理。在讲解其工作流程之前我们有必要了解18B20的内部存储器资源。18B20共有三种形态的存储器资源,它们分别是:
ROM 只读存储器,用于存放DS18B20ID编码,其前8位是单线系列编码(DS18B20的编码是19H),后面48位是芯片唯一的序列号,最后8位是以上56的位的CRC码(冗余校验)。数据在出产时设置不由用户更改。DS18B20共64位ROM。
5. 控制器对18B20操作流程:
1、 复位:首先我们必须对DS18B20芯片进行复位,复位就是由控制器(单片机)给DS18B20单总线至少480uS的低电平信号。当18B20接到此复位信号后则会在15~60uS后回发一个芯片的存在脉冲。
2、 存在脉冲:在复位电平结束之后,控制器应该将数据单总线拉高,以便于在15~60uS后接收存在脉冲,存在脉冲为一个60~240uS的低电平信号。至此,通信双方已经达成了基本的协议,接下来将会是控制器与18B20间的数据通信。如果复位低电平的时间不足或是单总线的电路断路都不会接到存在脉冲,在设计时要注意意外情况的处理。
3、 控制器发送ROM指令:双方打完了招呼之后最要将进行交流了,ROM指令共有5条,每一个工作周期只能发一条,ROM指令分别是读ROM数据、指
定匹配芯片、跳跃ROM、芯片搜索、报警芯片搜索。ROM指令为8位长度,功能是对片内的64位光刻ROM进行操作。其主要目的是为了分辨一条总线上挂接的多个器件并作处理。诚然,单总线上可以同时挂接多个器件,并通过每个器件上所独有的ID号来区别,一般只挂接单个18B20芯片时可以跳过ROM指令(注意:此处指的跳过ROM指令并非不发送ROM指令,而是用特有的一条“跳过指令”)。ROM指令在下文有详细的介绍。
4、 控制器发送存储器操作指令:在ROM指令发送给18B20之后,紧接着(不间断)就是发送存储器操作指令了。操作指令同样为8位,共6条,存储器操作指令分别是写RAM数据、读RAM数据、将RAM数据复制到EEPROM、温度转换、将EEPROM中的报警值复制到RAM、工作方式切换。存储器操作指令的功能是命令18B20作什么样的工作,是芯片控制的关键。
5、 执行或数据读写:一个存储器操作指令结束后则将进行指令执行或数据的读写,这个操作要视存储器操作指令而定。如执行温度转换指令则控制器(单片机)必须等待18B20执行其指令,一般转换时间为500uS。如执行数据读写指令则需要严格遵循18B20的读写时序来操作。数据的读写方法将有下文有详细介绍。 6. DS28B20芯片ROM指令表
Read ROM(读ROM)[33H] (方括号中的为16进制的命令字) Match ROM(指定匹配芯片)[55H] Skip ROM(跳跃ROM指令)[CCH] Search ROM(搜索芯片)[F0H] Alarm Search(报警芯片搜索)[ECH] 7. DS28B20芯片存储器操作指令表:
Write Scratchpad (向RAM中写数据)[4EH] Read Scratchpad (从RAM中读数据)[BEH] Copy Scratchpad (将RAM数据复制到EEPROM中)[48H] Convert T(温度转换)[44H] Recall EEPROM(将EEPROM中的报警值复制到RAM)[B8H] Read Power Supply(工作方式切换)[B4H] 8.写程序注意事项
DS18B20复位及应答关系
每一次通信之前必须进行复位,复位的时间、等待时间、回应时间应严格按时序编程。
DS18B20读写时间隙:
DS18B20的数据读写是通过时间隙处理位和命令字来确认信息交换的。 写时间隙:
写时间隙分为写“0”和写“1”,时序如图7。在写数据时间隙的前15uS总线需要是被控制器拉置低电平,而后则将是芯片对总线数据的采样时间,采样时间在15~60uS,采样时间内如果控制器将总线拉高则表示写“1”,如果控制器将总线拉低则表示写“0”。每一位的发送都应该有一个至少15uS的低电平起始位,随后的数据“0”或“1”应该在45uS内完成。整个位的发送时间应该保持在60~120uS,否则不能保证通信的正常。 读时间隙:
读时间隙时控制时的采样时间应该更加的精确才行,读时间隙时也是必须先由主机产生至少1uS的低电平,表示读时间的起始。随后在总线被释放后的15uS
中DS18B20会发送内部数据位,这时控制如果发现总线为高电平表示读出“1”,如果总线为低电平则表示读出数据“0”。每一位的读取之前都由控制器加一个起始信号。注意:必须在读间隙开始的15uS内读取数据位才可以保证通信的正确。 在通信时是以8位“0”或“1”为一个字节,字节的读或写是从高位开始的,即A7到A0.字节的读写顺序也是如图2自上而下的。
9.接线原理图:
本原理图采用四位数码管显示,低于100度时,首位不显示示例27.5,低于10度时示例为9.0,低于零度时示例为-3.7。
结束语:基于DS18B20温度测量温度准确,接线简单,易于控制,加以扩展可以应用到各种温度控制和监控场合。
参考文献:
DALLAS(达拉斯)公司生产的DS18B20温度传感器文献
程序:
#include
#define uchar unsigned char #define uint unsigned int
sbit sda=P1^7; sbit dian=P0^7;//小数点显示 uint tem;
uchar h; uchar code tabw[4]={0xf7,0xfb,0xfd,0xfe};//位选 uchar code tabs[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//数码管数据
//
0
4 5 6
8 9
空
- uchar code ditab[16]= {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; //查表显示小数位 ,1/16=0.0625,即当读出数据为3时,3*0.0625=0.1875,读出数据为3时对应1,查表显示1,为4时显2 uchar data temp[2]={0};//高位数据与低位数据暂存 uchar data display[5]={0};//显示缓存
void delay(uchar t)//t为1时延时小于5us { while(t--); } void delay1()//4us {} void delays(uchar m)//1ms { uchar i,j; for(i=0;i
for(j=0;j<110;j++); } void reset()//初始化 { uchar x=1; while(x) {
while(x)
{
sda=1;
sda=0;
delay(50);//延时500us以上
sda=1;
delay(5);//等待15us-60us
x=sda;
}
delay(45);
x=~sda; }
sda=1; } void write_s(uchar temp)//写入一个字节 { uchar i; for(i=0;i<8;i++) {
sda=1;
sda=0;
delay1();
sda=temp&0x01;
delay(6);
temp=temp/2; } sda=1; delay(1); } uchar read_s()//读出一个字节的数据 { uchar m=0,i; for(i=0;i<8;i++) {
sda=1;
m>>=1;
sda=0;
delay1();
sda=1;
delay1();
if(sda)
m=m|0x80;
delay(6); } sda=1; return m; } uint read_1820()//读出温度 { reset(); delay(200); write_s(0xcc);//发送命令
write_s(0x44);//发送转换命令
reset(); delay(1); write_s(0xcc);
write_s(0xbe); temp[0]=read_s(); temp[1]=read_s(); tem=temp[1]; tem<<=8; tem|=temp[0]; return tem; } void scan_led()//数据显示—数码管 { uchar i; for(i=0;i<4;i++) {
P0=tabs[display[i]];
P1=tabw[i];
delays(7);
if(i==1)
dian=0;
P1=tabw[i];
delays(2); } } void convert_t(uint tem)//温度转换{ uchar n=0; if(tem>6348) {
tem=65536-tem;
n=1; } display[4]=tem&0x0f; display[0]=ditab[display[4]];
display[4]=tem>>4;
display[3]=display[4]/100;
display[1]=display[4]%100;
display[2]=display[1]/10;
display[1]=display[1]%10; if(!display[3]) {
display[3]=0x0a; } if(!display[2])
display[2]=0x0a; if(n)
// 取百位数据暂存
// 取后两位数据暂存// 取十位数据暂存
{
n=0;
display[3]=0x0b; } } void main() { delay(0); delay(0); delay(0); P0=0xff; P1=0xff; for(h=0;h<4;h++)//初始化为零
{
display[h]=0; } reset(); write_s(0xcc); write_s(0x44); for(h=0;h<100;h++)//显示0保持
scan_led(); while(1) {
convert_t(read_1820());//读出并处理
scan_led();//显示温度
ds18b20资料及程序范文第6篇
1.《建设用地规划许可证》
2.《国有土地使用证》
3.《建设工程规划许可证》
4.《建筑工程施工许可证》(又称建筑工程开工证)
5.《商品房预售许可证》
详细步骤介绍:
一 、《建设用地规划许可证》和《国有土地使用证》
1.选址意见书(审查用地性质、范围、面积是否符合城市整体规划)
程序:
(1)企业提供申请报告、规划申请表、总平面图、土地转让协议或国有土地使用证、企业营业执照和资质证书,报规划局用地处
(2)用地处转总工室审查
(3)报局业务会批准
(4)领取选址意见书
2.规划院实地测量,并处定位图,收取测量费
3.建设用地规划许可证(规划局审批下发)
(1)企业持定位图、选址意见书、用地申请到用地处审查
(2)主管局长、主管局市长批准
(3)打交费单,领取用地规划许可证
4.国有土地使用证(由土地局审批下发)
(1)建设单位持用地申请、航测图、平面布置图、土地转让协议、建设用地规划许可证、土地转让双方的有关证件、委托书到土地局土地利用处
(2)土地评估
(3)土地局测量对现场测量,出定界图
(4)缴纳土地出让金和契税,领取国有土地使用证
二、《建设工程规划许可证》
1. 市消防支队盖章
(1) 持消防审批表、全套施工图到市消防支队建审科进行审批
(2) 核发消防设计审核意见书、建设工程规划许可证申请表盖章
2.人防证明市人防办六十个工作日办理自建手续
3.房地产开发建设规模 建设单位持单位申请、总平面图、资金证明到市房管局规划发展处办理
4.建设工程规划许可证(由规划局规划处下发)
(1)建设单位持申请报告、建设工程规划申请表(消防盖章)、土地征、用地规划许可证、总平面图、全套施工图、四套航测图到市规划局建管处
(2)以上资料由总工室、局业务会审定后报处长、局长签字
(3)打交费单交费,领取建设规划许可证、放验线通知单
5.放线报告
持放线通知和施工图、红线图到规划院测量队放线。
三、《建设工程施工许可证》(由建委审批下发)
1. 报建
提供资料:建设工程规划许可证、用地规划许可证、土地证、报建申请表4份、红线图、施工图、规划总平面图
2. 现场勘察(3个工作日)
3. 组织招标
4. 施工图审查
5. 施工合同审查
6. 交费,办理建设工程施工许可证(建设施工合同、勘察合同、设计合同、监理合同、报建申请表、工程预算书、中标通知书、交费*** )
四、《商品房预售许可证》(由市房管局预售科下发)