1、DS18B20.h 文件。主要用于函数声明和管脚定义。
#ifndef _DS18B20_H_ #define _DS18B20_H_ #include <intrins.h> #include <reg52.h> sbit DS = P1^7; ///温度测量芯片数据线 void delayus(unsigned char i); void delayms(int j); unsigned char DS18B20_Initial(); unsigned char DS18B20_ReadByte(); void DS18B20_SendByte(unsigned char dat); float DS18B20_ReadTmp(); #endif
2、DS18B20.c 文件,驱动程序 DS18B20驱动的重点是单片机IO口模拟通信时序。
/* DS18B20温度传感器驱动程序,调用方法为:调用函数DS18B20_ReadTmp(),返回浮点温度值, 返回的温度单位为℃ 。 */ #include <reg52.h> #include <DS18B20.h> #include <intrins.h> /* *函数名 :delayus(unsigned char i) *功能 : 产生微秒级延时,经调试,12MH延迟方程为晶振时 t=6i 8 , 所需延迟时间对应的i值为: 10us i=0(误差-1), 15us i=1(误差-1),45us i=6(误差-1), 60us i=9(误差 2), 80us i=12(误差0),480us i=79(误差 2) *输入 :延时参数 i *输出 :无 */ void delayus(unsigned char i) ///经调试,延迟方程为 t=6i 8 , 所需延迟时间对应的i值为: {
while(i) {
--i; } } /* *函数名 :delayms(int j) *功能 :毫秒级延迟 t=0.21i 0.01 (t单位ms) *输入 :j *输出 :无 */ void delayms(int j) {
while(j) {
unsigned char k=100;
while(k)
{
--k;
}
--j;
}
}
/* *函数名 : DS18B20_Initial() *功能 : DS18B20的初始化 *输入 : 无 *输出 :初始化失败返回0,成功返回1 */
unsigned char DS18B20_Initial()
{
unsigned char i=0;
DS=0;
delayus(85); //延时480us !!!79改85,增加一些延时
DS=1;
while(DS)
{
delayus(15); //延时约100us
i++;
if(i>5) //等待>500us
{
return 0; //初始化失败
}
}
delayus(85);
return 1; //初始化成功,给初始化函数返回1
}
/* *函数名 :DS18B20_ReadByte() *功能 : 读取一个字节的数据 *输入 : 无 *输出 : 读取到的数据*/
unsigned char DS18B20_ReadByte() /*单纯地复制存储数据位,不需要算术运算 因此用无符号数,不能用有符号数,否则符号会占用数据位*/
{
unsigned char dat=0,bi=0;
unsigned char i;
for(i=0;i<8;i++)
{
DS=0; //拉低数据线
_nop_(); //空指令,占用1个机器周期的时间,12MHz晶振时为1us
DS=1; //释放数据线
delayus(0); //延时10us ,等待温度芯片发送数据线
dat=dat>>1; //右移1位,准备给最高位存入数据
bi=DS; //DS不是数据,不能进行移位操作,要先存入数据字符bi中
dat=dat|(bi<<7); /***将数据线DS的数据赋值到变量dat的第8位(最高位)中 传感器是从低位开始发送数据,单片机要将收到的数据先存入高位,再一步步移至低位***/
delayus(6); //延时48us,进行下一次读取
}
return dat;
}
/* *函数名 : DS18B20_SendByte(unsigned short int dat) *功能 : 发送一个字节命令 *输入 : 需要发送的数据 *输出 :无 */
void DS18B20_SendByte(unsigned char dat)
{
unsigned char a;
for(a=0;a<8;a++)
{
DS=0;
delayus(1); //延时15us,准备写入数据
DS=dat&0x01; //写入一位数据,写入最低位数据
dat=dat>>1;
delayus(9); //延时等待60us
DS=1; //再次拉高数据线
}
}
/* *函数名: DS18B20_ReadTmp() *函数功能: 读取温度数据,并转换成以℃为单位的数值 *输入: 无 *输出: 温度值 */
float DS18B20_ReadTmp()
{
unsigned char tml,tmh; //温度数据的低字节和高字节。分开、连续读取
unsigned int tmp=0; //全部字节的温度数据(16字节)
float temperature; //经转换系数运算后的温度数据,℃
DS18B20_Initial(); //温度芯片初始化
delayms(5); //初始化完成后延时个1ms(时序图没有这样的要求)。
DS18B20_SendByte(0xcc); //跳过ROM,跳过温度芯片地址识别,直接进行温度变换
DS18B20_SendByte(0x44); //发送温度变换命令
DS18B20_Initial(); //温度芯片初始化
delayms(5); //初始化完成后延时个1ms(时序图没有这样的要求)。
DS18B20_SendByte(0xcc);
DS18B20_SendByte(0xbe); //发送读暂存器命令
tml=DS18B20_ReadByte(); //读取温度数据低字节,并存储到临时变量tml中
tmh=DS18B20_ReadByte();
tmp=tmp|tmh; //全温度字节中存入高字节
tmp=(tmp<<8)|tml; //全温度字节中存入低字节
temperature = tmp*0.0625; //换算温度值,℃
return temperature; //将临时变量tmp的值返回给读温度指令,以便后续进行数据处理
}