温度传感器 DS18B20

1. 实物图

实物图

2. 64位(激)光刻只读存储器
开始8位(28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码

光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的

ROM
3. 温度寄存器
高字节的前5位是符号位,如果测得的温度大于0,这5位为‘0’,只要将测到的数值乘以0.0625即可得到实际温度;如果温度小于0,这5位为‘1’,测到的数值需要先减1再取反再乘以0.0625即可得到实际温度

温度寄存器

4. 温度与数据关系
温度与数据关系

12-bit精度,0x550 * 0.0625 = 85

5. 精度寄存器
寄存器

精度

6. ROM指令表
ROM指令表

7. RAM指令表
RAM指令表

8. 时序图
初始化:
初始化

1.数据线拉到低电平“0”
2.延时480微秒(该时间的时间范围可以从480到960微秒)
3.数据线拉到高电平“1”
4.延时等待80微秒。如果初始化成功则在15到60微秒时间内产生一个由DS18B20所返回的低电平“0”。根据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环
5.若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第3步的时间算起)最少要480微秒

读:
读

1.将数据线拉低“0”
2.延时1微秒
3.将数据线拉高“1”,释放总线准备读数据
4.延时15微秒
5.读数据线的状态得到1个状态位,并进行数据处理
6.延时45微秒
7.重复1~6步骤,直到读完一个字节

写:
写

1.数据线先置低电平“0”
2.延时1微秒
3.按从低位到高位的顺序发送数据(一次只发送一位)
4.延时60微秒
5.将数据线拉到高电平
6.延时1微秒
7.重复1~6步骤,直到发送完整的字节

9. 举例

sbit DSPORT = P3 ^ 7;

u8 ds18b20Init()
{
    u8 i = 0;
    DSPORT = 0;
    i = 70;
    while(i--); //642us
    DSPORT = 1;
    i = 0;  

    while(DSPORT)
    {
         delay1ms(1);
         i++;
         if(i > 5)
         {
            return 0;
         }
    }

    return 1;
}

void ds18b20Write(u8 d)
{
    u8 i = 0, j = 0;

    for(j = 0; j < 8; j++)
    {
        DSPORT = 0;
        i++; //延时
        DSPORT = d & 0x01;
        i = 6;
        while(i--); //延时68us
        DSPORT = 1;
        d >>= 1;    
    }       

    return;
}       

u8 ds18b20Read()
{
    u8 i = 0, j = 0;
    u8 d = 0, t = 0;

    for(j = 8; j > 0; j--)
    {
         DSPORT = 0;
         i++; //延时
         DSPORT = 1;
         i++;
         i++;
         t = DSPORT;
         d = (d >> 1) | (t << 7);
         i = 4;
         while(i--);
    }

    return d;   
}        

void ds18b20ChangeTemp()
{
    ds18b20Init();
    delay1ms(1);
    ds18b20Write(0xcc); //忽略ROM 
    ds18b20Write(0x44); //温度转换

    return;
}

void ds18b20ReadTemp()
{
    ds18b20Init();
    delay1ms(1);
    ds18b20Write(0xcc); 
    ds18b20Write(0xbe); //读取RAM

    return;
}

int readTemp()
{
    int temp = 0;
    u8 tmph = 0, tmpl = 0;

    ds18b20ChangeTemp();
    ds18b20ReadTemp();

    tmpl = ds18b20Read(); //低字节   
    tmph = ds18b20Read(); //高字节       

    temp = tmph;
    temp <<= 8;
    temp |= tmpl; 

    return temp;           
}
posted @ 2017-07-11 20:56  thomas_blog  阅读(183)  评论(0编辑  收藏  举报