资讯详情

基于51单片机的DS18B20温度传感器

DS18B20温度传感器

芯片AT89S52 如下

/************************************************************************* 该程序的功能如下:DS18B20使用程序。将DS18B读取20的温度值并显示 示在液晶LCD1602上。 作者:Crazy Wind 日期:2020.11.9 version:1.0.0 **************************************************************************/ #include"reg52.h" #include"intrins.h" #define uchar unsigned char #define uint unsigned int uchar code digit[11]={ 
        "0123456789-"};     ///定义字符数组显示数字 uchar code Str[]={ 
        "DS18B20"};         //说明显示的是温度 uchar code Error[]={ 
        " DS18B20 ERROR"};   //说明没有检测到DS18B20 uchar code Error1[]={ 
        " PLEASE CHECK"};   //说明没有检测到DS18B20 uchar code Temp[]={ 
        "Temp:"};              ///说明显示温度 uchar code Cent[]={ 
        "C"};                  ///温度单位 uchar flag,tltemp;        ///负温度标志和临时暂存变量  /***************************************************** 函数功能:ms延时 ******************************************************/ void delayms(uint ms)  { 
          uchar i,j;     for(i=0;i<ms;i )     { 
                 for(j=115;j>0;j--)
       
        ; 
        } 
        } 
        /*****************************************************************/ 
        /***********************液晶LCD1602操作程序***********************/ 
        /*****************************************************************/ sbit RS
        =P2
        ^
        0
        ; 
        //寄存器选择位RS为P2.0 sbit RW
        =P2
        ^
        1
        ; 
        //读写选择位RW为P2.1 sbit E
        =P2
        ^
        2
        ; 
        //使能信号位E为P2.2 sbit BF
        =P0
        ^
        7
        ; 
        //忙碌标志位BF为P0.7 
        /***************************************************** 函数功能:判断液晶模块的忙碌状态 返回值:busy。busy=1,忙碌;busy=0,不忙 ******************************************************/ bit 
        BusyTest
        (
        void
        ) 
        { 
          bit busy
        ; RS
        =
        0
        ; 
        //RS为低电平,RW为高电平时,可以读状态 RW
        =
        1
        ; E
        =
        1
        ; 
        //E=1,才允许读写 
        _nop_
        (
        )
        ; 
        //空操作四个机器周期,给硬件反应时间 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; busy
        =BF
        ; 
        //将忙碌标志电平赋给m E
        =
        0
        ; 
        return busy
        ; 
        //将忙碌标志电平赋给m 
        } 
        /***************************************************** 函数功能:将模式设置指令或显示地址写入液晶模块 入口参数:z ******************************************************/ 
        void 
        Write_zl
        (uchar z
        ) 
        { 
          
        while
        (
        BusyTest
        (
        )
        ==
        1
        )
        ; 
        //如果忙就等待 RS
        =
        0
        ; 
        //RS和RW同时为低电平时,可以写入指令 RW
        =
        0
        ; E
        =
        0
        ; 
        //使能信号E置低电平(写指令前先赋低电平0) 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        //空操作两个机器周期,给硬件反应时间 P0
        =z
        ; 
        //将数据送入P0口(数据总线line),即写入指令或地址 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        //空操作四个机器周期,给硬件反应时间 E
        =
        1
        ; 
        //使能信号E上升沿(0到1)时读取信息 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        //空操作四个机器周期,给硬件反应时间  E
        =
        0
        ; 
        //使能信号E下降沿(1到0)时执行指令 
        } 
        /***************************************************** 函数功能:指定字符显示的实际地址 入口参数:x ******************************************************/ 
        void 
        WriteAddress
        (uchar x
        ) 
        { 
          
        Write_zl
        (x
        |
        0x80
        )
        ; 
        //显示位置的确定方法规定为"地址码x+80H"  
        } 
        /***************************************************** 函数功能:将数据(字符的标准ASCII码)写入液晶模块 入口参数:y(为字符常量) ******************************************************/ 
        void 
        WriteData
        (uchar y
        ) 
        { 
          
        while
        (
        BusyTest
        (
        )
        ==
        1
        )
        ; 
        //如果忙就等待 RS
        =
        1
        ; 
        //RS为高电平,RW为低电平时,可以写入数据 RW
        =
        0
        ; E
        =
        0
        ; 
        //使能信号E置低电平(写数据前先赋低电平0) 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        //空操作两个机器周期,给硬件反应时间 P0
        =y
        ; 
        //将数据送入P0口(数据总线line),即将数据写入液晶模块 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        //空操作四个机器周期,给硬件反应时间 E
        =
        1
        ; 
        //使能信号E上升沿(0到1)时读取信息 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        _nop_
        (
        )
        ; 
        //空操作四个机器周期,给硬件反应时间 E
        =
        0
        ; 
        //使能信号E下降沿(1到0)时执行指令  
        } 
        /***************************************************** 函数功能:对LCD的显示模式进行初始化设置 ******************************************************/ 
        void 
        LcdInit
        (
        void
        ) 
        { 
          
        delayms
        (
        15
        )
        ; 
        //延时15ms,首次写指令时应给LCD一段较长的反应时间 
        Write_zl
        (
        0x38
        )
        ; 
        //显示模式设置:16×2显示,5×7点阵,8位数据接口 
        delayms
        (
        5
        )
        ; 
        //延时5ms  
        Write_zl
        (
        0x38
        )
        ; 
        delayms
        (
        5
        )
        ; 
        Write_zl
        (
        0x38
        )
        ; 
        //3次写 设置模式 
        delayms
        (
        5
        )
        ; 
        Write_zl
        (
        0x0c
        )
        ; 
        //显示模式设置:显示开,无光标,光标不闪烁 
        delayms
        (
        5
        )
        ; 
        Write_zl
        (
        0x06
        )
        ; 
        //显示模式设置:光标右移,字符不移 
        delayms
        (
        5
        )
        ; 
        Write_zl
        (
        0x01
        )
        ; 
        //清屏幕指令,将以前的显示内容清除 
        delayms
        (
        5
        )
        ; 
        } 
        /*****************************************************************/ 
        /*************************DS18B20操作程序*************************/ 
        /*****************************************************************/ sbit DQ
        =P3
        ^
        3
        ; 
        //DS18B20管脚 uchar time
        ; 
        //设置全局变量,专门用于严格延时 
        /***************************************************** 函数功能:将DS18B20传感器初始化,读取应答信号 出口参数:flag ******************************************************/ bit 
        Init_DS18B20
        (
        void
        ) 
        { 
          bit flag
        ; 
        //储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在 DQ
        =
        1
        ; 
        //先将数据线拉高 
        for
        (time
        =
        0
        ;time
        <
        2
        ;time
        ++
        )
        ; 
        //略微延时约6μs  DQ
        =
        0
        ; 
        //再将数据线从高拉低,要求保持480~960μs 
        for
        (time
        =
        0
        ;time
        <
        200
        ;time
        ++
        )
        ; 
        //略微延时约600μs,以向DS18B20发出一持续480~960μs的低电平复位脉冲 DQ
        =
        1
        ; 
        //释放数据线(将数据线拉高)  
        for
        (time
        =
        0
        ;time
        <
        10
        ;time
        ++
        )
        ; 
        //延时约30μs(释放总线后需等待15~60μs让DS18B20输出存在脉冲)  flag
        =DQ
        ; 
        //让单片机检测是否输出了存在脉冲(DQ=0表示存在)  
        for
        (time
        =
        0
        ;time
        <
        200
        ;time
        ++
        )
        ; 
        //延时足够长时间,等待存在脉冲输出完毕 
        return 
        (flag
        )
        ; 
        //返回检测成功标志 
        } 
        /***************************************************** 函数功能:向DS18B20写一个字节数据 出口参数:dat ******************************************************/ 
        void 
        WriteOneChar
        (uchar dat
        ) 
        { 
          uchar i
        =
        0
        ; 
        for
        (i
        =
        0
        ;i
        <
        8
        ;i
        ++
        ) 
        { 
          DQ
        =
        1
        ; 
        //先将数据线拉高 
        _nop_
        (
        )
        ; 
        //等待一个机器周期  DQ
        =
        0
        ; 
        //将数据线从高拉低,即启动写时序  DQ
        =dat
        &
        0x01
        ; 
        //给数据线送dat中二进制数据的低位,等待DS18B20采样  
        for
        (time
        =
        0
        ;time
        <
        10
        ;time
        ++
        )
        ; 
        //延时约30μs,DS18B20在拉低后的约15~60μs期间从数据线上采样 DQ
        =
        1
        ; 
        //释放数据线  
        for
        (time
        =
        0
        ;time
        <
        1
        ;time
        ++
        )
        ; 
        //延时3μs,两个写时序间至少需要1μs的恢复期 dat
        >>=
        1
        ; 
        //将dat中的各二进制位数据右移1位 
        } 
        for
        (time
        =
        0
        ;time
        <
        4
        ;time
        ++
        )
        ; 
        //稍作延时,给硬件一点反应时间 
        } 
        /***************************************************** 函数功能:从DS18B20读一个字节数据 出口参数:dat ******************************************************/ uchar 
        ReadOneChar
        (
        void
        ) 
        { 
          uchar i
        =
        0
        ; uchar dat
        ; 
        //储存读出的一个字节数据 
        for
        (i
        =
        0
        ;i
        <
        8
        ;i
        ++
        ) 
        { 
          DQ
        =
        1
        ; 
        // 先将数据线拉高 
        _nop_
        (
        )
        ; 
        //等待一个机器周期  DQ
        =
        0
        ; 
        //将数据线从高拉低,即启动读时序 
        _nop_
        (
        )
        ; 
        //等待一个机器周期  DQ
        =
        1
        ; 
        //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备 
        for
        (time
        =
        0
        ;time
        <
        2
        ;time
        ++
        )
        ; 
        //延时约6μs,使主机在15μs内采样 dat
        >>=
        1
        ; 
        //将dat中的各二进制位数据右移1位 
        if
        (DQ
        ==
        1
        ) dat
        |
        =
        0x80
        ; 
        //如果读到的数据是1,则将1存入dat 
        else dat
        |
        =
        0x00
        ; 
        //如果读到的数据是0,则将0存入dat  
        for
        (time
        =
        0
        ;time
        <
        8
        ;time
        ++
        )
        ; 
        //延时3μs,两个读时序之间必须有大于1μs的恢复期  
        } 
        return
        (dat
        )
        ; 
        //返回读出的十六进制数据 
        } 
        /***************************************************** 函数功能:从DS18B20读一个字节数据 出口参数:dat ******************************************************/ 
        void 
        ReadyReadTemp
        (
        void
        ) 
        { 
          
        Init_DS18B20
        (
        )
        ; 
        //将DS18B20初始化 
        WriteOneChar
        (
        0xCC
        )
        ; 
        //跳过读序号列号的操作 
        WriteOneChar
        (
        0x44
        )
        ; 
        //启动温度转换  
        delayms
        (
        200
        )
        ; 
        //转换一次需要延时一段时间  
        Init_DS18B20
        (
        )
        ; 
        //将DS18B20初始化 
        WriteOneChar
        (
        0xCC
        )
        ; 
        //跳过读序号列号的操作 
        WriteOneChar
        (
        0xBE
        )
        ; 
        //读取温度寄存器,前两个分别是温度的低位和高位  
        } 
        /*****************************************************************/ 
        /****************************显示模块*****************************/ 
        /*****************************************************************/ uchar code zidingyi
        [
        ]
        =
        { 
         
        0x07
        ,
        0x05
        ,
        0x07
        ,
        0x00
        ,
        0x00
        ,
        0x00
        ,
        0x00
        ,
        0x00
        }
        ; 
        //自定义字符 
        /***************************************************** 函数功能:显示没有检测到DS18B20 ******************************************************/ 
        void 
        display_error
        (
        void
        ) 
        { 
          uchar i
        ; 
        WriteAddress
        (
        0x00
        )
        ; 
        //写显示地址,将在第1行第1列开始显示 i
        =
        0
        ; 
        while
        (Error
        [i
        ]
        !=
        '\0'
        ) 
        //"\0"数组结束标志 
        { 
          
        WriteData
        (Error
        [i
        ]
        )
        ; 
        //将字符常量写入LCD i
        ++
        ; 
        delayms
        (
        100
        )
        ; 
        //延时100ms 
        } 
        WriteAddress
        (
        0x40
        )
        ; 
        //写显示地址,将在第2行第1列开始显示 i
        =
        0
        ; 
        while
        (Error1
        [i
        ]
        !=
        '\0'
        ) 
        //"\0"数组结束标志 
        { 
          
        WriteData
        (Error1
        [i
        ]
        )
        ;
        //将字符常量写入LCD i
        ++
        ; 
        delayms
        (
        100
        )
        ; 
        //延时100ms 
        } 
        while
        (
        1
        )
        ; 
        //进入死循环,等待查明原因  
        } 
        /***************************************************** 函数功能:显示说明信息 ******************************************************/ 
        void 
        display_explain
        (
        void
        ) 
        { 
          uchar i
        ; 
        WriteAddress
        (
        0x04
        )
        ; 
        //写显示地址,将在第1行第5列开始显示 i
        =
        0
        ; 
        while
        (Str
        [i
        ]
        !=
        '\0'
        ) 
        //"\0"数组结束标志 
        { 
          
        WriteData
        (Str
        [i
        ]
        )
        ; 
        //将字符常量写入LCD i
        ++
        ; 
        delayms
        (
        100
        )
        ; 
        //延时100ms 
        } 
        } 
        /***************************************************** 函数功能:显示说明信息 ******************************************************/ 
        void 
        display_symbol
        (
        void
        ) 
        { 
          uchar i
        ; 
        WriteAddress
        (
        0x40
        )
        ; 
        //写显示地址,将在第2行第1列开始显示 i
        =
        0
        ; 
        while
        (Temp
        [i
        ]
        !=
        '\0'
        ) 
        //"\0"数组结束标志 
        { 
          
        WriteData
        (Temp
        [i
        ]
        )
        ; 
        //将字符常量写入LCD i
        ++
        ; 
        delayms
        (
        50
        )
        ; 
        //延时50ms 
        } 
        } 
        /***************************************************** 函数功能:显示温度的小数点 ******************************************************/ 
        void 
        display_dot
        (
        void
        ) 
        { 
          
        WriteAddress
        (
        0x49
        )
        ; 
        //写显示地址,将在第2行第10列开始显示  
        WriteData
        (
        '.'
        )
        ; 
        //将小数点的字符常量写入LCD 
        delayms
        (
        50
        )
        ; 
        //延时50ms  
        } 
        /***************************************************** 函数功能:显示温度的单位(Cent) ******************************************************/ 
        void 
        display_cent
        (
        void
        ) 
        { 
          uchar i
        ,a
        ; 
        WriteAddress
        (
        0x4d
        )
        ; 
        //写显示地址,将在第2行第14列开始显示  i
        =
        0
        ; 
        while
        (Cent
        [i
        ]
        !=
        '\0'
        ) 
        //"\0"数组结束标志 
        { 
          
        WriteData
        (Cent
        [i
        ]
        )
        ;
        //将字符常量写入LCD i
        ++
        ; 
        delayms
        (
        50
        )
        ; 
        //延时50ms 
        } 
        Write_zl
        (
        0x40
        )
        ; 
        //设定CGRAM地址 
        delayms
        (
        5
        )
        ; 
        for
        (a
        =
        0
        ;a
        <
        8
        ;a
        ++
        ) 
        { 
          
        WriteData
        (zidingyi
        [a
        ]
        )
        ; 
        //写入自定义图形  
        } 
        WriteAddress
        (
        0x4c
        )
        ; 
        //设定屏幕上的显示位置 
        delayms
        (
        5
        )
        ; 
        WriteData
        (
        0x00
        )
        ; 
        //从CGRAM里取出自定义图形显示  
        } 
        /***************************************************** 函数功能:显示温度的整数部分 入口参数:x ******************************************************/ 
        void 
        display_temp1
        (uchar x
        ) 
        { 
          uchar b
        ,s
        ,g
        ; 
        //分别储存温度的百位、十位和个位 b
        =x
        /
        100
        ; 
        //取百位 s
        =
        (x
        %
        100
        )
        /
        10
        ; 
        //取十位 g
        =x
        %
        10
        ; 
        //取个位  
        WriteAddress
        (
        0x46
        )
        ; 
        //写显示地址,将在第2行第7列开始显示 
        if
        (flag
        ==
        1
        ) 
        //负温度时显示“—” 
        { 
          
        WriteData
        (digit
        [
        10
        ]
        )
        ; 
        //将"-"的字符常量写入LCD 
        } 
        else 
        { 
          
        WriteData
        (digit
        [b
        ]
        )
        ; 
        //将百位数字的字符常量写入LCD 
        } 
        WriteData
        (digit
        [s
        ]
        )
        ; 
        //将十位数字的字符常量写入LCD 
        WriteData
        (digit
        [g
        ]
        )
        ; 
        //将个位数字的字符常量写入LCD 
        delayms
        (
        50
        )
        ; 
        //延时50ms  
        } 
        /***************************************************** 函数功能:显示温度的小数数部分 入口参数:x ******************************************************/ 
        void 
        display_temp2
        (uchar x
        ) 
        { 
          
        WriteAddress
        (
        0x4a
        )
        ; 
        //写显示地址,将在第2行第11列开始显示 
        WriteData
        (digit
        [x
        ]
        )
        ; 
        //将小数部分的第一位数字字符常量写入LCD 
        
        标签: ds18b20温度传感器参数

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台