温湿度传感器在嵌入式开发中应用场景非常多。本文主要利用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、基本命令集

命令 释义 代码 十六进制
触发 T 测量 保持主机 1110’0011 0XE3(主机模式)
触发 RH 测量 保持主机 1110’0101 0XE5(主机模式)
触发 T 测量 非保持主机 1111’0011 0XF3(非主机模式)
触发 RH 测量 非保持主机 1111’0101 0XF5(非主机模式)
写用户寄存器 1110’0110 0XE6
读用户寄存器 1110’0111 0XE7
软复位 1111’1110 0XFE

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);
}

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

  1. 【STM32】HAL库 STM32CubeMX教程十五---FMC-SDRAM(一)

    前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 本文 1首先讲解什么是FMC及SDRAM,W9825G6KH芯片原理,2基于CubeMx创建工程 ...

  2. 【STM32】HAL库 STM32CubeMX教程十四---SPI

    前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 在我们的HAL库中,对硬件SPI函数做了很好的集成,使得之前SPI几百行代码,在HAL库中,只需 ...

  3. stm32 ADC hal库实现

    stm32 ADC hal库实现 1.ADC的作用 (1)简介: ADC(Analog-to-Digital Converter),即模拟-数字转换器,可以将连续变化的模拟信号转换为离散的数字信号,进 ...

  4. STM32的HAL库分析及使用

    STM32的三种开发方式 通常新手在入门STM32的时候,首先都要先选择一种要用的开发方式,不同的开发方式会导致你编程的架构是完全不一样的.一般大多数都会选用标准库和HAL库,而极少部分人会通过直接配 ...

  5. STM32之HAL库详解 及 手动移植

    转载出处:http://blog.csdn.net/zcshoucsdn/article/details/55213616 HAL库结构   说到STM32的HAL库,就不得不提STM32CubeMX ...

  6. 正点原子STM32(基于HAL库)0

    目录 开发环境搭建与使用 常用开发工具简介 MDK 安装 仿真器驱动安装 CH340 USB 虚拟串口驱动安装 使用MDK5 编译例程 使用串口下载程序 使用DAP 下载与调试程序 使用DAP 下载程 ...

  7. STM32CubeMX | 基于STM32使用HAL库实现USB组合设备之多路CDC

    STM32CubeMX | 基于STM32使用HAL库实现USB组合设备之多路CDC 本博客完整代码下载地址:https://download.csdn.net/download/qq15347150 ...

  8. 正点原子STM32(基于HAL库)5

    目录 SRAM 实验 存储器简介 SRAM 方案简介 硬件设计 程序设计 程序流程图 程序解析 下载验证 内存管理实验 内存管理简介 硬件设计 程序设计 程序流程图 程序解析 下载验证 SD 卡实验 ...

  9. 【STM32】HAL库 STM32CubeMX教程十五---FMC-SDRAM(二)

    前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 上一讲我们说了CubeMX配置SDRAM的一些基本配置,还有FMC跟SDRAM的讲解,这一讲我们 ...

最新文章

  1. oracle 64位客户端_oracle的管理工具toad如何设置命令补全
  2. 如何从 dump 文件中提取出 C# 源代码?
  3. java离职交接文档_财务人员工作交接你知道么?没处理好不止将来风险大还可能违法...
  4. vscode输入vue自动_使用vscode,新建.vue文件,tab自动生成vue代码模板
  5. 【linux指令】sed指令
  6. lol游戏挂机软件_直男玩家吐槽LOL手游:挂机,送头,队友菜
  7. orcale物化视图刷新
  8. 自己动手写操作系统(高清图书+源代码)分享
  9. 微信公众开发java教程_[Java教程]微信公众平台开发(一)
  10. php 扫描条形码,将条形码扫描仪集成到PHP应用程序中?
  11. 手机微信连不上wifi服务器怎么回事,微信连不上wifi怎么办?
  12. SQL1005N 数据库别名 ECM 已存在于本地数据库目录或系统数据库目录中。
  13. 明大推荐系统导论笔记 week 2
  14. LeetCode算法解析之“箭爆气球问题”
  15. 平板为何无法用无线网连接媒体服务器,我家装了无线路由器后,台式机老是断网但是平板电脑却能连接无线网络上网...
  16. Fllutter TabBar中文文字抖动完美解决方案
  17. ssm毕设项目磐基建筑机械租赁有限公司机械租赁系统41c32(java+VUE+Mybatis+Maven+Mysql+sprnig)
  18. MySQL审核神器Inception
  19. 事务(Transaction)的特性
  20. tensorflow2.0学习经历:建立一个多元函数拟合模型并移植到ESP32(Arduino IDE)

热门文章

  1. 静态时序分析—虚拟时钟(virtual clock)与I/O延时约束
  2. 【android-自定义键盘的设置】
  3. python 列表的中括号[]与冒号:的作用
  4. Android 集成Chrome 浏览器内核 Crosswalk
  5. 学习IPPS库的编码部分知识点记录
  6. 信息技术课python培训心得
  7. 【物联网专题】物联网IoT相关学习与输出
  8. SuperMap iClient3D for WebGL沿线飞行飞行(二)
  9. django mysql 教程_Django 入门教程
  10. Python和Stata的数据交互