STC51单片机学习9--DS18B20温度传感器

一、DS18B20

DS18B20是Dallas半导体公司的一款数字温度传感器芯片;

DS18B20是一款支持 1-wire总线接口的温度传感器;

DS18B20能测量的温度范围-55℃--125℃,精度是±0.5℃;

DS18B20可以将分辨率设定为9到12位;

DS18B20的工作电压范围3--5.5V

二、DS18B20与STC89C51的连接

STC51单片机学习9--DS18B20温度传感器_第1张图片

单片机的P4.1引脚用来接DS18B20的数据引脚

sbit DS = P4^1;

三、DS18B20的内部构成

以下是友台半导体的DS18B0结构图,内部有9个模块

STC51单片机学习9--DS18B20温度传感器_第2张图片

1、电源与寄生电源

2、ROM:存DS18B20 的系列号,也就是那个64位的编码,

3、存储器控制逻辑

4、Scratchpad(高速暂存器)

高速暂存器就是用来存各种数据的,一共可以存9个字节的数据,存的就是下面5、6、7、8、9这几个模块的数据。

STC51单片机学习9--DS18B20温度传感器_第3张图片

5、温度传感器

Byte0和Byte1存的是温度,就是传感器已经换算好的数字温度,Byte0是温度的低8位,Byte1是温度的高8位,上电默认的温度是0550 = 0000 0101 0101 0000 =1360, 因为默认的分辨率是12位(0.0625℃),所以开机默认的温度是1360*0.0625 ==85℃。

DS18B20采用16位补码的形式来存储温度数据,单位是摄氏度。两个字节一共是8*2=16位,温度的换算表格如下所示:

高字节的5个S是符号位,S=1表示温度为正,S=0表示温度为负;

12位分辨率,最后一位是1/16==0.0625,所以最小的温度分辨率是0.0625℃;

11位分辨率,最后一位是1/8==0.125,所以最小的温度分辨率是0.125℃;

10位分辨率,最后一位是1/4==0.25,所以最小分辨率是0.25℃;

9位分辨率,最后一位是1/2==0.5,所以最小分辨率是0.5℃;

正温度的读取

因为存的温度是补码,正数的原码和补码是一样的,直接读数

比如+85摄氏度:0000 0101 0101 0000 = 1360; 1360*0.0625 =85

比如+25.0625摄氏度:0000 0001 1001 0001 = 401;401*0.0625=25.0625

负温度的读取

因为存的温度是补码,负数的补码转化为原码步骤:先取反,再+1

比如-55摄氏度的补码是:1111 1100 1001 0000(高5位是符号位);

所以真实的补码为100 1001 0000;

补码取反之后,再+1;011 0110 1111+1=011 0111 0000 = 880;

880*0.0625 == 55

几个温度所对应的补码

STC51单片机学习9--DS18B20温度传感器_第4张图片

6、报警触发寄存器

Byte2对应的是TH,也就是高温报警值,用户自己设置

Byte3对应的是TL,也就是低温报警值,用户自己设置

7、配置寄存器

Byte4对应的计时配置寄存器的值;

配置寄存器是用来配置温度的分辨率,可以把温度的分辨率配置为9bit、10bit、11bit、12bit,分别对应的实际温度分辨率为0.5℃、0.25℃、0.125℃、0.0625摄氏度。默认是12位分辨率(0.0625摄氏度)

配置寄存器的内容是这样的

温度的精度和配置

STC51单片机学习9--DS18B20温度传感器_第5张图片

8、用户Byte

有两个Byte,也是留给用户自己用的,不同厂家的设计可能不一样

9、CRC

CRC发生器产生校验码,存在Byte8,是64位ROM中的前56位编码的校验码,由CRC

四、DS18B20的处理序列,也就是工作步骤

1、初始化DS18B20

初始化就是先把总线拉高;

然后检查总线上是否存在DS18B20 ,如果有的话,总线会返回一个低电平脉冲,如果没有DS18B20,那总线一直就是高电平,似乎有点像IIC通讯的应答信号。

2、执行ROM指令:

这个ROM指令就是查询DS18B20 的64位序列号,相当于设备地址,在多个DS18B20总线连接,需要区分每个DS18B20设备。如果是单个的18B20就不需要查询这个序列号了。你不查询也要发一条指令0xCC,表示跳过ROM指令。

ROM指令有哪些

STC51单片机学习9--DS18B20温度传感器_第6张图片

3、执行DS18B20功能指令

STC51单片机学习9--DS18B20温度传感器_第7张图片

4、DS18B20 初始化的C语言实现

void DS18b20_Init(void)
{
    bit flag=1;

    while (flag)
    {
        while (flag)
         {
             DQ = 1;
            delay(1);
             DQ = 0; //MCU拉低总线480us以上
             delay(50); // 大约550us
             DQ = 1;    // MCU释放总线,等待DS18B20的应答
             delay(6);  // 等待66us左右才开始读DS18B20的应答
             flag = DQ; // MCU读总线,只有读到低电平,才表示成功,跳出循环
           }
        delay(45);    //延时500us
        flag = ~DQ;//初始化成功了还是要释放总线,把总线拉高
    }
    DQ=1;
}

5、DS18B20数据读取

DS18B0的数据线只有1根,在这一根线上完成读和写,那就需要的时序更加严格,资源少,命就得硬。

DS18B20的读写时序

MCU 往DS18B20写一个BIT的“0”:

MCU把总线拉低,拉低时间要持续到60--120us之间,然后释放总线(释放总线,上拉电阻就把总线拉高了)。

MCU往DS18B20写一个BIT的“1”:

MCU把总线拉低,,拉低时间要大于1us,然后在15us内拉高总线。

MCU从DS18B20中读一个BIT的:

MCU先把总线拉低,DS18B20检测到总线被拉低1us后,边开始往外送数据,如果送出的是“0”,DS18B20就把总线拉低,一直到读周期结束;如果送出的是“1”,就释放总线,让上拉电阻 把总线拉高。

读一个BIT的周期至少是60us,

STC51单片机学习9--DS18B20温度传感器_第8张图片

往DS18B20中写一个字节的数据

/**
 * 往DS18B20总写一个字节的数据
 * 因为DS18B20只能一个BIT一个BIT的写,所以要写一个字节就需要循环8次
*/
void write_byte(unsigned char Dat)
{
    unsigned char i;

    for (i=0; i<8; i++)
    {
        DQ = 1;//MCU把总线拉高
        _nop_(); //延时1us,STC89C52单片机,晶振12MHz,一个nop就是1us
        DQ = 0; //MCU把总线拉低
        nops(); //拉低持续4us
        DQ = Dat & 0x01;  //最低位移出
        delay(6);        //不管是0还是1,都持续66us左右
        Dat >>= 1;       //右移一位
    }
    DQ = 1;
    delay(1);  
}

从DS18B20 中读一个字节

/**
 * 从DS18B20中读一个字节的数据
 * 因为DS18B20只能一个BIT一个BIT的读,所以要读一个字节就需要循环8次
*/
unsigned char read_byte(void)
{
    unsigned char i, Dat=0;

    for (i=0; i<8; i++)
    {
        DQ=1; //MCU把总线拉高,还没开始读
        _nop_(); //
        Dat >>= 1;//每次循环数据右移1位
        DQ = 0; //MCU把总线拉低,
        nops();   //拉低尺寸4us左右
        DQ = 1; //MCU再把总线拉高,也相当于释放总线,总线的电平高低由DS18B20来控制了
        nops();   //再等待4us左右就开始读DS18B20吐出的数据
        if (DQ)
            Dat|=0x80; //一个BIT一个BIT的读
        delay(6);      //延时66us就差不多了
    }
    DQ=1; //读完成之后把总线拉高,因为空闲的时候总线hi高电平

    return(Dat);//返回一个字节的数据
}

读温度

/**
 * 读出温度
*/
void read_temp(void)
{
    DS18b20_Init();  // 器件初始化
    write_byte(0xCC); // 发Skip ROM命令
    write_byte(0x44); // 启动温度转换
    

    DS18b20_reset();//器件再初始化
    write_byte(0xCC); // 发Skip ROM命令
    write_byte(0xBE); // 发读命令

    temp_data[0]=read_byte();  //读温度低8位
    temp_data[1]=read_byte();  //读温度高8位
}

你可能感兴趣的:(51单片机,单片机,嵌入式硬件,mcu)