Ds18b20的使用
二、引脚图
从上图可以看出Ds18b20的接线得却十分简单,但需要注意的是,当传感器与单片机相连时,要加一个4.7K的上拉电阻(事实证明要求没那么严格,5K左右即可)。
三、工作指令
1.温度转换指令:0x44(即44H),启动Ds18b20启动转换温度
2.读暂存器指令:0xBE(即BEH),读取暂存器中的九字节数据
3.写暂存器置零:0x4E(即4EH),把数据写入暂存器的TH、TL
4.赋值暂存器:0x48(即48H),把暂存器中的TH、TL写入EEPROM中
5.读电源供电方式:0xB4(即B4H):启动Ds18b20,发送电源供电方式
6.重调EEPROM:0xB8(即B8H):把EEPROM中的TH、TL读至暂存器
四、通过单总线访问Ds18b20的时序
五、操作时序
1.复位操作
2.“读”操作
3.“写”操作
六、例程(例程均为自己编写且通过验证成功)
/*所用单片机型号为STC89C52RC,晶振为11.0592MHz*/
#include<reg52.h>
#include<intrins.h>
sbit Bus=P1^1;//数据单总线
unsigned int Ds_Result();//返回最终结果
bit DS_Init();//初始化子函数
void Ds_Write(unsigned char dat);//“写”子函数(用于向总线写命令)
unsigned char Ds_Read();//“读”子函数(用于从总线读值)
void Ds_Change();//开始转换温度
unsigned int Get_Temp();//获取温度子函数
void Delay10us(unsigned int t);//延时10*t微秒
void Delay1ms(unsigned int t);
/*ds18b20 10*t延时函数*/
void Delay10us(unsigned int t)
{
unsigned int i;
for(i=t;i>0;i–)
{
_nop_(); _nop_();
_nop_(); _nop_();
_nop_(); _nop_();
}
}
/*dsb8b20 1ms延时函数*/
void Delay1ms(unsigned int t) //误差 0us
{
unsigned char a,b,c;
for(t;t>0;t–)
for(c=1;c>0;c–)
for(b=142;b>0;b–)
for(a=2;a>0;a–);
}
/*ds18b20初始化*/
bit Ds_Init()
{
bit ack;
Bus=0;
Delay10us(60);//最小480,最大960
Bus=1;
Delay10us(6);//15-60us
while(Bus==0);
Bus=1;//让传感器释放总线,避免影响下一步
return ack;//ack为0则响应成功
}
/*ds18b20写时序*/
void Ds_Write(unsigned char dat)//一个写周期为60-120us,主机在15–45us内对信号采样
{
unsigned char mask;
for(mask=0x01;mask!=0;mask<<=1)
{
Bus=0;
_nop_();
if((mask&dat)==0)
{
Bus=0;
}
else
{
Bus=1;
}
Delay10us(6);//15-60us采样
Bus=1;
_nop_();
_nop_();
}
}
/*ds18b20读时序*/
unsigned char Ds_Read()
{
unsigned char dat=0;
unsigned char mask,fmask;
for(mask=0x01;mask!=0;mask<<=1)//一个周期需要至少60us,但采样要在15us内完成
{
Bus=0;
_nop_();
Bus=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if(Bus==0)//读0
{
fmask=~mask;
dat=dat&fmask;
}
else
{
dat|=mask;
}
Delay10us(5);
Bus=1;
}
return dat;
}
/*转换温度子函数*/
void Ds_Change()
{
Ds_Init();
Delay1ms(1);
Ds_Write(0xCC);//跳过ROM寻址
Ds_Write(0x44);//启动一次温度转换
}
/*ds18b20获取温度子函数*/
unsigned int Get_Temp()
{
unsigned int temp=0;
unsigned char LSB,MSB;//用来储存数据的第八位与高八位
Ds_Init();
Delay1ms(1);
Ds_Write(0xCC);//跳过寻址
Ds_Write(0xBE);//发送读值命令·
LSB=Ds_Read();
MSB=Ds_Read();
temp=MSB;
temp<<=8;
temp|=LSB;
return temp;
}
/*ds18b20 返回最终结果子函数*/
unsigned int Ds_Result()
{
float tp;
unsigned int temp;
Delay1ms(10);//10ms度过不稳定期
Ds_Change();//转换温度
Delay1ms(1000);//延时1s等待转化
temp=Get_Temp();
tp=temp;
temp=tp*0.0625;
return temp;//最终结果为temp
}
int main()
{
unsigned int temp;
temp=Ds_Result();//该值即为结果
}
左肩理想,右肩担当。君子不怨永远不会停下脚步!