数据传感器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();
}
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
转载自原文链接, 如需删除请联系管理员。
原文链接:18B20温度传感器详解,转载请注明来源!