蓝桥杯国信长天单片机—DS18B20 温度传感器设计(九)

DS18B20 是单线接口数字温度传感器,测量范围是-55℃~+125℃,-10℃~+85℃范围内精
度是±0.5℃,测量分辨率为 9~12 位(复位值为 12 位,最大转换时间为 750ms)。
DS18B20 包括寄生电源电路、64 位 ROM 和单线接口电路、暂存器、EEPROM、8 位 CRC 生
成器和温度传感器等。寄生电源电路可以实现外部电源供电和单线寄生供电,64 位 ROM 中存放
的 48 位序列号用于识别同一单线上连接的多个 DS18B20,以实现多点测温。
64 位 ROM 代码的格式为:

8 位 CRC 校验码 + 48 位序列号 + 8 位系列码(0x28) 其中 8 位 CRC 校验码是 48 位序列号和 8 位系列码的
CRC 校验码。

DS18B20 的暂存器如表

DS18B20 的操作包括下列 3 步:

复位
ROM 命令
功能命令
DS18B20 ROM 功能命令如表

国信长天单片机竞赛实训平台的 DS18B20 电路图如图

基于国信长天单片机竞赛实训平台的温度传感器示例程序

    #include "reg52.h"  //定义51单片机特殊功能寄存器
    #include "onewire.h"  //单总线函数库
    #include "absacc.h"

    sfr AUXR = 0x8E;

    unsigned char dspbuf[8] = {10,10,10,10,10,10,10,10};//显示缓冲区
    unsigned char dspcom = 0;
    unsigned char intr;
    bit temper_flag = 0;//温度读取标志
    code unsigned char tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
                                0xff
                               };

    void display(void);

    void cls_buzz()
    {
        P2 = ((P2&0x1f)|0xA0);
        P0 = 0x00;
        P2 &= 0x1f;
    }
    void cls_led()
    {
        P2 = ((P2&0x1f)|0x80);
        P0 = 0xFF;
        P2 &= 0x1f;
    }

    //主函数
    void main(void)
    {
        unsigned char temperature;

        cls_buzz();
        cls_led();

        AUXR |= 0x80;
        TMOD &= 0xF0;
        TL0 = 0xCD;
        TH0 = 0xD4;
        TF0 = 0;
        TR0 = 1;
        ET0 = 1;
        EA = 1;

        while(1)
        {
            if(temper_flag)
            {
                temper_flag = 0;
                temperature = rd_temperature();  //读温度
            }

            //显示数据更新
            (temperature>=10)?(dspbuf[6] = temperature/10):(dspbuf[6]=10);
            dspbuf[7] = temperature%10;
        }
    }

    //定时器中断服务函数
    void isr_timer_0(void)  interrupt 1  //默认中断优先级 1
    {
        display();
        if(++intr == 100)  //1ms执行一次
        {
            intr = 0;
            temper_flag = 1;  //100ms温度读取标志位置1
        }
    }

    //显示函数
    void display(void)
    {
        P2 = ((P2&0x1f)|0xE0);
        P0 = 0xff;
        P2 &= 0x1f;

        P0 = 1<<dspcom;
        P2 = ((P2&0x1f)|0xC0);
        P2 &= 0x1f;

        P0 = tab[dspbuf[dspcom]];
        P2 = ((P2&0x1f)|0xE0);
        P2 &= 0x1f;

        if(++dspcom == 8) {
            dspcom = 0;
        }
    }
    /*--------------------------------------------------------------------------
    ABSACC.H

    Direct access to 8051, extended 8051 and NXP 8051MX memory areas.
    Copyright (c) 1988-2010 Keil Elektronik GmbH and ARM Germany GmbH
    All rights reserved.
    --------------------------------------------------------------------------*/

    #ifndef __ABSACC_H__
    #define __ABSACC_H__

    #define CBYTE ((unsigned char volatile code  *) 0)
    #define DBYTE ((unsigned char volatile data  *) 0)
    #if !defined (__CX2__)
    #define PBYTE ((unsigned char volatile pdata *) 0)
    #endif
    #define XBYTE ((unsigned char volatile xdata *) 0)

    #define CWORD ((unsigned int volatile code  *) 0)
    #define DWORD ((unsigned int volatile data  *) 0)
    #if !defined (__CX2__)
    #define PWORD ((unsigned int volatile pdata *) 0)
    #endif
    #define XWORD ((unsigned int volatile xdata *) 0)


    #if defined (__CX51__) || defined (__CX2__)
    #define FVAR(object, addr)   (*((object volatile far *) (addr)))
    #define FARRAY(object, base) ((object volatile far *) (base))
    #define FCVAR(object, addr)   (*((object const far *) (addr)))
    #define FCARRAY(object, base) ((object const far *) (base))
    #else
    #define FVAR(object, addr)    (*((object volatile far *) ((addr)+0x10000L)))
    #define FCVAR(object, addr)   (*((object const far *) ((addr)+0x810000L)))
    #define FARRAY(object, base)  ((object volatile far *) ((base)+0x10000L))
    #define FCARRAY(object, base) ((object const far *) ((base)+0x810000L))
    #endif

    #if defined (__CX2__)
    #define HBYTE ((unsigned char volatile huge *)  0)
    #define HWORD ((unsigned int volatile huge *)  0)
    #define HVAR(object, addr)   (*((object volatile huge *) (addr)))
    #define HARRAY(object, base) ((object volatile huge *) (base))
    #endif

    #define CVAR(object, addr)   (*((object volatile code *) (addr)))
    #define CARRAY(object, base) ((object volatile code *) (base))
    #define DVAR(object, addr)   (*((object volatile data *) (addr)))
    #define DARRAY(object, base) ((object volatile data *) (base))
    #define XVAR(object, addr)   (*((object volatile xdata *) (addr)))
    #define XARRAY(object, base) ((object volatile xdata *) (base))

    #endif
    #ifndef _ONEWIRE_H
    #define _ONEWIRE_H

    #define OW_SKIP_ROM 0xcc
    #define DS18B20_CONVERT 0x44
    #define DS18B20_READ 0xbe

    //函数声明
    unsigned int rd_temperature(void);
    float rd_temperature_f(void);
    #endif
    #include "reg52.h"

    sbit DQ = P1^4;

    //单总线延时函数
    #ifndef STC12
    void Delay_OneWire(unsigned int t)  //STC89C52RC
    {
        while(t--);
    }
    #else
    void Delay_OneWire(unsigned int t)  //STC12C5260S2
    {
        unsigned char i;
        while(t--) {
            for(i=0; i<12; i++);
        }
    }
    #endif

    //通过单总线向DS18B20写一个字节
    void Write_DS18B20(unsigned char dat)
    {
        unsigned char i;
        for(i=0; i<8; i++)
        {
            DQ = 0;
            DQ = dat&0x01;
            Delay_OneWire(5);
            DQ = 1;
            dat >>= 1;
        }
        Delay_OneWire(5);
    }

    //从DS18B20读取一个字节
    unsigned char Read_DS18B20(void)
    {
        unsigned char i;
        unsigned char dat;

        for(i=0; i<8; i++)
        {
            DQ = 0;
            dat >>= 1;
            DQ = 1;
            if(DQ)
            {
                dat |= 0x80;
            }
            Delay_OneWire(5);
        }
        return dat;
    }

    //DS18B20初始化
    bit init_ds18b20(void)
    {
        bit initflag = 0;

        DQ = 1;
        Delay_OneWire(12);
        DQ = 0;
        Delay_OneWire(80); // 延时大于480us
        DQ = 1;
        Delay_OneWire(10);  // 14
        initflag = DQ;     // initflag等于1初始化失败
        Delay_OneWire(5);

        return initflag;
    }

    //DS18B20温度采集程序:整数
    unsigned char rd_temperature(void)
    {
        unsigned char low,high;
        char temp;

        init_ds18b20();
        Write_DS18B20(0xCC);
        Write_DS18B20(0x44); //启动温度转换
        Delay_OneWire(200);

        init_ds18b20();
        Write_DS18B20(0xCC);
        Write_DS18B20(0xBE); //读取寄存器

        low = Read_DS18B20(); //低字节
        high = Read_DS18B20(); //高字节

        temp = high<<4;
        temp |= (low>>4);

        return temp;
    }