单总线通信(Onewire)
温度传感器DS18B20
当总线的数据传输速率一般为16.3Kbit/s,最大可达142Kbit/s,通常采用100Kbit/s以下的速率传输数据。
温度传感器DS18B20原理图如下:
由图知,DS18B20温度传感器接在P14管脚,P14管脚和Vcc间接有一个上拉电阻。
1.初始化
DS18B20初始化函数:
void Init_DS18B20(void)
{
DQ=0;
Delay500us();
DQ=1;
Delay500us();
}
根据其时序图,初始化先将DQ拉低,延时,然后再拉高,延时。
2.ROM命令,跟随需要交换的数据。
与DS18B20相连的只有一条总线P14,所以我们可以使用忽略ROM指令CCH。
即(写字节指令将在后边介绍)
DS18B20_WriteByte(0XCC);
3.功能命令,跟随需要交换的数据。
我们将会使用到温度转换指令44H和读寄存器指令BEH(写字节指令将在后边介绍)
即
DS18B20_WriteByte(0X44);
和
DS18B20_WriteByte(0XBE);
所有的数据和指令的传递都是从最低有效位开始通过单总线。
补充:
写字节指令:
void DS18B20_WriteByte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
DQ=0;
DQ=dat&0X01; //写入数据最低位
Delay80us();
DQ=1;
dat>>=1;
}
}
根据其时序图,写入字节到温度传感器时,先将DQ拉低,写入数据最低位(根据数据0和1确定低和高),延迟至少60us使DS18B20采样后再拉高,再次写入即重复上述过程。如上循环及移位进行8次,可将dat中的数据全部通过单总线由最低位向最高位的顺序写入传感器。
读字节指令:
uchar DS18B20_ReadByte(void)
{
uchar i;
uchar dat;
for(i=0;i<8;i++)
{
DQ=0;
dat>>=1;
DQ=1;
if(DQ==1)
{
dat|=0X80; //读出数据最低位
}
Delay80us();
}
return dat;
}
根据其时序图,由传感器读出字节时,先将DQ拉低,然后再拉高,此时根据DQ电平高低读出数据最低位,延迟至少60us使DS18B20采样,再次写入即重复上述过程。如上循环及移位进行8次,可将dat中的数据全部通过单总线由最低位向最高位的顺序读出传感器。
温度传感器的显示:
由下面例子可知,16位二进制数,高4位为正负,低4位为小数,中间8位为整数值
整数表示:去掉高4位、低4位,保留中间8位,即为整数值;
小数表示:去掉高4位,保留低12位,12位数据温度精度为0.0625℃。
一般不需要进行精度调整,使用默认的即可,温度传感器精度为用户可编程的9,10,11或12位,分别以0.5℃,0.25℃,0.125℃,0.0625℃增量递增,在上电状态下默认的精度为12位。
1.温度检测程序:(整数表示)
uchar TemperGet(void)
{
uchar low,high;
uchar temp;
Init_DS18B20();
DS18B20_WriteByte(0XCC);
DS18B20_WriteByte(0X44);
Delay500us();
Init_DS18B20();
DS18B20_WriteByte(0XCC);
DS18B20_WriteByte(0XBE);
low=DS18B20_ReadByte();
high=DS18B20_ReadByte();
temp=high<<4; //假设high是0000 0001——0001 0000
temp=temp|(low>>4); //假设low是1001 1001——0000 1001
//那么temp=0001 1001
return temp;
}
2.温度检测程序:(小数表示)
long TemperGet(void)
{
uchar high,low;
long temp;
Init_DS18B20();
DS18B20_WriteByte(0XCC);
DS18B20_WriteByte(0X44);
Init_DS18B20();
DS18B20_WriteByte(0XCC);
DS18B20_WriteByte(0XBE);
low=DS18B20_ReadByte();
high=DS18B20_ReadByte();
temp=high&0X0F;
temp<<=8;
temp|=low;
temp=temp*625; //12位,精度为0.0625℃/位
return temp;
}
以下为完整的工程代码,可供下载:
温度传感器DS18B20的完整代码(舍弃小数部分)
温度传感器DS18B20的完整代码(保留小数部分)