zoukankan      html  css  js  c++  java
  • STM32应用实例五:与SHT1X温湿度传感器通讯

    在这次项目开发中应用到了SHT1X温湿度传感器,该系列有SHT10、SHT11和SHT15,属于Sersirion温湿度传感器家族中的贴片封装系列。包括一个电容性聚合体测湿敏感元件、一个用能隙材料制成的测温元件,传感器内部有一个精度高达14为位的A/D转换器。更详细资料请参考说明书。

    1、硬件介绍

    现在对本次使用的SHT15作简要介绍。其引脚定义如下:

    引脚

    名称

    描述

                                                                         

    1

    GND

    2

    DATA

    串行数据, 双向

    3

    SCK

    串行时钟, 输入口

    4

    VDD

    电源

    NC

    NC

    必须为空

    SHT1X温湿度传感器使用的2线通讯,类是于I2C总线,但并不相同,使用普通的GPIO就可实现通讯。此次采用STM32F103VET6来操作SHT15,具体的连接方式如下:

    SCK 用于微处理器与SHT1x 之间的通讯同步。由于接口包含了完全静态逻辑,因而不存在最小SCK 频率。

    DATA 引脚为三态结构,用于读取传感器数据 . 当向传感器发送命令时, DATA 在 SCK 上升沿有效且在 SCK 高电平时必须保持稳定。 DATA 在 SCK 下降沿之后改变。为避免信号冲突,微处理器应驱动DATA 在低电平。需要一个外部的上拉电阻(例如: 10kΩ)将信号提拉至高电平。上拉电阻通常已包含在微处理器的I/O 电路中。

    2、通讯实现

    现在说明一下传感器通讯的实现。首先看一看其操作命令。传感器的命令包含三个地址位(目前只支持000,这就是只能挂接在空闲的IIC总线上的原因)和五个命令位。SHT1x 会以下述方式表示已正确地接收到指令:在第8个SCK 时钟的下降沿之后,将DATA 下拉为低电平(ACK 位)。在第9个SCK 时钟的下降沿之后,释放DATA(恢复高电平)。命令集如下:

    命令

    代码

    预留

    0000x

    温度测量

    00011

    湿度测量

    00101

    读状态寄存器

    00111

    写状态寄存器

    00110

    预留

    0101x-1110x

    软复位, 接口复位, 状态寄存器复位即恢复为默认状态.在要发送下一个命令前,至少等待 11ms.

    11110

    接下来具体说说各种该命令操作的实现:

    (1)启动时序

    用一组“启动传输”时序来完成数据传输的初始化。它包括:当SCK时钟高电平时DATA翻转为低电平,紧接着SCK变成低电平,随后是在SCK时钟高电平,随后是在SCK时钟高电平DATA翻转位高电平。时序如下:

     

    具体的编码实现如下:

    /*SHT1X启动时序操作*/
    
    void StartSHT1XOperation(BusPinOperation *SetBusPin)
    
    {
    
      /*将data线设置为输出模式*/
    
      SetDataPineDirection(Out);
    
     
    
      SetBusPin[DataPin](Set);
    
      SetBusPin[SckPin](Reset);
    
      Delayus(10);
    
     
    
      SetBusPin[SckPin](Set);
    
      Delayus(5);
    
      SetBusPin[DataPin](Reset);
    
      Delayus(5);
    
      SetBusPin[SckPin](Reset);
    
      Delayus(10);
    
      SetBusPin[SckPin](Set);
    
      Delayus(5);
    
      SetBusPin[DataPin](Set);
    
      Delayus(10);
    
      SetBusPin[SckPin](Reset);
    
    }

    (2)通讯复位

    如果与SHT1x 通讯中断,可通过下列信号时序复位:当DATA 保持高电平时,触发SCK 时钟9 次或更多。时序图如下:

     

    具体的编码实现如下:

    /*SHT1X通讯复位*/
    
    void ResetSHT1XCommunication(BusPinOperation *SetBusPin)
    
    {
    
      /*将data线设置为输出模式*/
    
      SetDataPineDirection(Out);
    
      Delayms(1);
    
     
    
      SetBusPin[DataPin](Set);
    
      SetBusPin[SckPin](Reset);
    
     
    
      for(int i=0;i<9;i++)
    
      {
    
        SetBusPin[SckPin](Set);
    
        Delayus(10);
    
        SetBusPin[SckPin](Reset);
    
        Delayus(10);
    
      }
    
     
    
      StartSHT1XOperation(SetBusPin);
    
    }

    同时也可以实现软件复位,状态寄存器复位为默认状态。在要发送下一个命令前,至少等待 11ms。具体实现如下:

    /*对SHT1X实现软件复位*/
    
    uint8_t Sht1xSoftwareReset(BusPinOperation *SetBusPin)
    
    {
    
      uint8_t err = 0;
    
       
    
      ResetSHT1XCommunication(SetBusPin);
    
      err=err+WriteByteT0Sht1x(SOFTWARE_RESET,SetBusPin);
    
      return err;
    
    }

    (3)操作状态寄存器

    SHT1x 的某些高级功能可以通过给状态寄存器发送指令来实现,如选择测量分辨率,电量不足提醒,使用 OTP 加载或启动加热功能等。

    /*读状态寄存器*/
    
    uint8_t ReadStatusRegister(uint8_t *pValue,uint8_t *pCheckSum,BusPinOperation *SetBusPin)
    
    {
    
      uint8_t err=0;
    
     
    
      StartSHT1XOperation(SetBusPin);
    
      err=WriteByteT0Sht1x(READ_STATUS_REGISTER,SetBusPin);
    
      *pValue=ReadByteFromSht1x( Ack,SetBusPin);
    
      *pCheckSum=ReadByteFromSht1x( noAck,SetBusPin);
    
     
    
      return err;
    
    }
    
     
    
    /*写状态寄存器*/
    
    uint8_t WriteStatusRegister(uint8_t *pValue,BusPinOperation *SetBusPin)
    
    {
    
      uint8_t err=0;
    
     
    
      StartSHT1XOperation(SetBusPin);
    
      err +=WriteByteT0Sht1x(WRITE_STATUS_REGISTER,SetBusPin);
    
      err +=WriteByteT0Sht1x(*pValue,SetBusPin);
    
     
    
      return err;
    
    }

    (4)温湿度的读取和计算

    发布一组测量命令(‘00000101’表示相对湿度RH,‘00000011’表示温度T)后,控制器要等待测量结束。这个过程需要大约20/80/320ms,分别对应8/12/14bit 测量。根据本人测试8位时,15ms可以;12位时,70ms可以;14位时240ms可以。 SHT1x 通过下拉DATA 至低电平并进入空闲模式,表示测量的结束。控制器在再次触发SCK 时钟前,必须等待这个“数据备妥”信号来读出数据。检测数据可以先被存储,这样控制器可以继续执行其它任务在需要时再读出数据。

    /*获取SHT1X的温度值*/
    
    float GetSht1xTemperatureValue(float vdd,BusPinOperation *SetBusPin)
    
    {
    
      float tempValue=0.0;
    
      uint16_t sot=0;
    
      uint8_t err=0;
    
      uint8_t highByte=0;
    
      uint8_t lowByte=0;
    
      uint8_t checkSum=0;
    
      StartSHT1XOperation(SetBusPin);
    
      WriteByteT0Sht1x(TEMP_MEAS_COMMAND,SetBusPin);
    
      SetDataPineDirection(In);
    
      Delayms(240);
    
     
    
      if(ReadDataPinBit() == 1)
    
      {
    
        err += 1;
    
      }
    
      highByte=ReadByteFromSht1x(Ack,SetBusPin);
    
      lowByte=ReadByteFromSht1x(Ack,SetBusPin);
    
      checkSum=ReadByteFromSht1x(noAck,SetBusPin);
    
     
    
      sot=(uint16_t)highByte;
    
      sot=(sot*256)+(uint16_t)lowByte;
    
     
    
      if(err != 0)
    
      {
    
        ResetSHT1XCommunication(SetBusPin);
    
      }
    
      else
    
      {
    
        tempValue=ConvertTemperatureData(sot,vdd);
    
      }
    
     
    
      return tempValue;
    
    }
    
     
    
    /*获取SHT1X的湿度值*/
    
    float GetSht1xHumidityValue(float temp,BusPinOperation *SetBusPin)
    
    {
    
      float humiValue=0.0;
    
      uint16_t sorh=0;
    
      uint8_t err=0;
    
      uint8_t highByte=0;
    
      uint8_t lowByte=0;
    
      uint8_t checkSum=0;
    
     
    
      StartSHT1XOperation(SetBusPin);
    
      WriteByteT0Sht1x(HUMI_MEAS_COMMAND,SetBusPin);
    
      SetDataPineDirection(In);
    
      Delayms(70);
    
     
    
      if(ReadDataPinBit() == 1)
    
      {
    
        err += 1;
    
      }
    
      highByte=ReadByteFromSht1x(Ack,SetBusPin);
    
      lowByte=ReadByteFromSht1x(Ack,SetBusPin);
    
      checkSum=ReadByteFromSht1x(noAck,SetBusPin);
    
       
    
      sorh=(highByte<<8)|lowByte;
    
     
    
      if(err != 0)
    
      {
    
        ResetSHT1XCommunication(SetBusPin);
    
      }
    
      else
    
      {
    
        humiValue=ConvertHumidityData(sorh,temp);
    
      }
    
     
    
      return humiValue;
    
    }

    对于其他的计算部分直接按公式便写即可。

  • 相关阅读:
    Spring MVC视图层:thymeleaf vs. JSP
    Guava学习笔记:Google Guava 类库简介
    Hibernate与 MyBatis的比较
    SpringMVC与Struts2区别与比较总结
    Springmvc中@RequestParam传值中文乱码解决方案
    HQL和Criteria
    Struts2的select使用
    Spring AOP原理及拦截器
    hibernate:inverse、cascade,一对多、多对多详解
    mysql中索引利用情况(explain用法)
  • 原文地址:https://www.cnblogs.com/foxclever/p/6515058.html
Copyright © 2011-2022 走看看