DS18B20数字温度传感器

目录

一、基础知识

1、基础介绍:

2、DS18B20特点:

3、单总线时序

4、相关操作时序

5、部分ROM指令

二、相关代码 

 1、 使用步骤(单点总线情况)

2、 代码展示


数字温度传感器你会用了吗?会自己敲代码了吗?

一、基础知识

1、基础介绍:

 首先当然要知道它的用处啦!它是我们社会生活中不可缺少的"测温计”,温控大棚,高铁上的温度显示等等都离不开它的身影!

   DS18B20数字温度传感器是DALLAS公司生产的单总线器件,用它组成的一个测温系统具有线路简单、体积小的特点,在一根通信线上可以挂多个数字温度传感器,十分方便。超小的体积,超低的硬件开销,抗干扰能力强,精度高,附加能力强,使其更加受欢迎。

2、DS18B20特点:

  • 通信采用1-Wire接口(单线传输,只有一根数据线)
  • 每个DS18B20都有唯一的64位序列码储存在板载ROM中(防止一条线上多个设备无法知晓是哪个设备)
  • 无需外部元件
  • 可从数据线供电,电源范围为3.0~5.5V
  • 可测量的温度范围为-55~+125
  • 在-10~+85范围内精确度为0.5       

3、单总线时序

       其采用1-Wire Bus所有数据都在一条线上传输,因此单总线协议对时序要求非常严格以确保数据的完整性。

        单总线信号类型:复位脉冲、存在脉冲、写0、写1、读0、读1。所有这些信号除存在脉冲DS18B20发出和读数据的以外信号都由总线控制器发出。

数据传输从最低位开始(与IIC通信从最高位传输不同) 

4、相关操作时序

            初始化时序:包含复位DS18B20和接收DS18B20返回的存在信号。主机与DS18B20做任何通讯前都要对其初始化。

            写时序:分为写1与写0,通过控制单总线高低电平持续时间从而把逻辑1或逻辑0写DS18B20中。

            读时序:分为读0时序和读1时序。 总线控制器通过读取DS18B20控制的总线高低电平接收DS18B20数据。

5、部分ROM指令

       忽略ROM指令(CCh)    该指令允许总线控制器不提供64位ROM编码就使用功能指令。单点总线情况下使用此命令可以使器件无需发回64位ROM编码(即只用发送这一条,其它4条ROM指令不用去发送),从而大大降低时间成本,但是队友多器件忽略ROM指令会使得多机同时发送信号,总线发生数据冲突。

        温度转换指令(44h)      这条命令用以启动一次温度转换。温度转换指令被执行,产生的温度转换结果数据以2个字节的形式被存储在高速寄存器中,而后DS18B20保持等待状态。

        读寄存器指令(BEh)     该命令读取暂存器的内容,读取从字节0开始,一直进行下去,直到读完寄存器所有字节,如果不想读完所有字节,控制器可以发出复位指令停止读取。

       写暂存器指令(4Eh)      该命令向DS18B20暂存器写入数据,开始位置在TH寄存器(暂存器第二个字节),接下来写入TL寄存器(暂存器第3个字节),最后写入配置寄存器(暂存区的第4个字节)

            拷贝暂存器指令(48h)     这条命令将TH、TL和配置寄存器(第2、3、4字节)的内容拷贝到EEPROM中(使用户设置的值断电不会丢失) 

二、相关代码 

 1、 使用步骤(单点总线情况)

         初始化->ROM操作指令->DS18B20功能指令  温度转换指令   读取暂存器指令

2、 代码展示

#include <reg52.h>
#include <intrins.h>

#define  uchar unsigned char
#define  uint unsigned int

sbit DS = P3^7;  //DS18B20单总线
sbit LA=P2^2;
sbit LB=P2^3;
sbit LC=P2^4;   //数码管段选

void delay2(unsigned int z)     //延时函数2,delay(1000)=1s
{
	unsigned int x,y;
	for(x=z;x>0;x--)
	   for(y=120;y>0;y--);
}

unsigned char smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void timefrist()
{
	EA = 1;          //打开总开关
	ET0 = 1;         //中断函数0的开关
	TR0 = 1;         //打开定时器0开关
	TMOD = 0x01;      //模式一,定时模式
	TH0 = 0xED;       //这里改值了,到上限就5ms(改初值)
	TL0 = 0xFF;
//开关、模式、赋初值
}
unsigned char miao=0;
void DigDisplay(unsigned char h)
{
	unsigned char a=h%10;
	unsigned char b=h/10%10;
	unsigned char c=h/100;
	static unsigned char wei=0;
	switch(wei)
	{
		case 0: LA=1;LB=1;LC=1;P0 = smgduan[c];break;
		case 1:	LA=0;LB=1;LC=1;P0 = smgduan[b];break;
		case 2: LA=1;LB=0;LC=1;P0 = smgduan[a];break;
	}
	wei++;
	if(wei==3)
	{
		wei = 0;
	}
}

void Delay_us(char us)  //执行一次us--所需6.5us 进入一次函数11.95us
{
    while(us--);
}

bit ds_init()
{
     bit i;
     DS=1;
     _nop_();
     DS=0;
     Delay_us(75);  //拉低总线499.45us  挂在总线上的DS18B20将会全部被复位
     DS=1;  //释放总线
     Delay_us(4);  //37.95us  读取18B20存在信号
     i = DS;   //将返回的值存放在i中
     Delay_us(20);  //141.95us
     DS=1;  //释放总线
     _nop_();  //小延时使其稳定
     return i;
}

//写一个字节
void write_byte(uchar dat)
{
    uchar i;
    for(i=0;i<8;i++)
    {
         DS = 0;
         _nop_();  //产生写时序
         DS = dat & 0x01;
         Delay_us(10);  //76.95us
         DS = 1;  //释放总线准备下一次数据写入
         _nop_();
         dat >>= 1;
    }
}

uchar read_byte()
{
    uchar i,j,dat;
    for(i=0;i<8;i++)
    {
        DS = 0;
        _nop_(); //产生读时序
        DS = 1;
        _nop_();  //释放总线
        j = DS;
        Delay_us(10); //76.95us
        DS = 1;
        _nop_();
        dat = (j<<7) | (dat>>1);
    }
    return dat;
}

void main()
{
    uint i; //用于存放两个字节
    uchar L,M;//用于存储温度的低字节和高字节
    timefrist();     //定时器0初始
    while(1)
    {
         ds_init();  //初始化DS18B20
         write_byte(0xcc);  //发送跳跃ROM指令(忽略ROM指令)
         write_byte(0x44);  //发送温度转换指令  (温度将被存在高速寄存器中,再将其读出来)
         ds_init();  //初始化DS18B20
         write_byte(0xcc);  //发送跳跃ROM指令(忽略ROM指令)
         write_byte(0xbe);  //读取DS18B20暂存器值
         L = read_byte();  //读取高速暂存器第一个字节(即温度的低位)
         M = read_byte();  //读取高速暂存器第二个字节(即温度的高位)
         i = M;
         i<<=8; 
         i |= L; //将L,M都写入一个数i中
         i = i * 0.0625 * 10 + 0.5;  //将i换算为实际温度(同时将小数点右移一位 实际意义为保留小数点一位且四舍五入)
         delay2(2000);  //延时一秒,速度太快
         miao = i;  //将i的数值赋值给miao并将其显示出来
    }
}

//定时器中断函数
void timer0() interrupt 1
{
	 TH0 = 0xED;         //重新定义5ms初始值
	 TL0 = 0xFF;
	 DigDisplay(miao);   //显示,不断5ms显示就是动态显示
}

负数要设置判断语句,且其以补码形式存放,我们需要取反加一

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值