找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8185|回复: 3
打印 上一主题 下一主题
收起左侧

DS18B20的C51程序及DS18b20.h头文件下载

[复制链接]
跳转到指定楼层
楼主
ID:75263 发表于 2015-3-25 00:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
                                                                                                 //******************************************************************************
//  用于河北北方学院宣化教学部2015级单片机课程实验的
//   单线数字温度传感器DS18B20的C51驱动代码
//  
//  代码沿革
//      创建: 2015年4月1日
//      修改: 2015年4月4日,代码优化
//            2015年4月9日,注释
//  版权声明
//      1.版权拥有者是河北北方学院宣化教学部2005级单片机课程全体学生及该课程任课
//        教师.
//      2.任何团体或个人均可无条件使用本代码, 但版权拥有者不对由此引起的任何直接
//        或间接后果负担任何法律责任
//        3.一旦部分或全部使用本代码,则必须在源程序文档中无条件包含本版权声明
//******************************************************************************
#include "DS18b20.h"
#include "reg52.h"

//******************************************************************************
//  DS18B20复位和初始化函数: DS18B20_Reset(void)
//  功能: 8051发出时间长度>=480us的低电平到数据线,然后拉高数据线维持15~60us
//  输入: 无
//  输出: DS18B20被复位
//  返回: 无
//******************************************************************************
void DS18B20_Reset(void)
{
  uchar i;
  DQ = 0;                                                         //拉低数据线DQ
  i = 80;                     //使用12MHz晶体时用80,根据晶体频率按比例增减i的值
  while(i--);   //软件延时,"while(i--);"的反汇编代码单次循环消耗6us,80*6us=480us
  
  DQ = 1;
  i = 5;                         //使用12MHz晶体时用5,根据晶体频率按比例增减
  while(i--);     //软件延时,"while(i--);"的反汇编代码单次循环消耗6us,5*6us=30us
}
//******************************************************************************
//  读取一位数据函数: bit bitread(void)
//  功能: 51发长3us的低电平到数据线, 然后拉高数据线7us,再读回数据线,最后由软件延
//        时消耗掉60us位时间的剩余部分.
//  输入: 无
//  输出: 无
//  返回: 位值
//******************************************************************************
bit bitread(void)
{
  uchar i;
  bit dat;
  DQ = 0;                                                  //拉低数据线DQ
  i++;                                 //模拟1~15us的延时,反汇编显示实际延时3us
  DQ = 1;                                               //拉高数据线DQ
  i++;  i++;                                    //适当延时,反汇编显示实际延时7us
  dat = DQ;                            //至此,DS18B20会在DQ上给出位值,读回此位值
  i = 8;              //从DQ拉低至此,反汇编显示已耗时13us, 60us-13us=47us约=48us
  while(i--);     //软件延时,"while(i--);"的反汇编代码单次循环消耗6us,8*6us=48us
  return(dat);                                                        //返回位值
}
//******************************************************************************
//  读取一个字节数据函数: uchar byteread(void)
//  功能: 通过8次调用读取一位函数, 从DS18B20读回一个字节值,注意先读的是最低位
//  输入: 无
//  输出: 无
//  返回: 字节值
//******************************************************************************
uchar byteread(void)
{
  uchar i, j, dat;
  dat = 0;
  for(i=1; i<=8; i++)
  {
    j = bitread();                                                 //顺序读8个位
    dat >>= 1;
    dat |= (j<<7);                                              //组装成一个字节
  }
  return(dat);                                               //返回字节值
}
//******************************************************************************
//  写一个字节数据或命令函数: bytewrite(uchar dat)
//  功能: 写一个字节数据或命令到DS18B20中
//  输入: dat是准备写入DS18B20的一个命令字节或数据字节
//  输出: 命令字节或数据字节被写入DS18B20中
//  返回: 无
//  按位写入: 位值1写法:在DQ上发 1~ 15us低电平后跟高电平,应使位时间>=60us
//            位值0写法:在DQ上发60~120us低电平后跟高电平,应使位时间>=60us
//  注意:延时时间的统计计算需要浏览反汇编代码
//******************************************************************************
void bytewrite(uchar dat)
{
  uchar i, j;
  for(j=0; j<8; j++)
  {
    if(dat&0x01)          //如果当前位的值为1,发1~15us低电平后跟高电平到数据线DQ
    {
   DQ = 0;                                                   //拉低数据线DQ
   DQ = 0;                                //延时1us
   DQ = 0;                                      //到此共延时2us, 1us<2us<15us
      DQ = 1;                                                     //拉高数据线DQ
      i = 7;                               //自DQ拉低后到此语句执行完毕共耗时4us  
   while(i--);                    //每次循环耗时8us,7*8us=56us, 56us+4us=60us
    }
    else                //如果当前位的值为0,发60~120us低电平后跟高电平到数据线DQ
    {
   DQ = 0;                                        //拉低数据线DQ
      i = 8;  while(i--);                          //延时约65us, 60us<65us<120us
      DQ =1;                                                      //拉高数据线DQ
      DQ =1;                                                           //延时1us
      DQ =1;                                                           //延时2us
    }
    dat = dat>>1;                                           //右移,准备下一个位
  }
}
//******************************************************************************
//  温度转换启动函数: uchar DS18B20_Start(void)
//  功能: 复位DS18B20并检测其是否在位,若在位则启动温度转换
//  输入: 无
//  输出: 若DS18B20在位,启动温度转换过程
//  返回: 0启动失败,1启动成功
//******************************************************************************
uchar DS18B20_Start(void)
{
  uchar i = 10;
  DS18B20_Reset();      //复位DS18B20,返回时DQ已拉高,DS18B20最多60us后发在位脉冲
  while((DQ==1) &&                     //等待DS18B20在数据线DQ上发低电平在位脉冲
        (i--));                                        //最多等待80us(80us>60us)
  if(i!=0)                        //在i递减到0之前检测到DQ被拉低,说明DS18B20在位
  {
    while(DQ==0);                  //等待DS18B20把她的在位脉冲发完(持续60~120us)
    bytewrite(0xcc);                              //写"跳过ROM检测命令"到DS18B20
    bytewrite(0x44);                             //写"开始温度转换命令"到DS18B20
return 1;
  }
  return 0;
}
//******************************************************************************
//  读取温度值函数: DS18B20_Tempread(void)
//  输入: 无
//  输出: 无
//  返回: 补码表示的摄氏温度值,有符号整型数,若DS18B20异常则返回0x7fff
//******************************************************************************
int DS18B20_Tempread(void)
{
  uchar a, b, i = 10;
  DS18B20_Reset();      //复位DS18B20,返回时DQ已拉高,DS18B20最多60us后发在位脉冲
  while((DQ==1) &&                     //等待DS18B20在数据线DQ上发低电平在位脉冲
        (i--));                                        //最多等待80us(80us>60us)
  if(i!=0)                        //在i递减到0之前检测到DQ被拉低,说明DS18B20在位
  {
    while(DQ==0);                  //等待DS18B20把她的在位脉冲发完(持续60~120us)
    bytewrite(0xcc);                              //写"跳过ROM检测命令"到DS18B20
    bytewrite(0xbe);                          //写"连续读9个寄存器命令"到DS18B20      
    a = byteread();                             //读第一个寄存器(温度值低字节)
    b = byteread();                             //读第二个寄存器(温度值高字节)
                ;                                           //其余7个寄存器不读
    return (a + (b*256));                               //温度值组装成一个16位字
  }
  return 0x7fff; //最高五位正常情况下是值相同的符号位,现为01111,表明DS18B20异常
}
//******************************************************************************
//  配置函数: void DS18B20_Set(uchar v_reg2, v_reg3, v_reg4)
//  配置DS18B20的高温阀值寄存器,低温阀值寄存器,分辨率设置寄存器
//  输入: v_reg2  高温阀值寄存器的值
//    v_reg3  低温阀值寄存器的值
//        v_reg4  分辨率设置寄存器的值
//  输出: 若DS18B20在位,指定的三个寄存器被配置好
//  返回: 无
//******************************************************************************
void DS18B20_Set(uchar v_reg2, v_reg3, v_reg4)
{
  uchar i = 10;
  DS18B20_Reset();      //复位DS18B20,返回时DQ已拉高,DS18B20最多60us后发在位脉冲
  while((DQ==1) &&                     //等待DS18B20在数据线DQ上发低电平在位脉冲
        (i--));                                        //最多等待80us(80us>60us)
  if(i!=0)                        //在i递减到0之前检测到DQ被拉低,说明DS18B20在位
  {
    while(DQ==0);                  //等待DS18B20把她的在位脉冲发完(持续60~120us)
    v_reg4 |=  0x80;                                            //保证最高位TM=1
    bytewrite(0xcc);                              //写"跳过ROM检测命令"到DS18B20
    bytewrite(0x4e);                          //写"连续写9个寄存器命令"到DS18B20      
    bytewrite(0x00);                 //写第一个寄存器(温度值低字节,写无意义,给0)
    bytewrite(0x00);                 //写第二个寄存器(温度值高字节,写无意义,给0)
    bytewrite(v_reg2);                                //写第三个寄存器(高温阀值)
    bytewrite(v_reg3);                                //写第四个寄存器(低温阀值)
    bytewrite(v_reg4);                                  //写第五个寄存器(分辨率)
    ;                                                        //其余4个寄存器不写
   }
}

//******************************************************************************
//读取64位ROM
//******************************************************************************
uchar sn[8];
void DS18B20_Readrom(void)
{
  uchar i = 10;
  DS18B20_Reset();      //复位DS18B20,返回时DQ已拉高,DS18B20最多60us后发在位脉冲
  while((DQ==1) &&                     //等待DS18B20在数据线DQ上发低电平在位脉冲
        (i--));                                        //最多等待80us(80us>60us)
  if(i!=0)                        //在i递减到0之前检测到DQ被拉低,说明DS18B20在位
  {
    while(DQ==0);                  //等待DS18B20把她的在位脉冲发完(持续60~120us)
    bytewrite(0x33);
    for(i=0; i<8; i++)
      sn[ i] = byteread();
  }
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:75263 发表于 2015-3-25 00:44 | 只看该作者
DS18b20.h头文件下载:(复制后用记事本保存为:DS18b20.h)
  1. #ifndef DS18B20_H
  2. #define DS18B20_H
  3. #include "reg52.h"
  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. #define ulong unsigned long int
  7. sbit DQ = P1^0;
  8. uchar DS18B20_Start();
  9. int DS18B20_Tempread();
  10. void DS18B20_Set(uchar v_reg2, v_reg3, v_reg4);
  11. void readrom(void);
  12. #endif
复制代码


回复

使用道具 举报

板凳
ID:215280 发表于 2017-7-4 14:45 | 只看该作者
有了这个头文件不知道怎么设置,不知道放哪儿,然后程序就还是显示找不到文件!proteus刚学了几天就让做实物!!!
回复

使用道具 举报

地板
ID:503157 发表于 2019-4-16 13:53 | 只看该作者
点击工具栏上 Options for Target 魔术棒图标,在弹出窗口中选 C/C++ 标签页,在 Include Paths 栏中填入 .h 文件路径。比如子目录名就是"h",那就要在栏中填入".\h"。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表