DS18B20有三个引脚,其中两个引脚接入电源。单片机通过对第三个引脚进行高低电平的输入和输出实现数据的传输。
下面是DS18B20常用的指令表,第三个引脚在接收到相应的数据后能够制做出对应的响应。
代码 | 功能 |
---|---|
33H | 读取rom编码 |
55H | 发出指令并发送64位ROM编码,访问传感器总线上的编码 |
0F0H | 识别总线上搭载传感器的个数 |
0CCH | 忽略ROM地址,直接向DS18B20发温度变换指令 |
0ECH | 执行后只有温度超过设定值域才做出相应 |
44H | 启动传感器进行温度转换,结果存入RAM |
0BEH | 读取RAM中9个字节的内容 |
4EH | 发出向内部RAM的3、4字节写上、下限温度数据指令,之后传送两个字节的数据 |
48H | 将RAM中第3、4字节的内容复制到总线上 |
0B8H | 将总线中的内容恢复到总线中 |
0B4H | 设置供电方式。‘0’寄生供电,‘1’外接电源供电 |
控制温度传感器总共只需要三步:传感器初始化、读取数据以及写入数据(写入数据相当于单片机的控制指令,读取数据则是完成对上位机的响应) | |
传感器数据初始化 | |
①数据线拉到低电平 | |
②延时480微秒 | |
③数据线拉到高电平 | |
④延时等待80微秒(初始化成功时在15~60微秒时间内产生一个由传感器返回的低电平,由初始化判断该传感器是否存在) | |
⑤若单片机读取到上一步反馈的低电平数据,则延时480微秒。 | |
传感器初始化函数(DS18B20表示传感器连接到51单片机上的引脚) |
uchar Ds18b20Init() //初始化。成功返回1,不成功返回0.
{
uchar i;
DS18B20 = 0; //将总线拉低480微秒~960微秒
i = 70;
while(i--); //延时642微秒
DS18B20 = 1; //拉高总线,等待后续反馈
i = 0;
while(DS18B20) //等待DS18B20拉低总线
{
Delay1ms(1); //定义的延迟1ms的延迟函数
i++;
if(i>5) //等待5ms以上
{
return 0; //初始化失败
}
}
return 1; //初始化成功
}
读取传感器数据
① 将数据线拉低
② 延时1微秒
③ 将数据拉高,释放总线读取数据
④ 延时10微秒
⑤ 读取数据线状态得到一个状态位
⑥ 延时45微秒
通过上述方法重复读取位,达到读取字节的目的。
传感器数据读取函数
uchar Ds18b20ReadByte() //通过读取8次状态位达到读取字节的目的
{
uchar byte, bi;
uint i, j;
for(j=8; j>0; j--)
{
DS18B20 = 0; //先将总线拉低
i++;
DS18B20 = 1; //然后释放总线
i++;
i++; //延时6微秒等待数据稳定
bi = DS18B20; //读取数据,从最低位开始读取
byte = (byte >> 1) | (bi << 7); //从最低位开始记录,将byte依次右移
i = 4; //读取完之后等待48微秒再接着读取下一个数
while(i--);
}
return byte; //将读取完的字节保存
}
传感器写数据
① 总线置低电平
② 延时15微秒
③ 发送一位数据
④ 延时60微秒
⑤ 总线置高电平
⑥ 发送完毕后总线置高电平
传感器写函数
void Ds18b20WriteByte(uchar dat)//函数通过循环写8个位实现写一个字节
{
uint i, j;
for(j=0; j<8; j++)
{
DS18B20 = 0; //每写入一位数据之前先把总线拉低
i++;
DSPORT = dat & 0x01; //然后写入一个数据,从最低位开始
i=6;
while(i--); //延时68微秒
DS18B20 = 1; //释放总线,给总线1微秒恢复时间才能接着写入下一位 dat >>= 1;
}
}
在完成了上面的函数之后就能够对温度传感器写入数据和读取其中的数据,通过写特定的指令来完成特定的操作。
传感器读取温度函数
int Ds18b20ReadTemp() //读取的温度有两个字节,分别用tml和tmh存储两个字节
{
int temp = 0;
uchar tmh, tml;
Ds18b20Init(); //传感器初始化
Delay1ms(1); //延时1微秒
Ds18b20WriteByte(0xcc); //跳过读取序列号操作
Ds18b20WriteByte(0x44); //温度转换指令
//完成温度转换功能
Ds18b20Init(); //传感器初始化
Delay1ms(1);
Ds18b20WriteByte(0xcc); //跳过读取序列号操作
Ds18b20WriteByte(0xbe); //发送读取温度指令
//然后等待转换完后发送读取温度命令
tml = Ds18b20ReadByte(); //读取温度值共16位,先读低字节
tmh = Ds18b20ReadByte(); //再读高字节
temp = tmh; //先存高字节,后面通过移位存储低字节
temp <<= 8;
temp |= tml;
return temp;
}