ds18b20温度传感器arduino_na820温控器说明书

ds18b20温度传感器arduino_na820温控器说明书关于DS18B20和的基本信息在此就不详细介绍了


前言

关于DS18B20和的基本信息在此就不详细介绍了。本文代码部分主要参考了两篇文章1 2 ,具体时序图及解说可阅读这篇博客,对DS18B20的时序等工作原理的理解也参考了另一份博客3和视频 4 ,最终,成功将基于常见STM32开发板的DS18B20程序移植到了BearPi-HM_Nano开发板中,接下来将介绍如何开发板连接DS18B20数字温度传感器测量温度。

本实验在Hi3861开发环境下编译运行,得到的温度精度为小数点后三位。

温度传感器与小熊派开发板连接如下:
DQ——GPIO7 VDD——v5.5 GND——-GND
在这里插入图片描述


一、使用步骤

将DS18B20的头文件和.c文件放到所需的工程中即可。

step1 、在程序头部引入DS18B20.h头文件,
step2、在主程序中调用初始化函数 DS18B20_Init()
step3、在需要读取温度的位置调用读取函数DS18B20_Read_Temperature(),用于获取当前温度currentTemp。

#include DS18B20.h //step1
#include (other xxx.h)
....

void task(void){ 
   
float currentTemp;
GpioInit();
DS18B20_Init();		//step2
while(1){ 
   
	currentTemp=DS18B20_Read_Temperature();   //step3
	printf("\nCurrentTemperature = %.3f",currentTemp);
}
}

在工程的BUILD.gn文件中,
step4、static_library(“修改一下这里,自定义”)
step5、sources = [… …]中增加DS18B20.c文件,
step6、并在include_dirs = [… …]中增加DS18B20.c和DS18B20.h文件中所需的头文件路径。

在顶层BUIL.gn中,
step7、lite_component(“app”) {

features = [增加你要编译的工程,对应step4中的名字] }

二、程序代码

1、定义初始化部分

定义 GPIO7为DS18B20的信号引脚,再定一个全局变量DS18B20_DQ_IN存放从DS18B20中读取到的电平信号。

#define GPIO_DQ WIFI_IOT_IO_NAME_GPIO_7
WifiIotGpioValue DS18B20_DQ_IN = { 
   0};

将与输入有关的两个功能打包成函数,以便后面使用。

/****************************************************** * 函数名 :DS18B20_IO_IN * 功能 :设置端口为输入 * 输入 :无 * 输出 :无 *******************************************************/
void DS18B20_IO_IN(void){ 
   
    //设置GPIO_DQ为输入模式
    GpioSetDir(GPIO_DQ,WIFI_IOT_GPIO_DIR_IN);
    //配置为浮空输入
    IoSetPull(GPIO_DQ,WIFI_IOT_IO_PULL_NONE);
}

/****************************************************** * 函数名 :GPIO_GetInputValue * 功能 :获取GPIO输入状态 * 输入 :id, *val * 输出 :0/1 *******************************************************/
uint8_t GPIO_GetInputValue(WifiIotIoName id,WifiIotGpioValue *val){ 
   
   GpioGetInputVal(id,val);
   return *val;
}

初始化DS18B20

/******************************************** * 函数名 :DS18B20_Init * 功能 :初始化DS18B20 * 输入 :无 * 输出 :无 ********************************************/
uint8_t DS18B20_Init(void){ 
   
     //配置数据信号引脚GPIO_7(GPIO_DQ)
    IoSetFunc(GPIO_DQ,WIFI_IOT_IO_FUNC_GPIO_7_GPIO);
    //设置GPIO_DQ为输出模式
    GpioSetDir(GPIO_DQ,WIFI_IOT_GPIO_DIR_OUT);
    //设置GPIO_DQ输出高电平
    GpioSetOutputVal(GPIO_DQ,1);
    //复位DS18B20
    DS18B20_Res();
    //等待DS18B20的回应
    return DS18B20_Check();
}

/******************************************** * 函数名 :DS18B20_Res * 功能 :复位DS18B20 * 输入 :无 * 输出 :无 ********************************************/
void DS18B20_Res(void){ 
   
    //设置GPIO_DQ为输出模式
    GpioSetDir(GPIO_DQ,WIFI_IOT_GPIO_DIR_OUT);
    //拉低电平
    GpioSetOutputVal(GPIO_DQ, 0);
    //延时750us
    usleep(750);
    //拉高电平
    GpioSetOutputVal(GPIO_DQ, 1);
    //延时15us,为应答脉冲做准备
    hi_udelay(15);
}

响应部分

/******************************************** * 函数名 :DS18B20_Check * 功能 :将引脚设置为输入模式,等待DS18B20拉低电平的回应 * 判断引脚低电平时间是否大于60us,小于240us * 返回应答结果 * 输入 :无 * 输出 :返回1 无响应 返回0 有响应 * ******************************************/
uint8_t DS18B20_Check(void){ 
   
    uint8_t t=0;
    //配置GPIO_3为输入模式
    DS18B20_IO_IN();
    //等待应答,引脚一直为高,未被设备主动拉低。提供200us的超时时间
    while(GPIO_GetInputValue(GPIO_DQ,&DS18B20_DQ_IN) && t<200){ 
   
        t++;
        hi_udelay(1);
    }
    //若超时仍未响应,则返回1
    if(t>=200){ 
   
        printf("\nError: Waiting Response Overtime!Non-Respond!");
        return 1;
    }else{ 
   
        t=0;
    }
    //引脚响应,则判断引脚低电平时间是否大于60us,小于240us
    while((!GPIO_GetInputValue(GPIO_DQ,&DS18B20_DQ_IN)) && t<240){ 
   
        t++;
        hi_udelay(1);
    }
    //响应时间过长,应答失败
    if(t>=240){ 
   
        printf("\nError: Responsing Overtime! \n");
        return 1;
    }
    printf("\nResponse is OK !(t = %d)",t);
    return 0;
 
}

2、读写功能部分

写数据

/******************************************** * 函数名 :DS18B20_Write_Byte * 功能 :写一个字节到DS18B20 * 输入 :要写入的字节 * 输出 :无 * ******************************************/
void DS18B20_Write_Byte(uint8_t byte){ 
   
    uint8_t i,test;
    //设置GPIO_3为输出模式
    GpioSetDir(GPIO_DQ,WIFI_IOT_GPIO_DIR_OUT);
    for(i=1;i<=8;i++){ 
   
        test = byte & 0x01;
        byte = byte >> 1;
        if(test){ 
              //写1
            GpioSetOutputVal(GPIO_DQ, 0);
            hi_udelay(2);
            GpioSetOutputVal(GPIO_DQ, 1);
            hi_udelay(60);
        }else{ 
                 //写0
            GpioSetOutputVal(GPIO_DQ, 0);
            hi_udelay(60);
            GpioSetOutputVal(GPIO_DQ, 1);
            hi_udelay(2);
        }
    }
}

读数据

/******************************************** * 函数名 :DS18B20_Read_Byte * 功能 :读取一个字节 * 输入 :无 * 输出 :1/0 * ******************************************/
uint8_t DS18B20_Read_Bit(void){ 
   
    uint8_t t=0;
    //设置GPIO_3为输出模式
    GpioSetDir(GPIO_DQ,WIFI_IOT_GPIO_DIR_OUT);
    GpioSetOutputVal(GPIO_DQ, 0);      //拉低
    hi_udelay(2);
    GpioSetOutputVal(GPIO_DQ, 1);       //释放
    //设置GPIO_3为输入模式
    DS18B20_IO_IN();
    hi_udelay(12);
    //获取输入电平值
    if(GPIO_GetInputValue(GPIO_DQ,&DS18B20_DQ_IN)){ 
     
        hi_udelay(50);
        return 1;}
    else{ 
   
        hi_udelay(50);
        return 0;}
}

uint8_t DS18B20_Read_Byte(void){ 
   
    uint8_t i,j,data;
    data = 0;
    for(i=1;i<=8;i++){ 
   
        j=DS18B20_Read_Bit();
        data =(j<<7)|(data>>1);
        hi_udelay(2);
    }
    return data;
}

3、获取温度部分

/******************************************** * 函数名 :DS18B20_Read_Temperature * 功能 :温度读取 * 输入 :无 * 输出 :温度 * ******************************************/
void DS18B20_Change_Temperature(void){ 
   
    DS18B20_Res();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);
    DS18B20_Write_Byte(0x44);
}

float DS18B20_Read_Temperature(void){ 
   
    uint8_t TL,TH;
    uint16_t temp;
    short temperature;
    float result;
    DS18B20_Change_Temperature();
    DS18B20_Res();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);   //skip rom
    DS18B20_Write_Byte(0xbe);   //covert
    TL = DS18B20_Read_Byte();   //lsb
    TH = DS18B20_Read_Byte();   //msb
   
    if(TH >7){ 
   		//若读取到的温度为负数,则高低位都取反
        TH = ~TH;
        TL = ~TL;
        temp = 0;
    }else{ 
   			//读取到的温度为正
        temp = 1;
    }

    temperature = TH;
    temperature = temperature << 8;
    temperature += TL;
    result = (float)temperature * 0.0625;
    printf("\nresult = %.3f",result); 
    if(temp){ 
   
        return result;
    }else{ 
   
        return -result;
    }
}

4、完整代码

DS18B20.h

#ifndef _DS18B20_H_
#define _DS18B20_H_

#include <stdio.h>
#include "cmsis_os2.h"

uint8_t DS18B20_Init(void);
void DS18B20_Res(void);
uint8_t DS18B20_Check(void);
void DS18B20_Write_Byte(uint8_t byte);
uint8_t DS18B20_Read_Byte(void);
float DS18B20_Read_Temperature(void);

#endif /* _DS18B20_H_ */

DS18B20.c

#include <stdio.h>
#include <unistd.h>
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "ds18b20.h"
#include "hi_time.h"

#define GPIO_DQ WIFI_IOT_IO_NAME_GPIO_7

WifiIotGpioValue DS18B20_DQ_IN = { 
   0};

/****************************************************** * 函数名 :DS18B20_IO_IN * 功能 :设置端口为输入 * 输入 :无 * 输出 :无 *******************************************************/
void DS18B20_IO_IN(void){ 
   
    //设置GPIO_DQ为输入模式
    GpioSetDir(GPIO_DQ,WIFI_IOT_GPIO_DIR_IN);
    //配置为浮空输入
    IoSetPull(GPIO_DQ,WIFI_IOT_IO_PULL_NONE);
}

/****************************************************** * 函数名 :GPIO_GetInputValue * 功能 :获取GPIO输入状态 * 输入 :id, *val * 输出 :0/1 *******************************************************/
uint8_t GPIO_GetInputValue(WifiIotIoName id,WifiIotGpioValue *val){ 
   
   GpioGetInputVal(id,val);
   return *val;
}

/******************************************** * 函数名 :DS18B20_Init * 功能 :初始化DS18B20 * 输入 :无 * 输出 :无 ********************************************/
uint8_t DS18B20_Init(void){ 
   
     //配置数据信号引脚GPIO_7(GPIO_DQ)
    IoSetFunc(GPIO_DQ,WIFI_IOT_IO_FUNC_GPIO_7_GPIO);
    //设置GPIO_DQ为输出模式
    GpioSetDir(GPIO_DQ,WIFI_IOT_GPIO_DIR_OUT);
    //设置GPIO_DQ输出高电平
    GpioSetOutputVal(GPIO_DQ,1);
    //复位DS18B20
    DS18B20_Res();
    //等待DS18B20的回应
    return DS18B20_Check();
}

/******************************************** * 函数名 :DS18B20_Res * 功能 :复位DS18B20 * 输入 :无 * 输出 :无 ********************************************/
void DS18B20_Res(void){ 
   
    //设置GPIO_DQ为输出模式
    GpioSetDir(GPIO_DQ,WIFI_IOT_GPIO_DIR_OUT);
    //拉低电平
    GpioSetOutputVal(GPIO_DQ, 0);
    //延时750us
    usleep(750);
    //拉高电平
    GpioSetOutputVal(GPIO_DQ, 1);
    //延时15us,为应答脉冲做准备
    hi_udelay(15);
}

/******************************************** * 函数名 :DS18B20_Check * 功能 :将引脚设置为输入模式,等待DS18B20拉低电平的回应 * 判断引脚低电平时间是否大于60us,小于240us * 返回应答结果 * 输入 :无 * 输出 :返回1 无响应 返回0 有响应 * ******************************************/
uint8_t DS18B20_Check(void){ 
   
    uint8_t t=0;
    //配置GPIO_3为输入模式
    DS18B20_IO_IN();
    //等待应答,引脚一直为高,未被设备主动拉低。提供200us的超时时间
    while(GPIO_GetInputValue(GPIO_DQ,&DS18B20_DQ_IN) && t<200){ 
   
        t++;
        hi_udelay(1);
    }
    //若超时仍未响应,则返回1
    if(t>=200){ 
   
        printf("\nError: Waiting Response Overtime!Non-Respond!");
        return 1;
    }else{ 
   
        t=0;
    }
    //引脚响应,则判断引脚低电平时间是否大于60us,小于240us
    while((!GPIO_GetInputValue(GPIO_DQ,&DS18B20_DQ_IN)) && t<240){ 
   
        t++;
        hi_udelay(1);
    }
    //响应时间过长,应答失败
    if(t>=240){ 
   
        printf("\nError: Responsing Overtime! \n");
        return 1;
    }
    printf("\nResponse is OK !(t = %d)",t);
    return 0;
 
}

/******************************************** * 函数名 :DS18B20_Write_Byte * 功能 :写一个字节到DS18B20 * 输入 :要写入的字节 * 输出 :无 * ******************************************/
void DS18B20_Write_Byte(uint8_t byte){ 
   
    uint8_t i,test;
    //设置GPIO_3为输出模式
    GpioSetDir(GPIO_DQ,WIFI_IOT_GPIO_DIR_OUT);
    for(i=1;i<=8;i++){ 
   
        test = byte & 0x01;
        byte = byte >> 1;
        if(test){ 
              //写1
            GpioSetOutputVal(GPIO_DQ, 0);
            hi_udelay(2);
            GpioSetOutputVal(GPIO_DQ, 1);
            hi_udelay(60);
        }else{ 
                 //写0
            GpioSetOutputVal(GPIO_DQ, 0);
            hi_udelay(60);
            GpioSetOutputVal(GPIO_DQ, 1);
            hi_udelay(2);
        }
    }
}

/******************************************** * 函数名 :DS18B20_Read_Byte * 功能 :读取一个字节 * 输入 :无 * 输出 :1/0 * ******************************************/
uint8_t DS18B20_Read_Bit(void){ 
   
    uint8_t t=0;
    //设置GPIO_3为输出模式
    GpioSetDir(GPIO_DQ,WIFI_IOT_GPIO_DIR_OUT);
    GpioSetOutputVal(GPIO_DQ, 0);      //拉低
    hi_udelay(2);
    GpioSetOutputVal(GPIO_DQ, 1);       //释放
    //设置GPIO_3为输入模式
    DS18B20_IO_IN();
    hi_udelay(12);
    //获取输入电平值
    if(GPIO_GetInputValue(GPIO_DQ,&DS18B20_DQ_IN)){ 
     
        hi_udelay(50);
        return 1;}
    else{ 
   
        hi_udelay(50);
        return 0;}
}

uint8_t DS18B20_Read_Byte(void){ 
   
    uint8_t i,j,data;
    data = 0;
    for(i=1;i<=8;i++){ 
   
        j=DS18B20_Read_Bit();
        data =(j<<7)|(data>>1);
        hi_udelay(2);
    }
    return data;
}

/******************************************** * 函数名 :DS18B20_Read_Temperature * 功能 :温度读取 * 输入 :无 * 输出 :温度 * ******************************************/
void DS18B20_Change_Temperature(void){ 
   
    DS18B20_Res();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);
    DS18B20_Write_Byte(0x44);
}

float DS18B20_Read_Temperature(void){ 
   
    uint8_t TL,TH;
    uint16_t temp;
    short temperature;
    float result;
    DS18B20_Change_Temperature();
    DS18B20_Res();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);   //skip rom
    DS18B20_Write_Byte(0xbe);   //covert
    TL = DS18B20_Read_Byte();   //lsb
    TH = DS18B20_Read_Byte();   //msb
   
    if(TH >7){ 
   
        TH = ~TH;
        TL = ~TL;
        temp = 0;
    }else{ 
   
        temp = 1;
    }

    temperature = TH;
    temperature = temperature << 8;
    temperature += TL;
    result = (float)temperature * 0.0625;
    printf("\nresult = %.3f",result); 

    if(temp){ 
   
        return result;
    }else{ 
   
        return -result;
    }
}

三、实验结果

实验结果如下:
Alt
测量结果精度为小数点后三位。

四、移植难点

1、延时
这里的实现需要导入hi_time.h头文件,调用hi_udelay()实现而不能用usleep()函数。1
2、输入模式的设置
不能仅用GpioSetDir(WifiIotGpioIdx id, WifiIotGpioDir dir)函数,还需加上上拉函数将GPIO引脚设置为浮空输入,将读取传感器的值打包成了一个独立的函数,如下

void DS18B20_IO_IN(void){ 
   
    //设置GPIO_DQ为输入模式
    GpioSetDir(GPIO_DQ,WIFI_IOT_GPIO_DIR_IN);
    //配置为浮空输入
    IoSetPull(GPIO_DQ,WIFI_IOT_IO_PULL_NONE);
}

参考资料


  1. STM32学习之DS18B20数字温度传感器 ↩︎ ↩︎

  2. OpenHarmony学习笔记——Hi3861使用DHT11获取温湿度 ↩︎

  3. 第9讲_51单片机_DS18B20数字温度计模块 ↩︎

  4. STM32F103驱动DS18B20温度传感器(程序注释超详细) ↩︎

今天的文章ds18b20温度传感器arduino_na820温控器说明书分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/86265.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注