首页 > 其他分享 >嵌入式开发入门-51单片机基础知识(9)- DS18B20

嵌入式开发入门-51单片机基础知识(9)- DS18B20

时间:2023-05-06 14:23:26浏览次数:29  
标签:Ds18b20 51 DS18B20 总线 单片机 主机 时隙 写入

一、DS18B20简介

  1、DS18B20是一个数字温度传感器,单总线传输数据,测量温度范围为-45℃-125℃,测量精度可配置为9位,10位,11位,12位,默认配置12位,分别对应0.5℃、0.25℃、0.125℃和0.0625℃。

二、温度测量

  1、由于DS18B20通电后,处于空闲状态,不进行温度测量和转换,所以必须发出转换命令,DS18B20才开始工作。

  2、DS18B20工作后,测量的数据存放自ScrachPad寄存器中,并返回空闲状态。在温度转换过程中,DS18B20发送0响应,转换完成后,发送1响应。

  3、根据18B20 芯片手册中的电路图中看出,在不工作时,DQ拉高。

三、DS18B20操作步骤

第一步:初始化

  1、主机发送复位脉冲;

  2、主机接收DS18B20的存在脉冲;

第二步:ROM指令

  1、SEARCH ROM(F0h)

    搜索:系统刚通电时,如果存在多个从机,则需要使用Search ROM来识别总线中存在的各从机。

  2、READ ROM(33h)

    直接读取:该指令,只有在总线中只存在一个从机时使用。如果有多个存在,则会产生冲突。

  3、MATCH ROM(55h)

    匹配:该指令用于寻找总线中特定的从机。

  4、SKIP ROM(CCh)

    跳过:使用该指令不需要在使用其他ROM指令,可以直接操作总线上所有从机。如配合CONVERT指令,可以直接使能总线上所有从机开始工作转换。

  5、ALARM ROM(ECh)

    报警:该命令用于搜索总线中设置过报警参数的从机,在最近的转换过程中,是否有报警的设备。

第三步:功能指令

  1、CONVERT T(44h)

  转换温度:该指令用于启动单个温度转换,在外部供电时,18B20接收到该指令后,启动转换,转换进行时发送0,转换完成后发送1(DQ拉高,处于空闲状态)。

   2、WRITE SCRATCHPAD(4Eh)

  写指令:该命令用于主机将三字节的数据写入scratchpad寄存器中,第一个数据写入TH寄存器,第二个字节写入TL寄存器,第三个字节写入配置寄存器。

  数据首先传输最低位。三个字节必须在主机发送复位请求前写入,否则数据会丢失。

  3、READ SCRATCHPAD(BEh)

  读指令:该命令用于主机读取scratchpad寄存器的内容。数据首先最低位开始,直到读取第九个字节。如果主机只需要一部分数据,则主机可以在读到自己需要的数据后,就发出复位指令终止读取。

  4、COPY SCARTCHPAD(48h)

  复制指令:该指令用于将scratchpad中TH、TL和配置寄存器的内容复制到主机EEPROM中。如果在寄生电源模式下使用,在发出该指令后的10us内,主机必须强上拉10ms。

  5、RECALL E²

  调用指令:该指令用于从EEPROM中调用报警触发值(TH和TL)和配置数据,并将数据分别放在scratchpad的字节2、3和4中。主机在调用命令之后,发出读取时隙,DS18B20将通过发送0或1来指示调用状态。

  此命令允许主机将3字节的数据写入DS18B20的草稿行。第一个数据字节写入TH寄存器(暂存区的字节2),第二个字节写入TL寄存器(字节3),第三个字节写入配置寄存器(字节4)。数据必须首先传输最低有效位。所有三个字节必须在主机发出重置之前写入,否则数据可能已损坏。

四、初始化

  1、大部分涉及到通信的地方,初始化一般就是握手过程,双方达成共识,我要开始发送数据了,对方准备好数据了等。

  2、初始化步骤:

    (1)主机拉低总线至少480us完成复位脉冲。(类似于先给对方搭个招呼,然后释放总线,看对方如何回复)

    (2)主机释放总线。

    (3)DS18B20检测上升沿(在15us和60us内)(DS18B20等待主机给他打招呼),

    (4)检测到上升沿后,DS18B20将总线拉低60us-240us(DS18B20收到主机的招呼后,给主机回复招呼)

 1 bit Ds18b20_Init(void)
 2 {
 3     bit flag;
 4     DQ = 0;
 5     Delay500us();
 6     DQ = 1;
 7     Delay68us();
 8     flag = DQ;
 9     Delay500us();
10     return flag;
11 }
1 void Ds18b20_Check(void)
2 {
3     Lcd12864_Init();
4     while(Ds18b20_Init())Lcd12864_Show_String(2,2,"NO SENSOR!");    //初始化
5     Lcd12864_Show_String(2,2,"Initial OK");//检测到DS18B20,打印ok,否则打印no sensor
6     Delay500ms();
7 }

五、读写时隙

  5.1写时隙

  写入1时隙和写入0时隙。所有写入时隙持续时间至少为60us,单个写入时隙之间的恢复时间至少为1us,写入时隙都由主机将总线拉低开始。

要生成写入1的时隙,在总线拉低后,主机必须在15us内释放总线。

要生成写入0时隙,在总线拉低后,必须持续最少60us保持总线为低电平,然后在释放总线。

因为DS18B20在主机启动写入时隙后,在15us和60US之间采集主机数据,在这个期间为高,则向DS18B20写入1,如果为低,则写0。

   

 1 void Ds18b20_Write_Low(void)
 2 {
 3     DQ = 0;
 4     Delay68us();
 5     DQ = 1;
 6     _nop_();
 7     _nop_();
 8 }
 9 
10 
11 /******************************************************************************/
12 // 函数名称:Ds18b20_Write_High 
13 // 输入参数:无
14 // 输出参数:无
15 // 函数功能:DS18B20写1
16 /******************************************************************************/
17 void Ds18b20_Write_High(void)
18 {
19     DQ = 0;
20     _nop_();
21     _nop_();
22     DQ = 1;
23     Delay68us();
24 }
25 
26 
27 /******************************************************************************/
28 // 函数名称:Ds18b20_Write_Cmd 
29 // 输入参数:myCmd-命令
30 // 输出参数:无
31 // 函数功能:DS18B20写命令
32 /******************************************************************************/
33 void Ds18b20_Write_Cmd(uint8 cmd)
34 {
35     uint8 i;
36     for(i=0;i<8;i++)
37        {
38         if(cmd&0x01)Ds18b20_Write_High();
39         else Ds18b20_Write_Low();
40         cmd >>= 1;    
41     }    
42 }    

  5.2读时隙

  DS18B20只能在主机发出读取时隙时向主机发送数据。因此主机必须在发出readScratchpad[BEh]或readPower[B4h]命令后,立即生成读取时隙,以便DS18B20提供所请求的数据。

  读取时隙的持续时间至少为60us,时隙之间的恢复时间至少为1us,然后释放总线,从而启动读取时隙。

  在主机启动读取时隙后,DS18B20将在总线上传输1或0。

  DS18B20通过使总线保持高电平来发送1,将总线拉低来发送0。

  当发送0时,DS18B20将在时隙结束时释放总线,DS18B20发送的数据在启动读取时隙的下降沿之后15us内有效,因此,主机必须释放总线。然后从开始的15us内对总线状态进行采样。

uint8 Ds18b20_Read_Data(void)
{
    uint8 tmpRead=0x00;
    uint8 i;
    for(i=0;i<8;i++)
      {
        tmpRead>>=1;
        DQ = 0;
        _nop_();
        _nop_();
        DQ = 1;
        _nop_();
        _nop_();
        if(DQ)tmpRead|=0x80;//读1
        //else tmpRead|=0x00;//读0
        Delay68us();    
    }
    return tmpRead;
}

  5.3忙信号检测

void Ds18b20_Busy_Check(void)
{
    bit flag; //0-busy 1-done
    do{
        DQ = 0;
        _nop_();
        _nop_();
        DQ = 1;
        _nop_();
        _nop_();
        flag = DQ;
        Delay68us();        
    }while(!flag);
}

  5.4获取温度值

void Ds18b20_Get_Temp(uint8 *tempValue){
    uint8 valueLow,valueHigh;
    uint16 resultLow;    //范围超过了255

    Ds18b20_Init();
    Ds18b20_Write_Cmd(0xcc);//skip rom
    Ds18b20_Write_Cmd(0x44);//convert T
    //Delay750ms();//busycheck
    Ds18b20_Busy_Check();
    Ds18b20_Init();
    Ds18b20_Write_Cmd(0xcc);//skip rom
    Ds18b20_Write_Cmd(0xbe);//read scratchpad
    valueLow  = Ds18b20_Read_Data();//read byte0
    valueHigh = Ds18b20_Read_Data();//read byte1        
    resultLow = (valueLow & 0x0f) * 625;        
    valueLow >>= 4;
    *(tempValue+0) = (valueHigh *16 + valueLow)/100 + 0x30;   //温度值的百位
    *(tempValue+1) = (valueHigh *16 + valueLow)%100/10 + 0x30;//温度值的十位
    *(tempValue+2) = (valueHigh *16 + valueLow)%100%10 + 0x30;//温度值的个位
    *(tempValue+4) = resultLow/1000 + 0x30;                   //小数点后第一位
    *(tempValue+5) = resultLow%1000/100 + 0x30;               //小数点后第二位
    *(tempValue+6) = resultLow%1000%100/10 + 0x30;            //小数点后第三位
    *(tempValue+7) = resultLow%1000%100%10 + 0x30;            //小数点后第四位
}

  5.5主函数

int main(void){    
    Ds18b20_Check();                                     //检测总线是否存在DS18B20
    Lcd12864_Screen_Init();                              //LCD12864界面初始化设置    
    while(1){
        Ds18b20_Get_Temp(sampleResult);                  //读取温度
        if (sampleResult[0] == '0')sampleResult[0] = ' ';//首位如果为0,则不显示
        Lcd12864_Show_String(2, 2, sampleResult);        //显示温度
    }
}

 

标签:Ds18b20,51,DS18B20,总线,单片机,主机,时隙,写入
From: https://www.cnblogs.com/wanggengwu/p/17376670.html

相关文章

  • STM32单片机引脚要职能配置为输入或者输出模式,并不能像51一样准双向,那么如何进行但总
    如题随便找个端口举例对应的程序为 难道需要写之后立即初始化为输入?然后赶紧读?然后再赶紧初始化为输出?再往外写?是的,还真他妈就是这么傻逼的操作 ......
  • PM510V16 3BSE008358R1电磁感应效应、静电效应、热效应、化学效应等,更有可能损坏应用
    PM510V163BSE008358R1电磁感应效应、静电效应、热效应、化学效应等,更有可能损坏应用程序或系统 电测仪器分类:什么是电气测量设备?电气测量中使用的设备1个电阻或电流、电压、频率、磁通、功率因数等的测量仪器称为“电工测量仪器”。俗称欧姆表、电流表、电压表、频率表、磁......
  • 基于stm32实现DS18B20温度检测仿真
    一、cubmax设置PA0作为DS18B20数据口 打开串口1,显示温度信息时钟树设置72MHZ。二、程序头文件/*USERCODEBEGINIncludes*/#include"DS18B20.h"#include"stdio.h"/*USERCODEENDIncludes*/串口重定向/*USERCODEBEGIN0*/intfputc(intch,FILE*f......
  • 关于单片机控制电压检测的学习
    1.使用单片机内自带的ADC模块进行检测问题在于频率是否合适:在实验2的基础上得到结论,当两线圈距离在2cm左右时,工作频率将会超过1MHz。采样的最好结果是采集尽可能多的点,这样才能绘制出真正反映实际情况的曲线。目前想要完成的是实验3的demo,采用电阻分压和二极管整流,直接利用......
  • ASEMI代理ADM3251EARWZ-REEL原装ADI车规级ADM3251EARWZ-REEL
    编辑:llASEMI代理ADM3251EARWZ-REEL原装ADI车规级ADM3251EARWZ-REEL型号:ADM3251EARWZ-REEL品牌:ADI/亚德诺封装:SOIC-20-300mil批号:2023+引脚数量:20工作温度:-40°C~85°C安装类型:表面贴装型ADM3251EARWZ-REEL汽车芯片ADM3251EARWZ-REEL特性2.5kV完全隔离(电源和数据......
  • C++黑马程序员——P251-254. 常用排序算法 sort,random_shuffle,merge,reverse
    P251.常用排序算法——sortP252....——random_shuffleP253....——mergeP254....——reverseP251.sort  1#include<iostream>2#include<vector>3#include<algorithm>4#include<functional>//用greater5usingnamespacest......
  • 51nod 1242 斐波那契数列的第N项(矩阵快速幂)
    1242 斐波那契数列的第N项基准时间限制:1 秒空间限制:131072 KB分值: 0 难度:基础题 收藏 关注斐波那契数列的定义如下:F(0)=0F(1)=1F(n)=F(n-1)+F(n-2)(n>=2)(1,1,2......
  • NC15172 情人节的电灯泡
    题目链接题目题目描述情人节到了,小芳和小明手牵手,打算过一个完美的情人节,但是小刚偏偏也来了,当了一个明晃晃的电灯泡,小明很尴尬,就和小刚说,我交给你个任务,你完成了我俩就带你玩,否则你就回家吧。小刚很有当单身狗的觉悟,他坚决不想让小明过好情人节,同为单身狗的你能帮帮他吗?现在有......
  • 51nod_1355
    题目链接题意给出\(n\)个正整数\(a_1,a_2\cdots,a_n\),求\(\operatorname{lcm}(F_{a_1},F_{a_2},\cdots,F_{a_n})\)。其中\(\{F_i\}\)为斐波那契数列。\(2\len\le50000,1\lea_i\le1000000\)3s解答斐波那契数列的最小公倍数很难直接求,但是其最大公约数却有优美......
  • NC51101 Lost Cows
    题目链接题目题目描述\(N(2\leqN\leq8,000)\)cowshaveuniquebrandsintherange1..N.Inaspectaculardisplayofpoorjudgment,theyvisitedtheneighborhood'wateringhole'anddrankafewtoomanybeersbeforedinner.Whenitwastimetoli......