51单片机驱动——DS18B20
51单片机驱动——DS18B20
51单片机驱动——DS18B20
1.描述
DS18B20是常用的环境温度测量的传感器,但其对通信时序要求较高,而51单片机资源有限,大部分人在使用时也不会严格对照数据手册的时序图操作,所以经常会有人遇到,网上下载的代码无法正常驱动DS18B20读取环境温度,有的代码在Proteus等仿真软件里是可以正常使用的(时钟频率设定等因素),但在实物中就不能实现对应功能。下面的这个代码是在实物系统中验证过的,我也简单封装了一下,大家可以直接复制使用。
2.子文件
DS18B20.c
#include "DS18B20.h"sbit DS18B20=P1^0; //定义数据线void delay_ms(unsigned int x)//延时1ms
{unsigned int y,z;for(y=x;y>0;y--)for(z=110;z>0;z--);
}uchar DS18B20_Init() //初始化。成功返回1,不成功返回0.{uchar i;DS18B20 = 0; //将总线拉低480微秒~960微秒i = 70; while(i--); //延时642微秒DS18B20 = 1; //拉高总线,等待后续反馈i = 0;while(DS18B20) //等待DS18B20拉低总线{ delay_ms(1); //定义的延迟1ms的延迟函数i++;if(i>5) //等待5ms以上{return 0; //初始化失败}}return 1; //初始化成功
}uchar DS18B20_ReadByte() //通过读取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; //将读取完的字节保存
}void DS18B20_WriteByte(uchar dat)//函数通过循环写8个位实现写一个字节
{uint i, j;for(j=0; j<8; j++){DS18B20 = 0; //每写入一位数据之前先把总线拉低i++;DS18B20 = dat & 0x01; //然后写入一个数据,从最低位开始i=6; while(i--); //延时68微秒DS18B20 = 1; //释放总线,给总线1微秒恢复时间才能接着写入下一位 dat >>= 1;}
}int DS18B20_ReadTemp() //读取的温度有两个字节,分别用tml和tmh存储两个字节
{int temp = 0;uchar tmh, tml;DS18B20_Init(); //传感器初始化delay_ms(1); //延时1微秒DS18B20_WriteByte(0xcc); //跳过读取序列号操作 DS18B20_WriteByte(0x44); //温度转换指令 //完成温度转换功能DS18B20_Init(); //传感器初始化delay_ms(1); DS18B20_WriteByte(0xcc); //跳过读取序列号操作DS18B20_WriteByte(0xbe); //发送读取温度指令//然后等待转换完后发送读取温度命令tml = DS18B20_ReadByte(); //读取温度值共16位,先读低字节tmh = DS18B20_ReadByte(); //再读高字节temp = tmh; //先存高字节,后面通过移位存储低字节temp <<= 8;temp |= tml;return temp;
}uint Temper_change()
{uint temper;float tp;//temper=read_temper();temper=DS18B20_ReadTemp();if(temper<0) //考虑负温度的情况{temper=temper-1;temper=~temper;tp=temper*0.0625; //16位温度转换成10进制的温度temper=tp*100+0.5; //留两个小数点,并四舍五入}else{tp=temper*0.0625; //16位温度转换成10进制的温度temper=tp*100+0.5; //留两个小数点,并四舍五入}return temper;
}
DS18B20.h
#ifndef __DS18B20_H__
#define __DS18B20_H__
#include<reg52.h>#define uchar unsigned char
#define uint unsigned intuint Temper_change();void delay_ms(unsigned int x);//延时1ms
#endif
3.调用举例
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>
#include "ds18b20.h"unsigned int temper_value;//用于存储温度数据void main(void)
{
while (1) { temper_value = Temper_change();//temper_value,后续可以用来显示、或者判断等。}
}