外设驱动库开发笔记10:SHT2x系列温湿度传感器驱动

温湿度检测是嵌入式编程中经常应用到的一项功能。在我们的产品中亦经常使用。SHT2x系列温湿度传感器作为一种高精度低成本的集成模块,一直应用于我们的产品中。在这里我们讨论如何封装SHT2x系列温湿度传感器的驱动。

1、功能概述

SHT20配有一个全新设计的CMOSens芯片、一个经过改进的电容式湿度传感元件和一个标准的能隙温度传感元件,其性能已经大大提升甚至超出了前一代传感器(SHT1xSHT7x)的可靠性水平。

1.1、硬件描述

SHT2x湿度和温度传感器采用了新的封装模式和数字接口,每一个传感器都经过校准和测试。在产品表面印有产品批号,同时在芯片内存储了电子识别码-可以通过输入命令读出这些识别码。此外,SHT2x温湿度传感器的分辨率可以通过输入命令进行改变(8/12bit乃至12/14bitRH/T),传感器可以检测到电池低电量 状态,并且输出校验和,有助于提高通信的可靠性。SHT2x温湿度传感器的封装及引脚定义如下图:

SHT2x 温湿度传感器的供电范围为 2.1-3.6V,推荐电压为 3.0V。电源(VDD)和接地(VSS)之间须连接一个100nF的去耦电容,且电容的位置应尽可能靠近传感器。数字接口为标准I2C总线。接线方式如下图:

1.2、串行通讯

SHT2x温湿度传感器采用标准的 I2C协议进行通讯。在启动传输后,随后传输的I2C首字节包括 7位的I2C设备地址(B-范例地址“1000’000”)和一个SDA方向位(读 R“1”,写 W“0”)。在第 8SCL时钟下降沿之后,通过拉低 SDA引脚(ACK位),指示传感器数据接收正常。在发出测量命令之后(“1110’0011”代表温度测量,“1110’0101”代表相对湿度测量),MCU必须等待测量完成。基本的命令列表如下:

从上表我们知道,读取SHT2x温湿度传感器数据有两种不同的方式可选,主机模式或非主机模式。在主机模式下,在测量的过程中, SCL线被封锁(由 传感器进行控制),在非主机模式下,当传 感器在执行测量任务时,SCL线仍然保持开 放状态,可进行其他通讯。非主机模式允许 传感器进行测量时在总线上处理其他 I2C 线通讯任务。

1.3、数据转换

传感器内部设置的默认分辨率为相对湿度12位和温度14位。SDA的输出数据被转换成两 个字节的数据包,高字节MSB在前(左对齐)。每个字节后面都跟随一个应答位。两个状态位,即LSB的后两位在进行物理计算前须置“0”

不论基于哪种分辨率,相对湿度RH都可以根据SDA输出的相对湿度信号 SRH通过如下公式计算获得(结果以%RH表示)。

以上所给出的 RH物理值对应于世界气象组织(WMO)所规定的基于液态水的相对湿度。基于冰的相对湿度RHi可通过特定温度t下基于水的 相对湿度 RHw转换而来,同样参照应用说明

相对湿度单位为 %RH温度单位为°C for temperature. 相关系数如下:

不论基于哪种分辨率,温度 T都可以通过将温度输 出信号 ST代入到下面的公式计算得到(结果以温 °C表示):

2、驱动设计与实现

我们已经了解了SHT2x系列温湿度传感器基本技术特性,接下来我们进一步考虑如何设计并实现SHT2x系列温湿度传感器的驱动。

2.1、对象定义

在使用一个对象之前我们需要获得一个对象。同样的我们想要SHT2x系列温湿度传感器就需要先定义SHT2x系列温湿度传感器的对象。

2.1.1、对象的抽象

我们要得到SHT2x系列温湿度传感器对象,需要先分析其基本特性。一般来说,一个对象至少包含两方面的特性:属性与操作。接下来我们就来从这两个方面思考一下SHT2x系列温湿度传感器的对象。

先来考虑属性,作为属性肯定是用于标识或记录对象特征的东西。我们来考虑SHT2x系列温湿度传感器对象属性。首先对于I2C设备会有一个地址,用于表示总线上不同的通讯节点,所以我们将设备地址作为SHT2x系列温湿度传感器对象的一个属性。用户寄存器标识了设备的配置状态,所以我们也将其作为SHT2x系列温湿度传感器对象的一个属性。同样的每个SHT2X都有一个电子识别码,用以标识SHT2X设备的身份,所以我们也将其作为SHT2x系列温湿度传感器对象的一个属性。此外我们也将读出来的温湿度的数字编码所以我们也将其作为SHT2x系列温湿度传感器对象的属性以记录当前状态。

接着我们还需要考虑SHT2x系列温湿度传感器对象的操作问题。通过I2C总线发送数据或者接收数据均依赖于具体的操作平台,所以我们将向SHT2x发送数据以及从SHT2x获取数据均作为SHT2x系列温湿度传感器对象的操作。此外,在驱动中会用到延时操作函数,延时操作一般也会依赖于具体平台的实现,所以我们也将其作为SHT2x系列温湿度传感器对象的操作。

根据上述我们对SHT2x温湿度传感器的分析,我们可以定义SHT2x温湿度传感器的对象类型如下:

/*定义SHT2x对象*/typedef struct SHT2xObject{uint8_t userReg;      //用户寄存器uint8_t devAddress;          //设备地址uint8_t sn[8];        //设备序列号uint16_t tempCode;    //温度的数值码uint16_t humiCode;    //湿度的数值码void (*Delayms)(volatile uint32_t nTime);       //毫秒延时操作指针void (*Transmit)(struct SHT2xObject *sht,uint8_t *tData,uint16_t tSize);   //发送数据操作指针void (*Receive)(struct SHT2xObject *sht,uint8_t *rData,uint16_t rSize);    //接收数据操作指针
}SHT2xObjectType;

2.1.2、对象初始化

我们知道,一个对象仅作声明是不能使用的,我们需要先对其进行初始化,所以这里我们来考虑SHT2x系列温湿度传感器对象的初始化函数。一般来说,初始化函数需要处理几个方面的问题。一是检查输入参数是否合理;二是为对象的属性赋初值;三是对对象作必要的初始化配置。据此我们设计SHT2x系列温湿度传感器对象的初始化函数如下:

/* 初始化配置SHT2x */
void SHT2xInitialization(SHT2xObjectType *sht,SHT2xDPIType dpi,SHT2xBatteryType endBat,SHT2xHeaterType heater,SHT2xOTPType otp,SHT2xTransmit write,SHT2xReceive read,SHT2xDelayms delayms)
{uint8_t userReg=0;uint8_t dpiSet[4]={DPI_RH12_T14,DPI_RH8_T13,DPI_RH10_T12,DPI_RH11_T11};uint8_t batEnd[2]={END_OF_BATTERY_H,END_OF_BATTERY_L};uint8_t heaterSet[2]={ONCHIPHEATERDISABLE,ONCHIPHEATERENABLE};uint8_t otpSet[2]={OTPENABLE,OTPDISABLE};if((sht==NULL)||(write==NULL)||(read==NULL)||(delayms==NULL)){return;}sht->Transmit=write;sht->Receive=read;sht->Delayms=delayms;sht->devAddress=SHT2X_ADDRESS;sht->tempCode=0;sht->humiCode=0;userReg=dpiSet[dpi]|batEnd[endBat]|heaterSet[heater]|otpSet[otp];SetSHT2xUserRegister(sht,userReg);       //配置用户寄存器sht->Delayms(20);GetSHT2xUserRegister(sht);                //读取用户寄存器GetSHT2xSerialNumber(sht);               //获取电子识别码
}

2.2、对象操作

我们已经完成了SHT2x系列温湿度传感器对象类型的定义和对象初始化函数的设计。但我们的主要目标是获取对象的信息,接下来我们还要实现面向SHT2x温湿度传感器的各类操作。

2.2.1、软件复位

软件复位命令用于在无需关闭和再次打开电源的情况下,重新启动传感器系统。在接收到这个命令之后,传感器系统开始重新初始化,并恢复默认设置状态,用户寄存器的加热器位除外。软复位所需时间不超过15毫秒。命令格式如下:

/*软件复位*/
void SoftResetSHT2x(SHT2xObjectType *sht)
{uint8_t tData=SOFT_RESET;sht->Transmit(sht,&tData,1);
}

2.2.2、用户寄存器操作

用户寄存器用于配置SHT2X的工作特性,包括测量分辨率、电池电压、OTP加载和片内加热器配置等。用户寄存器的结构及各位的定义如下:

电池电量不足警报在电源电压下降到 2.25V 以下时激活。内部加热器用于传感器功能性诊断,温度升高时相对湿度降低。OTP重加载为一个安全功能,可以在每次测量前将整个OTP设置加载到寄存器,加热器位除外。SHT2X中此功能默认为禁止状态,且不推荐用户使用。请采用软复位代替它包含OTP重加载。

/*配置用户寄存器*/
static void SetSHT2xUserRegister(SHT2xObjectType *sht,uint8_t cmd)
{uint8_t status;uint8_t command;uint8_t pData[2];GetSHT2xUserRegister(sht);status=sht->userReg&0x38;command=cmd&0xC7;command=command|status;if(command!=sht->userReg){pData[0]=WRITE_USER_REGISTER;pData[1]=command;sht->Transmit(sht,pData,2);sht->Delayms(10);GetSHT2xUserRegister(sht);}
}

在配置用户寄存器时,需注意不得变更预留位且相关的预留位的默认值以后可能会改变。因此,在进行任何写寄存器的操作之前,必须先读预留位的默认值。之后,用户寄存器字节由对应的预留位的默认值和其他剩余位的默认值或者写入值组成。

2.2.3、数据获取

SHT2x温湿度传感器数据获取有主机模式或非主机模式两种。我们在这里先看看非主机模式,在非主机模式下,MCU需要对传感器状态进行查询。此过程通过发送一个启动传输时序,之后紧接着是如下图所示的I2C首字节(1000’0001)来完成。如果内部处理工作完成,单片机查询到传感器发出的确认信号后,相关数据就可以通过MCU进行读取。如果测量处理工作没有完成,传感器无确认位(ACK)输出,此时必须重新发送启动传输时序。

根据上述描述和时序图我们可以得到获取数据的函数如下:

/*读取SHT2x的湿度数据*/
float GetSHT2xHumidityValue(SHT2xObjectType *sht,uint8_t cmd)
{uint8_t data[3]={0,0,0};uint16_t result=0;/*设置转换命令*/sht->Transmit(sht,&cmd,1);sht->Delayms(29);/*读取数据*/sht->Receive(sht,data,3);if(CheckCRC8ForSHT2x(data,2,data[2])){result=(uint16_t)(data[0]);result=(result<<8)+(uint16_t)(data[1]);}sht->humiCode=result;return CalcSHT2xHumidity(result);
}

3、驱动的使用

我们已经设计并实现了SHT2x温湿度传感器驱动,接下来我们还需要对这一驱动进行验证,所以我们要基于此驱动设计一个简单的应用。

3.1、声明并初始化对象

使用基于对象的操作我们需要先得到这个对象,所以我们先要使用前面定义的SHT2X温湿度传感器对象类型声明一个SHT2X温湿度传感器对象变量,具体操作格式如下:

SHT2xObjectType sht2x;

声明了这个对象变量并不能立即使用,我们还需要使用驱动中定义的初始化函数对这个变量进行初始化。这个初始化函数所需要的输入参数如下:

SHT2xObjectType *shtSHT2X对象变量

SHT2xDPIType dpi,测量分辨率配置

SHT2xBatteryType endBat,电池结束状态配置

SHT2xHeaterType heater,加热器是否启用配置

SHT2xOTPType otp,是否加载OTP配置

SHT2xTransmit write,写操作指针

SHT2xReceive read,读操作指针

SHT2xDelayms delayms,毫秒延时指针

对于这些参数,对象变量我们已经定义了。所使用的测量分辨率配置、电池结束状态配置、加热器是否启用配置以及是否加载OTP配置均为枚举,根据实际情况选择就好了。主要的是我们需要定义几个函数,并将函数指针作为参数。这几个函数的类型如下:

/* 毫秒延时函数指针类型 */
typedef void (*SHT2xDelayms)(volatile uint32_t nTime);/* 发送数据函数指针类型 */
typedef void (*SHT2xTransmit)(struct SHT2xObject *sht,uint8_t *tData,uint16_t tSize);/* 接收数据函数指针类型 */
typedef void (*SHT2xReceive)(struct SHT2xObject *sht,uint8_t *rData,uint16_t rSize);

对于这几个函数我们根据样式定义就可以了,具体的操作可能与使用的硬件平台有关系。所以我们定义在STM32平台下使用硬件接口I2C收发器的函数。具体函数定义如下:

/*从SHT20接收数据*/
static void ReceiveFromSHT20(SHT2xObjectType *sht,uint8_t *rData,uint16_t rSize)
{HAL_I2C_Master_Receive(&sht2xi2c, sht->devAddress,rData, rSize, 1000);
}/*向SHT20传送数据*/
static void TransmitToSHT20(SHT2xObjectType *sht,uint8_t *tData,uint16_t tSize)
{HAL_I2C_Master_Transmit(&sht2xi2c,sht->devAddress,tData,tSize,1000);
}

对于延时函数我们可以采用各种方法实现。我们采用的STM32平台和HAL库则可以直接使用HAL_Delay()函数。于是我们可以调用初始化函数如下:

SHT2xInitialization(&sht2xSHT2x_DPI_RH12_T14SHT2x_End_HighSHT2xHEATERDISABLESHT2xOTPDISABLETransmitToSHT20ReceiveFromSHT20HAL_Delay);

在这里我们将SHT2x温湿度控制器对象变量初始化为:最高分辨率,在大于2.25V结束电池状态,不加载OTP,不使用加热器。

3.2、基于对象进行操作

我们定义了对象变量并使用初始化函数给其作了初始化。接着我们就来考虑操作这一对象获取我们想要的数据。我们在驱动中已经将获取数据并转换为相应的物理量值,接下来我们使用这一驱动开发我们的应用实例。

/* 获取SHT2x温适度数据 */
void GetSHT2xMeasureData(void)
{float humidity;float temperature;humidity=GetSHT2xHumidityValue(&sht2x,MEASURE_RH_COMMAND_NOHOST);temperature=GetSHT2xTemperatureValue(&sht2x,MEASURE_T_COMMAND_NOHOST);
}

这里我们设计了一个简单的应用,直接获取SHT2x温湿度传感器测量到的温湿度数据。

4、应用总结

因为SHT2x温湿度传感器采用的是标准I2C接口,所以在驱动设计中没有考虑硬件接口相关的内容。我们只专注于SHT2x温湿度传感器的配置与操作。所以在使用驱动程序时,无论是使用硬件I2C收发控制器还是使用GPIO模拟的软件收发控制都需要单独做相应的配置。

我们已经设计并实现了SHT2x温湿度传感器的驱动程序,也使用这一驱动程序实现了读取SHT2x温湿度传感器温度、湿度数据的简单应用。经我们测试所得到的结果是符合我们期望的,这也说明驱动程序的设计是成功的。

在使用驱动时还需注意,在做初始化配置时,对用户寄存器的写操作需注意不得变更预留位且相关的预留位的默认值以后可能会改变。因此,在进行任何写用户寄存器的操作之前,必须先读预留位的默认值。而且在初始化配置时,还要注意SHT2X OTP功能默认为禁止状态,且不推荐用户使用。

欢迎关注:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499360.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Modbus协议栈应用实例之二:Modbus RTU从站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们将使用协议栈实现一个Modbus RTU从站应用。 1、何为RTU从站 Modbus协议是一…

外设驱动库开发笔记11:SHT3x系列温湿度传感器驱动

在我们的产品中经常会遇到温湿度检测的需求。可以用于检测温湿度的传感器元件也有很多。我们经常使用的SHT各系列数字温湿度传感器来实现应用需求。在这里我们将设计并实现SHT3x系列温湿度传感器的驱动。 1、功能概述 SHT3x系列温湿度传感器是适用于各种应用的高品质湿度传感…

LwIP应用开发笔记之十:LwIP带操作系统基本移植

现在&#xff0c;TCP/IP协议的应用无处不在。随着物联网的火爆&#xff0c;嵌入式领域使用TCP/IP协议进行通讯也越来越广泛。在我们的相关产品中&#xff0c;也都有应用&#xff0c;所以我们结合应用实际对相关应用作相应的总结。 1、技术准备 我们采用的开发平台是STM32F407…

ThreadX应用开发笔记之一:移植ThreadX到STM32平台

现在一些小型系统中也往往有多任务处理的需求&#xff0c;这就为实时操作系统提供了用武之地。事实上国内外各种各样的RTOS有很多&#xff0c;而且基本都在走开源的路线&#xff0c;ThreadX也不例外&#xff0c;在这一篇中我们就来学习ThreadX初步应用并将其移植到STM32平台中。…

外设驱动库开发笔记12:TSEV01CL55红外温度传感器驱动

有时候我们需要检测一些无法直接接触的器件的温度。为了实现这一需求&#xff0c;我们通常会选择红外温度传感器来实现这一功能。考虑到复用的问题&#xff0c;我们一般会将操作元器件的代码抽象为驱动函数以备调用。这里我们就来设计并实现TSEV01CL55红外温度传感器的驱动。 …

FreeRTOS应用开发笔记之一:FreeRTOS在STM32的移植

FreeRTOS是如今在小型嵌入式领域应用比较广泛的一种实时操作系统。它是一种开源且免费的操作系统&#xff0c;而且移植和使用都非常的简单。在这里我们将学习并移植FreeRTOS。 1、必要的准备 工欲善其事&#xff0c;必先利其器&#xff0c;在开始学习和移植之前&#xff0c;相…

外设驱动库开发笔记13:MLX90614红外温度传感器驱动

红外温度传感器一般用于非接触式的温度检测。在我们的系统中经常会有这样的需求。所以我们将其设计为通用的驱动库以备复用。这一篇我们将讲述MLX90614红外温度传感器驱动的设计与实现。 1、功能概述 MLX90614是一种红外温度计&#xff0c;用于非接触式温度测量。红外测温是根…

Modbus协议栈应用实例之三:Modbus TCP客户端应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们将解说如何使用协议栈实现一个Modbus TCP客户端。 1、何为TCP客户端 Modbus…

Modbus协议栈应用实例之四:ModbusTCP服务器应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们来简述如何使用协议栈实现一个Modbus TCP服务器应用。 1、何为TCP服务器 Mo…

外设驱动库开发笔记14:DS18B20温度变送器驱动

在一时候我们需要相对简单的检测温度信号&#xff0c;而DS18B20就是一款功能和应用都相对简单的温度传感器&#xff0c;通过单线就可以实现检测温度信号的需求。这一篇我们就来实现操作DS18B20获取温度数据的驱动。 1、功能概述 DS18B20是常用的数字温度传感器&#xff0c;其…

Modbus协议栈应用实例之五:Modbus ASCII主站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们来使用协议栈实现Modbus ASCII主站应用。 1、何为ASCII主站 我们知道Modbus…

Modbus协议栈应用实例之六:Modbus ASCII从站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们来使用协议栈实现Modbus ASCII从站应用。 1、何为ASCII从站 我们知道Modbus…

外设驱动库开发笔记15:DHT11温湿度传感器驱动

与DS18B20一样DHT11也是采用单总线&#xff0c;但所不同的是DHT11可同时实现温度和湿度的检测。在我们的产品中经常使用它来检测环境的温湿度信息。这一篇我们将设计并封装DHT11的驱动程序&#xff0c;以方便重复使用。 1、功能概述 DHT11数字温湿度传感器是一款含有已校准数…

外设驱动库开发笔记16:MS5536C压力变送器驱动

压力检测也是经常会遇到的需求&#xff0c;比如环境压力或者低压气体等都会用到压力检测。这类检测压力都比较低&#xff0c;一般不会超过大气压&#xff0c;有时甚至是负压。这一篇我们要讨论的MS5536C就属于这类器件。接下来我们将设计并实现MS5536C的驱动。 1、功能概述 M…

外设驱动库开发笔记17:MS5803压力变送器驱动

很多时候我们需要检测被控对象的绝对压力&#xff0c;而且在我们的多款产品中也有这样的需求。当然检测绝对压力的传感器有很多&#xff0c;我们经常使用MS5803来实现压力检测。本篇中我们将设计并实现MS5803系列压力传感器的驱动。 1、功能概述 MS5803系列产品包含压阻传感器…

通讯接口应用笔记1:RS485通讯上下拉电阻的选择

RS485是一种常见的通讯接口方式&#xff0c;在我们的实际产品中也是多次使用。但我们平常并不会去过多考虑某一实现的细节问题&#xff0c;不过最近我们遇到了一个因如上下拉电阻的选择问题而造成的通讯故障&#xff0c;所以在这一片中我们来讨论一下RS485总线上下拉电阻的选择…

外设驱动库开发笔记18:MS5837压力变送器驱动

绝对压力的检测是常见的需求。在我们的系统中也常常会遇到。而MS5837压力传感器也是我们进场会采用的方案。在这篇里我们将讨论并实现MS5837压力传感器的驱动。 1、功能概述 MS5837压力传感器是一种可用于电路板上&#xff0c;适用于检测10-1200mbar压力范围的传感器&#xf…

外设驱动库开发笔记19:BMP280压力温度传感器驱动

压力和温度监测在嵌入式系统开发中是非常常见的需求&#xff0c;特别是对环境大气压力和温度的检测需求就更常见了。我们一般都会选择一些封装较小操作比较方便的压力传感器。BMP280就是满足这一要求的器件。在这一篇中我们将设计并实现BMP280的驱动。 1、功能概述 BMP280是一…

一个简单的空气质量数据监测站项目

大气质量数据监测站用于测试空气质量监测及数据采集&#xff0c;实现野外或者室内空气质量的检测。并通过网络将数据上传到OneNet​显示。​ 1、项目概述 本项目是一个定制项目&#xff0c;要求采集大气的压力、温度、湿度、PM25、位置等数据并上传到指定的后台服务器。但有时…

一个基于STM32实现的多组分气体分析仪项目

本篇将简要的总结一下一个基于STM32F412ZG实现的多组分气体分析仪的项目。简要描述该项目的软硬件设计及其验证。 一、项目概述 多组分气体分析仪是我公司近期研发的三个主要产品之一。采用模块化设计&#xff0c;可增减配置&#xff0c;可分析混合气体中的氧气、氢气、甲烷、…