认识温度传感器,我们得先看原理图:
这个温度传感器可以说非常强大,强大到只用一根DQ数据总线,便可以完成数据的传输和能量的输送。我们在来看看他的特性,便不得不觉得非常神奇:
最神奇的莫过于可以独立工作,因为里面装的有储能电容。下面开始介绍怎么控制它:
首先,需要着重记住一句话:当需要执行温度测量和AD转换时,总线控制器必须发[44h]的命令。
其次,需要记住一些指令:
接着,我们还需要记住它的执行序列,这样三步不能颠倒顺序。
1.初始化
2.ROM操作指令
3.DS18B20功能指令
我们开始写程序:
第一步:温度传感器的初始化,还是需要用到温度传感器的说明书。
它告诉我们需要先将总线拉低即DQ=0,随后延迟480微秒以上,再上拉DQ=1,延迟480微秒以上,保持上拉,等待接受信息。程序如下:
void dsinit()//温度传感器的初始化
{
DQ=0;//DQ数据线本来是低电平
Delay500us();//延迟500微秒后,上拉
DQ=1;//完成上拉
Delay500us();//保持上拉,等待回复信号
}
第二步:写温度转换的程序,之后是写指令和读指令:
首先是写一个write的子函数,因为板子制度二进制的,我们需要将其一一转化。还需要结合写时序图:
我们的思路是:将8位二进制数一一写入,逐一进行操作。详细代码如下:
//发送dat16位的数
void write(uchar dat)
{
uchar i;
for(i=0;i<8;i++)//因为0x44有8位十六进制,所以逐一进行写操作
{
DQ=0;//现根据16页的图,先将DQ拉为低电平
DQ=dat&0x01;//0000 0010 & 0000 0001 = 0000 0000
//这一步进行判定写进去的值,到底是写0还是写1,写0则不用管
Delay100us();//保持低电平的状态,让其读懂是1还是0
DQ=1;//将其拉高 以上只移动了一位
// 本来是 0000 0010 第一回
dat>>=1;//dat=dat>>1;//0000 0001//1000 0000 向右移1位
// 第二回 第三回
}
}
然后写一个read的子函数,将数据读入,思路大体同上:
uchar read()//带返回值的,只能这么写
{
uchar i;
uchar dat;//表示读回来的数字
for(i=0;i<8;i++)
{
DQ=0;
_nop_();//由于担心时间不够,加上了一个机器周期,起延迟的效果
dat>>=1;//刚开始就要移位
DQ=1;
if(DQ==1)
{
dat |= 0x80;// dat=dat|0x80; 定义为 0000 0000 | 1000 0000 =1000 0000
}
Delay100us();
}
return dat;
}
最后整合进入读取温度的函数:
uchar temget()//再写一个忽略ROM的指令
{
uchar temp;
uchar low,high;//读取高8位,低8位的值
dsinit();
write(0xcc);//忽略ROM指令,write函数目的在于转换16进制,
write(0x44);//温度转换指令
Delay500us(); Delay500us();
dsinit();
write(0xcc);
write(0xbe);//这里写的是读暂存器的指令
//接下来涉及到如何读数的问题
low=read();
high=read();
//接下来进行转换
temp=high<<4;//0000 0101 =0101 0000
temp |= (low>>4); // 1010 0110 0000 0110 | 0101 0000=0101 0110
return temp;
}