您的位置:首页 > 其它

18B20温度传感器详解

2013-12-20 17:31 423 查看
数据传感器DS18B20

编写原因:.....暂略

特性:

1. 单独的单线接口,只需1个接口引脚即可通信;

2. 不需要外部元件;

3. 可用数据线供电;

4. 不需备份电源;

5. 测量范围从-55°C ~ +125°C, 增量为0.0625°C;

6. 以12位数字值方式读出温度;

7. 在1s内把温度变换为数字;



知识点:

1. 每个18B20包括唯一的64位长的序号放在ROM中;

开始8位产品类型编码| 接着48位每个器件唯一序号| 最后8位:前56位的CRC

2. 18B20最小单位刻度是0.0625°C, (这里后面解释)

DS18B20的控制流程

根据DS18B20的通信协议,DS18B20只能作为从机,而单片机系统作为主机,片机控制DS18B20完成一次温度转换必须经过3个步骤:

1. 初始化;

2. 发送ROM指令;

3. 发送18B20功能指令。

@以上3个流程还有顺序不能颠倒且缺一不可,每次只要发送任何一条ROM指令,这个流程必须从第1再开始才能发送另外的ROM指令;

一,初始化



/*
*******************************************************************************
**
**                             GPIO_DQ_Out_Mode(void)
**
**
**	功能描述:设置DQ引脚为开漏输出模式
**
**	参  数  :无
**
**	返回值  :无
**
*******************************************************************************
*/
void GPIO_DQ_Out_Mode(void)
{
GPIO_InitTypeDef GPIO_InitStructure ;

GPIO_InitStructure.GPIO_Pin = DQ_GPIO_Pin ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ; //开漏输出
GPIO_Init(DQ_GPIO ,&GPIO_InitStructure) ;
}

/*
*******************************************************************************
**
**                                GPIO_DQ_Input_Mode(void)
**
**
**	功能描述:设置DQ引脚为浮空输入模式
**
**	参  数  :无
**
**	返回值  :无
**
*******************************************************************************
*/
void GPIO_DQ_Input_Mode(void)
{
GPIO_InitTypeDef GPIO_InitStructure ;

GPIO_InitStructure.GPIO_Pin = DQ_GPIO_Pin ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ; //浮空输入
GPIO_Init(DQ_GPIO ,&GPIO_InitStructure) ;
}

/*
*******************************************************************************
**                                  Tx_ResetPulse(void)
**
**
**	功能描述:发送复位脉冲
**
**	参  数  :无
**
**	返回值  :无
**
*******************************************************************************
*/
void Tx_ResetPulse(void)
{
GPIO_DQ_Out_Mode() ;

DQ_Write_0() ;  //复位脉冲
Delay_10us(50) ; //至少保持480us
DQ_Write_1() ;  //加速上升沿速度
Delay_10us(1) ;
}
/*
*******************************************************************************
**
**                              Rx_PresencePulse(void)
**
**
**	功能描述:接受应答信号
**
**	参  数  :无
**
**	返回值  :无
**
*******************************************************************************
*/
void Rx_PresencePulse(void)
{
GPIO_DQ_Input_Mode() ;
while( DQ_ReadBit()) ;  //等待DS18b20应答
while( DQ_ReadBit() == 0) ; //DS18b20将总线拉低60~240us ,然后总线由上拉电阻拉高
Delay_10us(30) ;
GPIO_DQ_Out_Mode() ;    //接受完成,主机重新控制总线
}
/*
*******************************************************************************
**                                 DS18B20_Init(void)
**
**
**	功能描述:初始化DS18b20
**
**	参    数:无
**
**	返回值  :无
**
*******************************************************************************
*/
void DS18B20_Init(void)
{
Tx_ResetPulse();
Rx_PresencePulse();
}


Tx_ResetPulse:函数:主机总线发送复位脉冲

PresencePulse函数:主机读取18B20返回的存在脉冲(电平持续60-240us)

二.写时序



/*
*******************************************************************************
**
**                      Write_OneByte_ToDS18b20(unsigned char data)
**
**
**	功能描述:写一个字节到DS18b20
**
**	参  数  :无
**
**	返回值  :无
**
*******************************************************************************
*/
void Write_OneByte_ToDS18b20(unsigned char data)
{
unsigned char i ;
GPIO_DQ_Out_Mode() ;
for(i=0 ;i<8 ;i++)
{
if(data&0x01)    //低位在前
{
//写1
DQ_Write_0() ; //写时间空隙总是从总线的低电平开始
Delay_10us(1) ;  //15us内拉高
DQ_Write_1() ;
Delay_10us(8) ; //整个写1时隙不低于60us
}
else
{
//写0
DQ_Write_0() ;
Delay_10us(11) ; //保持在60us到120us之间
DQ_Write_1() ;
Delay_10us(1) ;
}
data >>= 1 ;
}
}
写1 还是写0 由15-60us 的电平区分,所以 DQ_write_0函数后延时长是写0, DQ_write_1函数后延时长是写1;

且是从低位开始写, 所以写完后 data>>=1 ;

三.读时序



/*
*******************************************************************************
**
**                       Read_OneByte_FromDS18b20(void)
**
**
**     功能描述:从DS18b20读一个字节
**
**     参  数  :无
**
**     返回值  :读出的数据
**
*******************************************************************************
*/
unsigned charRead_OneByte_FromDS18b20(void)
{
unsigned char i ,data = 0 ;

for(i=0 ;i<8 ;i++)
{
GPIO_DQ_Out_Mode() ;
data >>= 1 ;
DQ_Write_0() ;
Delay_10us(1) ;
GPIO_DQ_Input_Mode() ;
Delay_10us(1) ;
if(DQ_ReadBit())
{
data |= 0x80 ;
}
Delay_10us(7) ;   //等待这一位数据完成传输
}
GPIO_DQ_Out_Mode() ;
return data ;
}


四.读取温度值和计算

18B20用12位存储温度值,最高位是符号位,下图是其温度存储方式,负温度S=1,正温度S=0;

如:0550H 是+85°C 0191H:+25.0625°C FC90H是-55°C



/*
***************************************************************************************************
**
**        Read_Temperature(unsigned char *sign , unsigned char *interger , unsigned int *decimal)
**
**
**	功能描述:读取温度信息
**
**	参    数:*sign - 保存符号(零上或零下)
**            *integer - 保存整数部分
**            *decimal - 保存小数部分
**
**	返回值  :无
**
***************************************************************************************************
*/
void Read_Temperature(unsigned char *sign , unsigned char *interger , unsigned int *decimal)
{
unsigned char a=0;
unsigned char b=0;
unsigned int tmp ;

DS18B20_Init();
Write_OneByte_ToDS18b20(ROM_Read_Cmd);

DS18B20_Init();
Write_OneByte_ToDS18b20(ROM_Skip_Cmd);//跳过读序列号操作
Write_OneByte_ToDS18b20(Convert_T); //启动温度转换
Delay_ms(780);//等待DS18b20转换完成

DS18B20_Init();
Write_OneByte_ToDS18b20(ROM_Skip_Cmd);
Write_OneByte_ToDS18b20(Read_Scratchpad); //读取寄存器内容

a= Read_OneByte_FromDS18b20();     //温度低8位
b= Read_OneByte_FromDS18b20();     //温度高8位

Tx_ResetPulse();  //中断数据读取
tmp = (b<<8) | a ;
if(b & 0xF0)
{
*sign = 1 ;              //符号部分
tmp = ~tmp+1 ;		//二进制数求补 再换成十进制数得到被测温度值
}
else
{
*sign = 0 ;
}
*interger = (tmp>>4) & 0x00FF;  //整数部分
*decimal = (tmp & 0x000F) * 625 ; //小数部分 实际上是乘以0.0625最小步进 同时把小数变成非小数显示
}


1.因为上面说过每次只要发送了ROM命令 ,再发其他命令必须重新初始化;

2.将存储器中的二进制数求补后再转换成十进制;

代码和数据手册已上传到我的资源:http://download.csdn.net/detail/yx_l128125/6755749
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: