资讯详情

【HamonyOS嵌入式】BearPi-HM_Nano控制DS18B20温度传感器(注释版)

文章目录

  • 前言
  • 一、使用步骤
  • 二、程序代码
    • 1.定义初始化部分
    • 2.读写功能部分
    • 3.获取温度部分
    • 4、完整代码
      • DS18B20.h
      • DS18B20.c
  • 三、实验结果
  • 四、移植难点
  • 参考资料


前言

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

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

温度传感器与小熊派开发板连接如下: 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 =<

标签: 湿度传感器hm1520

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台