实验20:DS18B20温度传感器实验

一、介绍

    独特的单总线接口方式,DS18B20在与微处理器连接时仅需要一条线即可实现微处理器与DS18B20的双向通讯,大大提高了系统的抗干扰性。

    测温范围:-55°C ~ +125°C,精度为+-0.5°C。

    支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定。

    工作电源:3.0V ~ 5.5V。

    在使用中不需要任何外围元件。

    测量结果以9~12位数字量方式串行传送。

    单总线是一种半双工通信方式。

    DS18B20共有6种信号类型:复位脉冲、应答脉冲、写0、写1、读0和读1。所有这些信号,除了应答脉冲以外,都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。

二、封装

三、连接方式

四、原理图

五、时序

    (1)复位脉冲

          单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480 us,,以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~60 us,并进入接收模式(Rx)。接着DS18B20拉低总线60~240 us,以产生低电平应答脉冲。

    (2)写时序

          写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。

          写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。

          写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。

    (3)读时序

          单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。

          所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。

          典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。

    (4)DS18B20的典型温度读取过程

          复位--->发SKIP ROM命令(0XCC)--->发开始转换命令(0X44)--->延时--->复位--->发送SKIP ROM命令(0XCC)--->发读存储器命令(0XBE)--->连续读出两个字节数据(即温度)--->结束。

六、程序

ds18b20.h文件

#ifndef __DS18B20_H__
#define __DS18B20_H__

#include"stm32f4xx_conf.h"

#define DS18B20_DQ_OUT_LOW()  GPIO_ResetBits(GPIOB,GPIO_Pin_15)
#define DS18B20_DQ_OUT_HIGH() GPIO_SetBits(GPIOB,GPIO_Pin_15)

#define DS18B20_DQ_IN()  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)
#define DS18B20_DQ_IN()  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)

void DS18B20_RST(void);
uint8_t DS18B20_ACK(void);
void DS18B20_Write_Byte(uint8_t data);
uint8_t DS18B20_Read_Byte(void);
short DS18B20_Get_Temp(void);

#endif
 

ds18b20.c文件

#include "./DS18B20/ds18b20.h"
#include "./delay.h"

/****************************
    功能:配置GPIO的输入模式
    参数:无
    返回值:无
*****************************/
void DS18B20_GPIO_IN(void)
{
    GPIO_InitTypeDef initValue;
    
    /*1、打开时钟*/
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
    
    /*2、配置GPIO的输入功能*/
    initValue.GPIO_Mode = GPIO_Mode_IN;
    initValue.GPIO_Pin = GPIO_Pin_15;
    initValue.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB,&initValue);
}

/****************************
    功能:配置GPIO的输出模式
    参数:无
    返回值:无
*****************************/
void DS18B20_GPIO_OUT(void)
{
    GPIO_InitTypeDef initValue;
    
    /*1、打开时钟*/
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
    
    /*2、配置GPIO的输出功能*/
    initValue.GPIO_Mode = GPIO_Mode_OUT;
    initValue.GPIO_Pin = GPIO_Pin_15;
    initValue.GPIO_PuPd = GPIO_PuPd_NOPULL;
    initValue.GPIO_OType = GPIO_OType_PP;
    initValue.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&initValue);
}

/****************************
    功能:复位脉冲
    参数:无
    返回值:无
*****************************/
void DS18B20_RST(void)
{
    /*1、配置GPIO的输出模式*/
    DS18B20_GPIO_OUT();
    
    /*2、输出低电平*/
    DS18B20_DQ_OUT_LOW();
    
    /*3、延时至少480us*/
    delay_us(750);
    
    /*4、输出高电平*/
    DS18B20_DQ_OUT_HIGH();
    
    /*5、延时15~60us*/
    delay_us(15);
}

/*************************************
    功能:应答信号
    参数:无
    返回值:
      返回1-->未检测到DS18B20的存在
      返回0-->DS18B20存在
**************************************/
uint8_t DS18B20_ACK(void)
{
    uint8_t retry = 0;
    
    /*1、配置GPIO的输入功能*/
    DS18B20_GPIO_IN();
    
    /*2、等待DQ拉低*/
    while(DS18B20_DQ_IN() && retry<200) //高电平
    {
        retry++;
        delay_us(1);
    }
    if(retry >= 200)
    {
        return 1;
    }
    else
    {
        retry = 0;
    }
    
    /*3、*/
    while(!DS18B20_DQ_IN() && retry<240)//低电平
    {
        retry++;
        delay_us(1);
    }
    if(retry>=240)
    {
        return 1;
    }
    return 0;
    
}

/****************************
    功能:写一个字节到DS18B20
    参数:无
    功能:无
*****************************/
void DS18B20_Write_Byte(uint8_t data)
{
    uint8_t i;
    uint8_t testb;
    
    /*1、配置GPIO的输出模式*/
    DS18B20_GPIO_OUT();
    
    /*2、写字节到DS18B20*/
    for(i = 0;i<8;i++)
    {
        testb = data & 0x01; //取出低位数据
        data = data >> 1;
        if(testb == 1)//写1
        {
            DS18B20_DQ_OUT_LOW();
            delay_us(2);
            DS18B20_DQ_OUT_HIGH();
            delay_us(60);
        }
        else //写0
        {
            DS18B20_DQ_OUT_LOW();
            delay_us(60);
            DS18B20_DQ_OUT_HIGH();
            delay_us(2);
        }
    }
}

/****************************************
    功能:从DS18B20中读取一个位
    参数:无
    返回值:读取到的数据
*****************************************/
uint8_t DS18B20_Read_Bit(void)
{
    uint8_t data;
    
    /*1、配置GPIO的输出模式*/
    DS18B20_GPIO_OUT();
    
    /*2、输出低电平*/
    DS18B20_DQ_OUT_LOW();
    
    /*3、延时至少1us*/
    delay_us(2);
    
    /*4、输出高电平*/
    DS18B20_DQ_OUT_HIGH();
    DS18B20_GPIO_IN();//输入模式
    
    /*5、延时0~15us*/
    delay_us(12);
    
    /*6、读取一个位的数据*/
    if(DS18B20_DQ_IN() == 1)//读取到的数据为1
    {
        data = 1;
    }
    else//读取到的数据为0
    {
        data = 0;
    }
    
    /*7、延时50us*/
    delay_us(50);
    
    return data;
    
}

/****************************************
    功能:从DS18B20中读取一个字节的数据
    参数:无
    返回值:读取到的数据
*****************************************/
uint8_t DS18B20_Read_Byte(void)
{
    uint8_t i = 0;
    uint8_t j;
    uint8_t data = 0;
    
    for(i = 0;i<8;i++)
    {
        j = DS18B20_Read_Bit();
        data = ((j<<7) | (data >>1));
    }
    return data;
}

/**********************************************
    功能:读取温度
    参数:无
    返回值:读取到的温度(-550~1250,扩大了10倍)
***********************************************/
short DS18B20_Get_Temp(void)
{
    uint8_t t;
    short temp;
    uint8_t TL,TH;
    
    /*1、复位*/
    DS18B20_RST();
    
    DS18B20_ACK();//应答
    
    /*2、发送SKIP ROM命令(0xCC)*/
    DS18B20_Write_Byte(0xCC);
    
    /*3、发送开始转换命令(0x44)*/
    DS18B20_Write_Byte(0x44);
    
    
    /*4、复位*/
    DS18B20_RST();
    
    DS18B20_ACK();//应答
    
    /*5、发送SKIP ROM命令(0xCC)*/
    DS18B20_Write_Byte(0xCC);
    
    /*6、发送存储器命令(0xBE)*/
    DS18B20_Write_Byte(0xBE);
    
    /*7、连续读出两个字节数据(即温度)*/
    TL = DS18B20_Read_Byte();
    TH = DS18B20_Read_Byte();
    
    /*8、处理读取到的数据*/
    if(TH > 7) //温度为负
    {
        TH = ~TH;
        TL = ~TL;
        t = 0;
    }
    else //温度为正
    {
        t = 1;
    }
    
    //获得高8位
    temp = TH;
    temp <<= 8;
    temp += TL;//获得低8位
    temp = (double)temp * 0.625;//转换
    if(t == 1)
    {
        return temp;
    }
    else
    {
        return ~temp;
    }
}
 

main.c文件

#include "delay.h"
#include "stdio.h"
#include "./USART/usart.h"
#include "./DS18B20/ds18b20.h"

int main(void)
{
    short temperature;
    //初始化延时函数
    delay_init(168);
    //初始化串口
    USART_Config();

    //读取DAC值
    temperature = DS18B20_Get_Temp();
    printf("value = %d \r\n",temperature);
    
    while(1)
    {
        
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值