100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > STM32使用HAL库编写SHT2x温湿度传感器驱动

STM32使用HAL库编写SHT2x温湿度传感器驱动

时间:2022-12-06 14:13:43

相关推荐

STM32使用HAL库编写SHT2x温湿度传感器驱动

温湿度传感器在嵌入式开发中应用场景非常多。本文主要利用STM32及HAL库完成SHT2x温湿度传感器温湿度值得读取及将值通过串口打印出来。

一、SHT20芯片芯片介绍

1、官方收据手册可以该网站下载:数字温湿度传感器 SHT2X-深圳市森思德克科技有限公司

该网站提供的手册为英文的,该芯片使用较多,通过百度也能找到中文的。

2、SHT20 配有一个全新设计的 CMOSens®芯片、一 个经过改进的电容式湿度传感元件和一个标准的能 隙温度传感元件。(这段摘自数据手册)

二、芯片技术手册读到可能对后续编程有用的信息

1、该芯片采用数字输出,I2C接口,低功耗。

2、SHT20的分辨率可以通过输入命令进行改变(8/12bit乃至12/14bit的RH/T)。RH代表湿度,T代表温度。

3、默认测量分辨率14bit(温度)/12bit(湿度),可通过寄存器发送命令将其减少到12/8bit,11/11bit,13/10bit。

4、温湿度测量频率过高,传感器自身温度会升高而影响精度。

5、接口定义

6、传感器通讯流程如下

(1)启动传感器:将传感器上电后,传感器最多需要15毫秒时间(此时SCL为高电平)以达到空闲状态,即做好准备接收由主机MCU发送的命令。

(2)启动/停止时序:参照标准I2C总线。

(3)在启动传输后,随后传输的I2C首字节应包括7位的I2C设备地址和一个SDA方向位(读:1,写:0)。等待应答后,发送温度或湿度的测量命令。

(4)传感器地址由厂商写死的,I2C 设备地址( 地址‘1000’000’)和一个 SDA

方向位(读 R: ‘1’,写 W: ‘0’)。

7、基本命令集

8、主机/非主机模式

(1)MCU与传感器之间的通讯有两种不同的工作方式:主机模式或非主机模式。

(2)在主机模式下,在测量过程中,SCL线被封锁(由传感器进行控制)。在非主机模式下,当传感器执行测量任务时,SCL线仍然保持开放状态,可进行其他通讯。非主机模式允许传感器进行测量时在总线上处理其他I2C总线通讯任务。

(3)在主机模式测量时,SHT2x将SCL拉低强制主机进入等待状态。通过释放SCL线,表示传感器内部处理工作结束,进而可以继续数据传送。

第一步:发送起始信号→

第二步:发送传感器写地址→

第三步骤:等待传感器应答→

第四步:发送测量信号命令→

第五步骤:等待传感器应答→

第六步:发送起始信号→

第七步:发送传感器读地址→

第八步:等待传感器应答→

第九步:测量期间保持(延时一会)→

第十步:接收数据高八位,主机发送应答→

第十一步:接收数据低八位,主机发送应答→

第十二步:接收校验码值→主机发送NACK、P(传输停止时序)。

由于测量的最大分辨率为14位,第二字节SDA上的后两位(bit43和bit44)用来传输相关的状态信息。

后两位即LSB Stat简称 LSBs 。两个LSBs中的bit1表明测量的类型('0':温度, '1':湿度)。bit0位当前没有赋值。(这点非主机模式也是这种)

(4)在非主机模式时,MCU需要对传感器状态进行查询。主机发送一个启动传输时序,之后发送读地址( 1000’0001)。如果内部处理工作完成,单片机查询到传感器发出的确认信号后,相关的数据就可以通过MCU进行读取。如果测量处理工作没有完成,传感器无确认位(ACK)输出,此时必须重新发送启动传输时序。

9、软复位

三、I2C代码

1、头文件

#ifndef __DRV_SHT2x_I2C_H#define __DRV_SHT2x_I2C_H/*头文件包含*/#include "drv_gpio.h"#include "drv_i2c.h" /*包含uS级延时函数*//*宏定义*//*置位与清零SCL管脚*/#define __SHT2X_I2C_SCL_H() HAL_GPIO_WritePin(SHT_SCL_GPIO_Port,SHT_SCL_Pin,GPIO_PIN_SET) #define __SHT2X_I2C_SCL_L() HAL_GPIO_WritePin(SHT_SCL_GPIO_Port,SHT_SCL_Pin,GPIO_PIN_RESET)/*置位与清零SDA管脚*/#define __SHT2X_I2C_SDA_H() HAL_GPIO_WritePin(SHT_SDA_GPIO_Port,SHT_SDA_Pin,GPIO_PIN_SET) #define __SHT2X_I2C_SDA_L() HAL_GPIO_WritePin(SHT_SDA_GPIO_Port,SHT_SDA_Pin,GPIO_PIN_RESET)/*读取SDA管脚状态*/#define __SHT2X_READ_I2C_SDA() HAL_GPIO_ReadPin(SHT_SDA_GPIO_Port,SHT_SDA_Pin)/*读取SCL管脚状态*/#define __SHT2X_READ_I2C_SCL() HAL_GPIO_ReadPin(SHT_SCL_GPIO_Port,SHT_SCL_Pin)/*设置SDA管脚为输出模式*/#define __SHT2X_I2C_SDA_OUT()SHT_SDA_OutputMode()/*设置SDA管脚为输入模式*/#define __SHT2X_I2C_SDA_INPUT() SHT_SDA_InputMode()/*函数声明*/void SHT_SDA_OutputMode();/*设置SHT_SDA管脚为输出模式*/void SHT_SDA_InputMode(void); /*设置SHT_SDA管脚为输入模式*/void SHT2X_I2C_Init(void);/*SHT_SDA和SHT_SCL引脚电平初始化*/void SHT2X_I2C_Start(void); /*sht2x_I2C总线起始信号时序*/void SHT2X_I2C_Stop(void);/*sht2x_I2C总线停止信号时序*/uint8_t SHT2X_I2C_Wait_Ack(void);/*IIC等待应答信号,1接收应答失败,0接收应答成功*/void SHT2X_I2C_Ack(void); /*IIC产生应答*/void SHT2X_I2C_NAck(void);/*IIC不产生应答*/void SHT2X_I2C_Write_Byte(uint8_t Byte);/*SHT2X_I2C总线写字节时序*/uint8_t SHT2X_I2C_Read_Byte(I2C_ACK_TypeDef AckValue);/*SHT2X_I2C总线读字节时序*/#endif

2、C文件

#include "drv_sht2x_i2c.h"/**功能:设置SHT_SDA管脚为输出模式*参数:无*返回值:无*/void SHT_SDA_OutputMode(){GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = SHT_SDA_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; /*输出模式*/GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);}/**功能:设置SHT_SDA管脚为输入模式*参数:无*返回值:无*/void SHT_SDA_InputMode(void){GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = SHT_SDA_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;/*输入模式*/GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);}/**功能:SHT_SDA和SHT_SCL引脚电平初始化*参数:无*返回值:无*测试:OK*/void SHT2X_I2C_Init(void){__SHT2X_I2C_SCL_H();__SHT2X_I2C_SDA_H();HAL_Delay(15); /*延时15mS*/}/**功能:sht2x_I2C总线起始信号时序*参数:无*返回值:无*注意:开始状态是由主机控制的一种特殊总线状态,指示从机传输开始(Start之后,BUS总线一般被认为处于占线状态)*/void SHT2X_I2C_Start(void){__SHT2X_I2C_SDA_OUT();/*SDA配置为输出模式*//*SCL为高电平,SDA的下降沿为I2C起始信号*/__SHT2X_I2C_SDA_H();__SHT2X_I2C_SCL_H();I2C_Delay_us(20);__SHT2X_I2C_SDA_L();I2C_Delay_us(20);__SHT2X_I2C_SCL_L();}/**功能:sht2x_I2C总线停止信号时序*参数:无*返回值:无*注意:停止状态是由主机控制的一种特殊的总线状态,指示从机传输结束(Stop之后,BUS总线一般被认为处于空闲状态)*/void SHT2X_I2C_Stop(void){__SHT2X_I2C_SDA_OUT();/*SCL为高电平,SDA的上升沿为I2C停止信号*/__SHT2X_I2C_SDA_L();__SHT2X_I2C_SCL_H();I2C_Delay_us(1);I2C_Delay_us(10);__SHT2X_I2C_SDA_H();}/**功能:IIC等待应答信号*参数:无*返回值:1接收应答失败,0接收应答成功*/uint8_t SHT2X_I2C_Wait_Ack(void){uint8_t ucErrTime = 0;SHT_SDA_InputMode(); __SHT2X_I2C_SDA_H();I2C_Delay_us(10);__SHT2X_I2C_SCL_H();I2C_Delay_us(10);while(__SHT2X_READ_I2C_SDA()){ucErrTime++;if(ucErrTime > 250){SHT2X_I2C_Stop();return NACK;}}__SHT2X_I2C_SCL_L(); return ACK;}/**功能:IIC产生应答*/void SHT2X_I2C_Ack(void){__SHT2X_I2C_SCL_L();__SHT2X_I2C_SDA_OUT();__SHT2X_I2C_SDA_L();I2C_Delay_us(20);__SHT2X_I2C_SCL_H();I2C_Delay_us(20);__SHT2X_I2C_SCL_L();}/**功能:IIC不产生应答*/void SHT2X_I2C_NAck(void){__SHT2X_I2C_SCL_L();__SHT2X_I2C_SDA_OUT();__SHT2X_I2C_SDA_H();I2C_Delay_us(20);__SHT2X_I2C_SCL_H();I2C_Delay_us(20);__SHT2X_I2C_SCL_L();}/**功能:SHT2X_I2C总线写字节时序*参数:Byte:写入的内容*测试:OK*/void SHT2X_I2C_Write_Byte(uint8_t Byte){__SHT2X_I2C_SDA_OUT(); /*SDA配置为输出模式*//*SCL为低电平时,SDA准备数据,接着SCL为高电平,读取SDA数据*/for (uint8_t i = 0; i < 8; i++){/*SCL清零,主机SDA准备数据*/__SHT2X_I2C_SCL_L();I2C_Delay_us(1);if((Byte & (1 << 7)) == (1 << 7)){__SHT2X_I2C_SDA_H();}else{__SHT2X_I2C_SDA_L();}I2C_Delay_us(1);/*SCL置高,传输数据*/__SHT2X_I2C_SCL_H();I2C_Delay_us(10);/*准备发送下一比特位*/Byte <<= 1;}__SHT2X_I2C_SCL_L();}/**功能:SHT2X_I2C总线读字节时序*参数:*返回值:读取到的数据*测试:OK*/uint8_t SHT2X_I2C_Read_Byte(I2C_ACK_TypeDef AckValue){uint8_t byte = 0;__SHT2X_I2C_SDA_INPUT();/*SCL为低电平时,SDA准备数据,接着SCL为高电平,读取SDA数据*/for (uint8_t i = 0; i < 8; i++){/*准备接收下一比特位*/byte <<= 1;/*SCL清零,从机SDA准备数据*/__SHT2X_I2C_SCL_L();I2C_Delay_us(10);/*SCL置高,获取数据*/__SHT2X_I2C_SCL_H();I2C_Delay_us(10);byte |= __SHT2X_READ_I2C_SDA();}/*SCL清零,主机准备应答信号*/__SHT2X_I2C_SCL_L();I2C_Delay_us(1);__SHT2X_I2C_SDA_OUT();/*主机发送应答信号*/if(AckValue == ACK){__SHT2X_I2C_SDA_L();}else{__SHT2X_I2C_SDA_H();}I2C_Delay_us(1);__SHT2X_I2C_SCL_H(); I2C_Delay_us(10);/*SCL先清零,再释放SDA,防止连续传输数据时,从机错将SDA释放信号当成NACk信号*/__SHT2X_I2C_SCL_L();__SHT2X_I2C_SDA_H(); I2C_Delay_us(1);/*返回数据*/return byte;}

四、SHT2x代码

1、头文件

#ifndef __SHT2_H#define __SHT2_H/*头文件包含*/#include "main.h"/*宏定义*/#define SHT2x_ADDR_READ 0x81 /*传感器i2C读地址*/#define SHT2x_ADDR_WRITE 0x80 /*传感器I2C写地址*//*测量信号的选择*/typedef enum{HUMIDITY,/*选择湿度*/TEMP /*选择温度*/}etSHT2xMeasureType; /* *功能:传感器命令 *TRIG:触发(trigger) *MEASUREMENT:测量*HM:hold master*/typedef enum{/*主机模式*/TRIG_T_MEASUREMENT_HM = 0xE3, /*触发温度测量,主机模式*/TRIG_RH_MEASUREMENT_HM = 0xE5, /*触发湿度测量,主机模式*//*非主机模式*/TRIG_T_MEASUREMENT_POLL = 0xF3, /*触发温度测量,非保持主机*/TRIG_RH_MEASUREMENT_POLL = 0xF5, /*触发湿度测量,非保持主机*/USER_REG_W= 0xE6, /*command writing user register(写用户寄存器)*/USER_REG_R= 0xE7, /*command reading user register(读用户寄存器)*/SOFT_RESET= 0xFE /*command soft reset(软件复位)*/}etSHT2xCommand;/*函数声明*/ float SHT2x_MeasurePoll(etSHT2xMeasureType SHT2xMeasureType);/*非主机模式采集温度或湿度*/#endif

2、C文件

/**文件:SHT2x.c *功能:温湿度采集程序*//*头文件包含*/ #include "SHT2x.h"#include "drv_uart.h"#include "drv_sht2x_i2c.h"/**功能:非主机模式采集温度或湿度*参数:SHT2xMeasureType:需要采集的项,HUMIDITY湿度 TEMP温度*返回值:读到的温湿度值*/float SHT2x_MeasurePoll(etSHT2xMeasureType SHT2xMeasureType){float temp; /*临时变量*/unsigned char MSB,LSB; /*存储测量值的高八位和低八位*/float Humidity,Temperature;SHT2X_I2C_Start(); /*sht2x_I2C总线起始信号时序*/SHT2X_I2C_Write_Byte(SHT2x_ADDR_WRITE); /*sht2x_I2C总线写传感器写地址*/if(SHT2X_I2C_Wait_Ack() == ACK) /*写写地址等待应答*/ {switch(SHT2xMeasureType){ case HUMIDITY: /*湿度*/ SHT2X_I2C_Write_Byte(TRIG_RH_MEASUREMENT_POLL);/*非主机模式测湿度命令*/ break; case TEMP: /*温度*/ SHT2X_I2C_Write_Byte(TRIG_T_MEASUREMENT_POLL);/*非主机模式测温度命令*/break; default: printf("Tip: SHT2x_MeasurePoll function error.\r\n");break;}if(SHT2X_I2C_Wait_Ack() == 0)/*非主机模式测温湿度指令应答*/ {HAL_Delay(85); /*延时等待测量完成*/SHT2X_I2C_Start(); SHT2X_I2C_Write_Byte(SHT2x_ADDR_READ); /*sht2x_I2C总线写传感器读地址*/if(SHT2X_I2C_Wait_Ack() == 0) /*写读地址等待应答*/{MSB = SHT2X_I2C_Read_Byte(ACK);LSB = SHT2X_I2C_Read_Byte(ACK);SHT2X_I2C_Read_Byte(NACK); SHT2X_I2C_Stop();LSB &= 0xfc;temp = MSB*256 + LSB;if (SHT2xMeasureType == HUMIDITY){Humidity =(temp*125)/65536-6;//printf("Humidity = %.2f\r\n",Humidity);return Humidity;} else{ Temperature = (temp*175.72)/65536-46.85;//printf("Temperature = %.2f\r\n",Temperature);return Temperature; }}}}printf("Tip: SHT2x_MeasurePoll error\r\n");return 0XFF;/*表示出错了*/}

五、测试

float Humidity,Temperature; //定义温度和湿度变量while (1){/*Test*/Temperature = SHT2x_MeasurePoll(TEMP); /*非主机模式采集温度*/printf("Temperature%.2f\r\n",Temperature);Humidity = SHT2x_MeasurePoll(HUMIDITY); /*非主机模式采集湿度*/printf("Humidity = %.2f\r\n",Humidity);HAL_Delay(1000);}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。