传感器学习——DS18B20

DS18B20

DS18B20是Dallas公司生产的数字温度传感器,具有体积小、适用电压宽、经济灵活的特点。它内部使用了onboard专利技术,全部传感元件及转换电路集成在一个形如三极管的集成电路内。DS18B20有电源线、地线及数据线3根引脚线,工作电压范围为3~5.5 V,支持单总线接口。

DS18B20的结构和工作原理

DS18B20 的测量范围为 -55 ℃ ~+ 125 ℃ ; 在 -10~+ 85°C范围内,精度为 ± 0.5°C
DS18B20的外部结构如图1所示。其中,VDD为电源输入端,DQ为数字信号输入/输出端,GND为电源地
在这里插入图片描述
第0和第1字节为16位转换后的温度二进制值,其中前4位为符号位,其余12位为转换后的数据位(分辨率为12位)。如果温度大于0,则前4位值为0,只要将测到的数值乘上0.062 5即可得到实际温度值;如果温度小于0,则前4位为1,需将测得的数值取反加1后,再乘上0.062 5。第0和第1字节各位的二进制值如下:
在这里插入图片描述
在这里插入图片描述
根据DS18B20的通信协议,MCU对其操作主要有如下3个步骤:读写之前,对DS18B20发送约500 μs的低电平进行复位;复位成功,发送ROM指令;发送RAM指令。MCU对DS18B20的具体操作流程如图4所示。
在这里插入图片描述

程序源码

ds18b20.c

#include "ds18b20.h"
#include "delay.h" 
void DS18B20_Rst(void)    
{                 
 DS18B20_IO_OUT(); //SET PG11 OUTPUT
  DS18B20_DQ_OUT=0; //拉低DQ
  delay_us(750);    //拉低750us
   DS18B20_DQ_OUT=1; //DQ=1 
 delay_us(15);     //15US
}

//等待ds18b20回应
//返回1未检测到ds18b20的存在
//返回0存在
u8 DS18B20_Check(void)     
{   
 u8 retry=0;
 DS18B20_IO_IN();//SET PG11 INPUT  
    while (DS18B20_DQ_IN&&retry<200)
    
 {
  retry++;
  delay_us(1);
   };  
 if(retry>=200)return 1;
 else retry=0;
    while (!DS18B20_DQ_IN&&retry<240)
     {
  retry++;
  delay_us(1);
   };
 if(retry>=240)return 1;     
 return 0;
}
//从ds18b20读取一个位
//返回值1/0

u8 DS18B20_Read_Bit(void)     // read one bit
{
  u8 data;
 DS18B20_IO_OUT();//SET PG11 OUTPUT
  DS18B20_DQ_OUT=0; 
 delay_us(2);
   DS18B20_DQ_OUT=1; 
 DS18B20_IO_IN();//SET PG11 INPUT
 delay_us(12);
 if(DS18B20_DQ_IN)data=1;
  else data=0;  
  delay_us(50);           
  return data;
}
//从ds18b20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)    // read one byte
{        
    u8 i,j,dat;
    dat=0;
 for (i=1;i<=8;i++) 
 

  {
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }          
    return dat;
}
//写一个字节到ds18b20
//dat:要写入的字节

void DS18B20_Write_Byte(u8 dat)     
 {             
    u8 j;
    u8 testb;
   DS18B20_IO_OUT();//SET PG11 OUTPUT;
    for (j=1;j<=8;j++) 
     {
        testb=dat&0x01;
        dat=dat>>1;
        if (testb) 
        {
            DS18B20_DQ_OUT=0;// Write 1
            delay_us(2);                            
            DS18B20_DQ_OUT=1;
            delay_us(60);             
                    }
        else 
        {
            DS18B20_DQ_OUT=0;// Write 0
            delay_us(60);             
            DS18B20_DQ_OUT=1;
            delay_us(2);                          
        }
            }
}
//开始温度转换
void DS18B20_Start(void)// ds1820 start convert
{                        
    DS18B20_Rst();    
   DS18B20_Check();  
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0x44);// convert
} 
//初始化ds18b20的io口 DQ同时检测DS的存在
//返回1:不存在
//返回0:存在

u8 DS18B20_Init(void)
{
 GPIO_InitTypeDef  GPIO_InitStructure;
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
  //GPIOG9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉­
  GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化
 
  DS18B20_Rst();
 return DS18B20_Check();
}  
//从ds18b20得到温度值
//精度:0.1c
//返回值:温度值(-550~1250)
short DS18B20_Get_Temp(void)
{
    u8 temp;
    u8 TL,TH;
   short tem;
    DS18B20_Start ();                    // ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check();  
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0xbe);// convert     
    TL=DS18B20_Read_Byte(); // LSB   
    TH=DS18B20_Read_Byte(); // MSB   
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
        temp=0;//温度为负
    }else temp=1;//温度为正
    tem=TH; //获得高八位
    tem<<=8;        
    tem+=TL;//获得低八位
    tem=(double)tem*0.625;//转换    
 if(temp)return tem; //放回温度值
 else return -tem;    
}



        

ds18b20.h

#ifndef __DELAY_H
#define __DELAY_H       
#include <sys.h>   
void delay_init(u8 SYSCLK);
void delay_ms(u16 nms);
void delay_us(u32 nus);


#endif
发布了6 篇原创文章 · 获赞 11 · 访问量 139

猜你喜欢

转载自blog.csdn.net/weixin_46156693/article/details/104459040