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

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

1、功能概述

SHT3x系列温湿度传感器是适用于各种应用的高品质湿度传感器。SHT3x温湿度传感器系列结合了多种功能和各种接口适合各类应用。

1.1、硬件描述

SHT3x建立在全新和优化的CMOSens®芯片之上,进一步提高了产品可靠性和精度规格。SHT3x提供了一系列新功能,如增强信号处理、两个独特和用户可选I2C地址、一个可编程温湿度极限的报警模式,以及高达1 MHz的通信速度。SHT3x系列温湿度传感器的引脚排布及说明如下图所示:

SHT3x系列温湿度传感器适用于2.155.5 V的宽电源电压范围。电源插脚必须与一个100nf电容解耦,该电容应尽可能靠近传感器。

SCLSDA线都是开放式I/O,带有到VDDVSS的二极管。它们应该连接到外部上拉电阻。I2C总线上的设备必须只驱动线路到地面。外部上拉电阻必须把信号高。上拉电阻可能包括在微控制器的I/O电路中。SHT3x系列温湿度传感器接线方式如下图:

SCL用于同步微控制器与传感器之间的通信。时钟频率可以自由选择在01000千赫之间。支持根据I2C标准伸缩时钟的命令。SDA引脚用于在传感器之间传输数据。频率高达400khz的通信必须满足I2C快速模式标准。

1.2、信息通讯

SHT3x系列温湿度传感器支持I2C快速模式(频率高达1000千赫)。可以通过适当的用户命令启用和禁用时钟拉伸。

向传感器发送一个命令后,传感器需要最少等待1ms的时间才能接收到另一个命令。所有SHT3x命令和数据都映射到16位地址空间。此外,数据和命令由CRC校验和保护。这增加了通信的可靠性。传感器的16位命令已经包含一个3CRC校验和。传感器发送和接收的数据总是由一个8CRC来完成。在写方向上,必须传输校验和,因为SHT3x只接受后面跟着正确校验和的数据。在读取方向上,由主程序读取和处理校验和。

SHT3x系列温湿度传感器可以通过ADDR引脚设置设备的通讯地址。请注意,I2C地址是通过I2C读写头的7msb表示的,LSB在读写操作之间切换。具体的地址如下:

1.3、数据转换

测量数据总是以16位无符号整数的形式传输。这些值已经线性化,并补偿了温度和电源电压的影响。可以使用简单的公式将这些原始值转换为物理量值。相对湿度换算公式(结果为%RH)

温度转换公式(结果为摄氏度和华氏度)

SRHST分别表示原始传感器输出的湿度和温度。只有当SRHST用十进制表示时,这些公式才能正确工作。

2、驱动设计与实现

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

2.1、对象定义

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

2.1.1、对象的抽象

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

先来考虑属性,作为属性肯定是用于标识或记录对象特征的东西。我们来考虑SHT3x系列温湿度传感器对象属性。作为一个I2C总线设备,设备地址用于标识设备在总线上的唯一性,所以我们将设备地址作为SHT3x对象的一个属性。对于每一个SHT3x设备都有一个电子标识码,它是标识SHT3x设备个体的东西,所以我们将其作为SHT3x对象的属性。此外,温湿度的当前值标识了当前的状态我们将其作为两个属性。还有SHT3x的状态寄存器也是记录SHT3x配置及工作状态的,所以我们也将其作为SHT3x对象的属性。

接着我们还需要考虑SHT3x系列温湿度传感器对象的操作问题。作为数字通讯设备,我们向其发送数据和从其接收数据都是必要,但接收与发送数据依赖于所处的硬件平台,所以我们将发送数据与接收数据作为SHT3x对象的两个操作。基于时序操作的需要,在通讯过程中需要作延时处理,但如何实现延时依赖于具体的硬件平台,所以我们也将延时处理作为SHT3x对象的一个操作。

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

/* 定义SHT3x对象类型 */
typedef struct SHT3xObject{uint8_t devAddress;           // SHT3x对象的地址SHT3xStatusRegister status;          // SHT3x状态及存期的值uint32_t serialNumber;        // SHT3x对象的序列号float temperature;float humidity;void (*Delayms)(volatile uint32_t nTime);       //延时操作指针void (*Receive)(uint8_t devAddress,uint8_t *rData,uint16_t rSize);    //接收数据操作指针void (*Transmit)(uint8_t devAddress,uint8_t *tData,uint16_t tSize);   //发送数据操作指针
}SHT3xObjectType;

2.1.2、对象初始化

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

/* SHT3x对象初始化 */
SHT3xErrorType SHT3xInitialization(SHT3xObjectType *sht,uint8_t address,SHT3xTransmit transmit,SHT3xReceive receive,SHT3xDelayms delayms){SHT3xErrorType error=SHT3X_NO_ERROR;if((sht==NULL)||(transmit==NULL)||(receive==NULL)||(delayms==NULL)){return SHT3X_PARM_ERROR;}sht->Transmit=transmit;sht->Receive=receive;sht->Delayms=delayms;sht->temperature=0.0;sht->humidity=0.0;if((address==0x44)||(address==0x45)){sht->devAddress=(address<<1);}else if((address==0x88)||(address==0x8A)){sht->devAddress=address;}else{sht->devAddress=0;error|=SHT3X_PARM_ERROR;}sht->status.word=0;error|=SHT3xReadStatusRegister(sht);if(error==SHT3X_NO_ERROR){error|=SHT3xReadSerialNumber(sht);}return error;
}

2.2、对象操作

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

2.2.1、单次测量

SHT3X温湿度传感器有一种单次测量模式。这种模式只按我们规定的方式运行一次,测量通信序列由一个启动条件、I2C写标头和一个16位测量命令组成。在传感器完成测量后,通过发送一个START条件和一个I2C读标头,主控可以读取测量结果。具体的格式如下:

根据这一单次数据测量并读取的流程图,我们可以很方便的得到单次读取SHT3X温湿度传感器数据的程序。

/* 获取一次性采集 */
SHT3xErrorType SHT3xGetSingleShotData(SHT3xObjectType *sht,SHT3xRepeatability repeatability,SHT3xMode mode)
{SHT3xErrorType error=SHT3X_NO_ERROR;uint8_t data[6];uint16_t tempCode;uint16_t humiCode;SHT3xCommands commands[2][3]={{CMD_MEAS_CLOCKSTR_H,  // 单次数据采集模式,时钟延展,高重复性CMD_MEAS_CLOCKSTR_M,  // 单次数据采集模式,时钟延展,中重复性CMD_MEAS_CLOCKSTR_L,  // 单次数据采集模式,时钟延展,低重复性},{CMD_MEAS_POLLING_H,   // 单次数据采集模式,轮询,高重复性CMD_MEAS_POLLING_M,   // 单次数据采集模式,轮询,中重复性CMD_MEAS_POLLING_L,   // 单次数据采集模式,轮询,低重复性}};SHT3xWriteCommand(sht,commands[mode][repeatability]);if(mode==MODE_CLKSTRETCH){sht->Delayms(1);}else if(mode==MODE_POLLING){sht->Delayms(20);}sht->Receive(sht,data,6);error|=CheckCRC8ForSHT3x(&data[0],2,data[2]);error|=CheckCRC8ForSHT3x(&data[3],2,data[5]);if(error==SHT3X_NO_ERROR){tempCode=(data[0]<<8)+data[1];humiCode=(data[3]<<8)+data[4];sht->temperature=CalcTemperatureValue(tempCode);sht->humidity=CalcHumidityValue(humiCode);}return error;
}

2.2.2、周期测量

SHT3X温湿度传感器还有一种周期性检测数据的方式。这种方式先将SHT3X温湿度传感器配置为周期获取模式。在这一模式下就可以周期获取数据了。周期获取数据的格式如下图:

根据上述周期读取数据的字节顺序图我们可以编写周期获取的程序如下:

/* 读取周期性采集的数据 */
SHT3xErrorType SHT3xFetchPeriodicMeasurmentData(SHT3xObjectType *sht)
{SHT3xErrorType error=SHT3X_NO_ERROR;uint8_t data[6];uint16_t tempCode;uint16_t humiCode;SHT3xWriteCommand(sht,CMD_FETCH_DATA);sht->Delayms(1);sht->Receive(sht,data,6);error|=CheckCRC8ForSHT3x(&data[0],2,data[2]);error|=CheckCRC8ForSHT3x(&data[3],2,data[5]);if(error==SHT3X_NO_ERROR){tempCode=(data[0]<<8)+data[1];humiCode=(data[3]<<8)+data[4];sht->temperature=CalcTemperatureValue(tempCode);sht->humidity=CalcHumidityValue(humiCode);}return error;
}

2.2.3、系统复位

对于SHT3X来说系统复位包括的内容比较多,有接口复位、软件复位、广播复位和硬件复位引脚复位。这里我们需要考虑的主要是软件复位,其操作方式如下图:

根据上图我们可以很轻松的实现软件复位操作。

2.2.4、内部加热器

SHT3x配备了内部加热器,但仅用于可靠性检查。加热器可以通过命令开关,控温范围大约在几度范围之内。其状态可在状态寄存器中查看,默认加热器是关闭。器操作命令如下:

但是不建议操作加热器。

2.2.5、状态寄存器

状态寄存器包含有关加热器运行状态、警报模式以及最后一个命令的执行状态和最后一个写序列的信息。读取状态寄存器的命令如下所示:

状态寄存器的第1511104位等是我们关系比较多的,这些报警标志位可以通过命令清楚。根据上述数据字节流图我们可以得到读状态寄存器的函数如下:

/* 读取状态寄存器的值 */
SHT3xErrorType SHT3xReadStatusRegister(SHT3xObjectType *sht,SHT3xStatusRegister *status)
{SHT3xErrorType error=SHT3X_NO_ERROR;uint8_t sta[3];SHT3xWriteCommand(sht,CMD_READ_STATUS);sht->Delayms(1);sht->Receive(sht,sta,3);error|=CheckCRC8ForSHT3x(&sta[0],2,sta[2]);if(error==SHT3X_NO_ERROR){status->word=(sta[0]<<8)+sta[1];}else{status->word=0;}return error;
}

3、驱动的使用

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

3.1、声明并初始化对象

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

SHT3xObjectType sht3x;

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

SHT3xObjectType *sht,待初始化的SHT3X

uint8_t address,设备地址

SHT3xReceive receive,接收数据函数指针

SHT3xTransmit transmit,发送数据函数指针

SHT3xDelayms delayms,毫秒延时函数指针

对于这些参数,对象变量我们已经定义了。设备地址则根据实际的使用地址输入即可。主要的是我们需要定义几个函数,并将函数指针作为参数。这几个函数的类型如下:

/* 毫秒延时函数指针类型 */
typedef void (*SHT3xDelayms)(volatile uint32_t nTime);/* 接收数据函数指针类型 */
typedef void (*SHT3xReceive)(SHT3xObjectType *sht,uint8_t *rData,uint16_t rSize);/* 发送数据函数指针类型 */
typedef void (*SHT3xTransmit)(SHT3xObjectType *sht,uint8_t *tData,uint16_t tSize);

对于这几个函数我们根据样式定义就可以了,具体的操作可能与使用的硬件平台有关系。我们的应用基于STM32F4平台实现,接下来将基于我们的平台实现这些函数。具体函数定义如下:

/*从SHT3X接收数据*/
static void ReceiveFromSHT3x(SHT3xObjectType *sht,uint8_t *rData,uint16_t rSize)
{HAL_I2C_Master_Receive(&sht3xi2c, sht->devAddress,rData, rSize, 1000);
}/*向SHT3X传送数据*/
static void TransmitToSHT3x(SHT3xObjectType *sht,uint8_t *tData,uint16_t tSize)
{HAL_I2C_Master_Transmit(&sht3xi2c,sht->devAddress,tData,tSize,1000);
}

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

SHT3xInitialization(&sht3x0x88TransmitToSHT3xReceiveFromSHT3xHAL_Delay);

其中0x88为设备地址。

3.2、基于对象进行操作

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

/*获取温湿度计数据*/
void SHT3xMeasureData(void)
{float humidity;float temperature;SHT3xErrorType error=SHT3X_NO_ERROR;SHT3xStatusRegister status;error|=SHT3xReadStatusRegister(&sht3x,&status);if(error!=SHT3X_NO_ERROR){return ;}if(status.bit.ResetDetected){SHT3xClearStatusRegister(&sht3x);SHT3xStartPeriodicMeasurment(&sht3x,REPEATAB_HIGH,FREQUENCY_1HZ);}error|=SHT3xFetchPeriodicMeasurmentData(&sht3x);if(error==SHT3X_NO_ERROR){temperature=sht3x.temperature;humidity=sht3x.humidity;}
}

4、应用总结

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

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

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

欢迎关注:

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

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

相关文章

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;可分析混合气体中的氧气、氢气、甲烷、…

外设驱动库开发笔记20:BME280压力湿度温度传感器驱动

嵌入式产品开发中&#xff0c;我们常常会有检测环境温度、压力、湿度的需求。如果有一个集成有这3个传感器的元件&#xff0c;无疑将是很方便的。博世的BME280就能实现这一要求。在这一篇中我们将讨论BME280的驱动设计与实现。 1、功能概述 BME280是一款专为移动应用而开发的…

外设驱动库开发笔记21:BME680环境传感器驱动

环境传感器是一类我们很常用的传感器。它可以方便我们获取压力、温度、湿度以及空气质量等数据。在这一篇中&#xff0c;我们将分析BME680环境传感器的功能&#xff0c;并设计和实现BME680环境传感器的驱动。 1、功能概述 BME680是一款专为移动应用和可穿戴设备开发的集成环境…