一. 概述
DS18B20数字温度传感器提供9-Bit到12-Bit的摄氏温度测量精度和一个用户可编程的非易失性且具有过温和低温触发报警的报警功能。 DS18B20采用的1-Wire通信即仅采用一个数据线(以及地)与微控制器进行通信,采集数据的精度为12bit。
该传感器的温度检测范围为-55℃至+125℃,并且在温度范围超过-10℃至85℃之外时还具有+-0.5℃的精度。 此外,DS18B20可以直接由数据线供电而不需要外部电源供电。
二. 电气参数
1.特点
2.引脚说明
3.参考电路图
DS18B20供电一般采用外部供电方式,并且在数据线上并联一个4.7k的上拉电阻,以增强数据的抗干扰能力。
三. 控制时序
1.初始化时序
与DS18B20所有的通信都是由初始化时序开始的,该时序包括从主设备发出的复位脉冲及从DS18B20响应的存在脉冲组成。 如图所示。
当DS18B20响应复位信号的存在脉冲后,则其向主设备表明其在该总线上,并且已经做好操作命令。
/*******************************************************************************
* 函 数 名 : Ds18b20Init
* 函数功能 : 初始化
* 输 入 : 无
* 输 出 : 初始化成功返回1,失败返回0
*******************************************************************************/
uchar Ds18b20Init()
{
unsigned char x=0;
DSPORT = 1; //DQ复位
Delay_DS18B20(8); //稍做延时
DSPORT = 0; //单片机将DQ拉低
Delay_DS18B20(80); //精确延时,大于480us
DSPORT = 1; //拉高总线
Delay_DS18B20(14);
x = DSPORT; //稍做
return x;//初始化成功
}
2.读时序
写时段有两种情况:“写1”时段和“写0”时段。 主设备通过写1时段来向DS18B20中写入逻辑1以及通过写0时段来向DS18B20中写入逻辑0。 每个写时段最小必须有60us的持续时间且独立的写时段间至少有1us的恢复时间。 两个写时段都是由主设备通过将1-Wire总线拉低来进行初始化,如图。
根据以上读0及1的时序,便可实现读取一个完整字节的函数,如下:
/*******************************************************************************
* 函 数 名 : Ds18b20ReadByte
* 函数功能 : 读取一个字节
* 输 入 : 无
* 输 出 : dat
*******************************************************************************/
uchar Ds18b20ReadByte()
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DSPORT = 0; // 给脉冲信号
dat>>=1;
DSPORT = 1; // 给脉冲信号
if(DSPORT)
dat|=0x80;
Delay_DS18B20(4);
}
return(dat);
}
3.写时序
仅在读时段期间DS18B20才能向主设备传送数据。 因此,主设备在执行完读暂存寄存器[BEh]或读取供电模式[B4h]后,必须及时地生成读时段,这样DS18B20才能提供所需的数据。 此外,主设备可以在执行完转换温度[指令:44h]或拷贝EEPROM[指令:B8h]命令后生成读时段,以便获得在“DS18B20功能命令”表中提到的操作信息。 时序如图:
根据以上写0及1的时序,便可实现写入一个完整字节的函数,如下:
/*******************************************************************************
* 函 数 名 : Ds18b20WriteByte
* 函数功能 : 向18B20写入一个字节
* 输 入 : com
* 输 出 : 无
*******************************************************************************/
void Ds18b20WriteByte(uchar dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DSPORT = 0;
DSPORT = dat&0x01;
Delay_DS18B20(5);
DSPORT = 1;
dat>>=1;
}
}
四. 控制程序
1.读取温度流程
要读取一个完整的温度值,需要根据以上流程进行操作。 先对DS18B20进行复位操作,再发送开始转换指令(指令值:0x44),再发送复位操作,等待DS18B20应答后,发送读取温度指令,最后就可以读取16位的数据(有限位最大为12位)。
2.读取温度程序
/*******************************************************************************
* 函 数 名 : Ds18b20ChangTemp
* 函数功能 : 让18b20开始转换温度
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Ds18b20ChangTemp()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc); //跳过ROM操作命令
Ds18b20WriteByte(0x44); //温度转换命令
// Delay1ms(100); //等待转换成功,而如果你是一直刷着的话,就不用这个延时了
}
/*******************************************************************************
* 函 数 名 : Ds18b20ReadTempCom
* 函数功能 : 发送读取温度命令
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Ds18b20ReadTempCom()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc); //跳过ROM操作命令
Ds18b20WriteByte(0xbe); //发送读取温度命令
}
/*******************************************************************************
* 函 数 名 : Ds18b20ReadTemp
* 函数功能 : 读取温度
* 输 入 : 无
* 输 出 : 温度值
*******************************************************************************/
int Ds18b20ReadTemp()
{
int temp = 0;
uchar tmh, tml;
Ds18b20ChangTemp(); //先写入转换命令
Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令
tml = Ds18b20ReadByte(); //读取温度值共16位,先读低字节
tmh = Ds18b20ReadByte(); //再读高字节
temp = tmh;
temp <<= 8;
temp |= tml;
return temp;
}
/*******************************************************************************
* 函 数 名 : GetTemp
* 函数功能 : 串口输出温度值
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
Void GetTemp(void)
{
int temp;
float tp;
ET0 = 0;
temp = Ds18b20ReadTemp();
ET0 = 1;
if(temp<= 0) //当温度值为负数
{
// temp=temp-1;
// temp=~temp;
// tp=temp;
// temp=tp*0.0625*100+0.5;
Uart_SendString("Overrate!\\r\\n"); //超过量程
}
else
{
tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
}
Uart_SendString("The Current Temperature is: ");
Uart_SendByte((temp% 10000 / 1000) + 0x30);
Uart_SendByte((temp% 1000 / 100) + 0x30);
Uart_SendByte('.');
Uart_SendByte((temp% 100 / 10) + 0x30);
Uart_SendByte((temp% 10) + 0x30);
Uart_SendString("℃\\r\\n");
}
全部0条评论
快来发表一下你的评论吧 !