STM32CubeMX——HTU21D温湿度传感器测温湿度

前言

高情已逐晓云空,不与梨花同梦。 ————苏轼《西江月·梅花


一、简介

HTU21温湿度传感器采用基于法国Humirel高性能的湿度感应元件制成,HTU21系列模块为OEM客户应用提供了准确可靠的温湿度测量数据。HTU21不仅输出方式多样化,工作电压范围比较宽,同时具有很高的温度精度和湿度精度。

HTU21D温湿度传感器可通过一个微控制器的接口和模块的连接达到温度和湿度的数字输出。HTU21D 的分辨率可以通过输入命令进行改变( 8/12bit 乃至 12/14bitRH/T ),传感器可以检测到电池低电量状态,并且输出校验和,有助于提高通信的可靠性。传感器输出经过标定的数字信号,标准 I2C 格式。

补充说明: OEMOriginal Equipment Manufacturer(原始设备制造商)之缩写,意为通常拥有充裕、廉价的劳动力,提供国际市场所需的制造、组装产品之委托服务的厂商,即代工厂。由制造方负责生产、提供人力和场地,采购方负责销售的一种现代流行生产方式。

  • 特点及应用:

传感器的特点 应用举例
完整的互换性,在标准环境下无需校准 家庭应用
长期处于湿度饱和状态,可以迅速恢复 医疗领域
自动组装工艺生产,无铅材料制成,适合回流焊 打印机
每个传感器具有单独标记,可追溯生产源头 加湿器
  • 性能规格:

STM32CubeMX——HTU21D温湿度传感器测温湿度_第1张图片

  • 电气特性和基本性能:(在 T = 25°C,Vdd = 3.3V下)

STM32CubeMX——HTU21D温湿度传感器测温湿度_第2张图片

  • 数据手册下载地址:温湿度敏感芯片传感器HTU21D

  • 传感器电路和引脚定义

    • 电路图:(包括上拉电阻 RPVDDGND 之间的去耦电容)
      STM32CubeMX——HTU21D温湿度传感器测温湿度_第3张图片
    • 引脚定义:
      STM32CubeMX——HTU21D温湿度传感器测温湿度_第4张图片

实物图:

  • 我所使用的下面这种更为简洁的温湿度传感器,相比之下去掉了两个 NC 引脚,可直接与STM32开发板连接;
    STM32CubeMX——HTU21D温湿度传感器测温湿度_第5张图片
  • 正面图:
    STM32CubeMX——HTU21D温湿度传感器测温湿度_第6张图片

二、引脚配置

这四个引脚分别为GND, VCC(+), SCL, SDA,具体的引脚已经在简介的图中标明了。

  • VCC:接电源正极 3.3~5V
  • GND:接地;
  • SCL(串行时钟输入)PB10 (I2C2_SCL)
  • SDA(船型数据端口)PB11 (I2C2_SDA)

接线表:

温湿度传感器的接口 STM32的IO口 设置的工作模式
VCC VCC(3.3V) -
GND GND -
SCL(串行时钟输入) PB10 I2C的时钟信号线
SDA(串行数据端口) PB11 I2C的数据信号线
- PA9 TX(USART1 串口1通信)
- PA10 RX(USART1 串口1通信)
  • 电源引脚 (VDD, GND)HTU21 的供电范围为 1.8VDC - 3.6VDC,推荐电压为 3.0V。电源(VDD)和接地(VSS)之间须连接一个0.1uF的去耦电容,且电容的位置应尽可能靠近传感器。
  • 串行时钟输入(SCL):SCL 用于微处理器与 HTU21D 之间的通讯同步。由于接口包含了完全静态逻辑,因而不存在最小 SCL 频率。
  • 串行数据 (DATA): DATA 引脚为三态结构,用于读取传感器数据。当向传感器发送命令时, DATASCK 上升沿有效且在 SCK 高电平时必须保持稳定。 DATASCK 下降沿之后改变。当从传感器读取数据时, DATASCK 变低以后有效,且维持到下一个 SCK 的下降沿。为避免信号冲突,微处理器应驱动 DATA 在低电平。需要一个外部的上拉电阻(例如: 10kΩ)将信号提拉至高电平。上拉电阻通常已包含在微处理器的 I/O 电路中。

三、STM32单片机与传感器的 “交流”

1. 启动传感器

将传感器上电,电压所选择的VDD电源电压(范围介于1.8V与3.6V之间),上电后,传感器最多需要15毫秒时间(此时SCL为高电平)用来达到空闲状态,即做好准备接收有主机(MCU)发送的命令(做好与MCU交流的准备)。

2. 启动信号

启动传输,发送一位数据,包括DATA线在SCK线高电平期间,出现一个向低电平的跳变。
STM32CubeMX——HTU21D温湿度传感器测温湿度_第7张图片

  • I2C总线传输数据过程中的三种类型信号:
    • 开始信号: SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。
    • 结束信号: SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。
    • 应答信号: 接收数据的 I2C 在接收到 8bit 数据后,向发送数据的 I2C 发出特定的低电平脉冲表示已收到数据。 CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU 接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。
  • 这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。
    STM32CubeMX——HTU21D温湿度传感器测温湿度_第8张图片

3. 停止信号

终止传输,停止发送数据时,包括DATA线在SCK线高电平期间,出现一个向高电平的跳变。
STM32CubeMX——HTU21D温湿度传感器测温湿度_第9张图片

4. I2C数据传输

SCL 时钟电平为低, 可以改换 SDA 数据线的电平,在 SCL 上升沿的过程将 SDA数据发送出去。SCL 为高电平时,SDA 上的数据保持稳定。
STM32CubeMX——HTU21D温湿度传感器测温湿度_第10张图片

5. HTU21D数据测量

  • 传感器命令表:

STM32CubeMX——HTU21D温湿度传感器测温湿度_第11张图片
STM32CubeMX——HTU21D温湿度传感器测温湿度_第12张图片

  • MCU与传感器之间的通讯方式有两种不同的工作方式:主机模式和非主机模式

    • 主机模式下:在测量过程中,SCL线被封锁(由传感器进行控制),
    • 非主机模式下:在测量过程中,SCL线依然保持开放状态,可进行其他通讯。

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

6. HTU21D数据读取与转换

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


四、新建工程

1.打开STM32CubeMX软件,点击“新建工程”

在这里插入图片描述

2. 选择 MCU 和封装

在这里插入图片描述

3.配置时钟

在这里插入图片描述
在这里插入图片描述
具体学习可以参考:博客网站-RCC学习

4.配置调试模式

5.串口(USART1)配置

在这里插入图片描述

6. I2C配置

STM32CubeMX——HTU21D温湿度传感器测温湿度_第14张图片

7.生成代码

输入项目名称和路径。(注:路径中不允许出现中文。)
在这里插入图片描述
选择应用的IDE,开发环境MDK-ARM V5
在这里插入图片描述
每个外设生成独立的 ’.c/.h’ 文件

  • 不勾: 所有初始化代码都生成在 main.c
  • 勾选: 初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。

    点击 GENERATE CODE 生成代码

8.构建工程

  • DeBug的模式根据不同的芯片进行选择:
    在这里插入图片描述

四、编写代码

main.c文件中,添加一下代码:

  • 重写fgetfput函数:勾选微库(这个很重要),添加头文件
    在这里插入图片描述
/* USER CODE BEGIN Includes */
#include
/* USER CODE END Includes */
/**
  * 函数功能: 重定向c库函数printf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}

  • 添加代码htu21d文件对(.c/.h):
  • htu21d.h
#ifndef __HTU21D_H_
#define __HTU21D_H_

#include "i2c.h"

//句柄定义
#define HTU21D_I2C hi2c2

//读写命令
#define HTU21D_WRITE_CMD	0x80
#define HTU21D_READ_CMD		0x81

//传感器命令
#define HTU21D_TRIGGER_T_M						0xe3		//触发温度测量(保持主机)         0xe3 = 1110 0011
#define HTU21D_TRIGGER_RH_M						0xe5		//触发相对湿度测量(保持主机)   0xe5 = 1110 0101
#define HTU21D_TRIGGER_T_NO_M					0xf3		//触发温度测量(非保持主机)     0xf3 = 1111 0011
#define HTU21D_TRIGGER_RH_NO_M 				    0xf5		//触发相对湿度测量(非保持主机) 0xf5 = 1111 0101 
#define	HTU21D_WRITE_USER_REGISTER		        0xe6		//写用户寄存器					 0xe6 = 1110 0110 
#define HTU21D_READ_USER_REGISTER			 	0xe7		//读用户寄存器					 0xe7 = 1110 0111 
#define HTU21D_SOFT_RESER						0xfe		//软复位						 0xfe = 1111 1110	



//HTU21D值结构体
typedef struct{
	float temperature;		//温度 
	float humidity;			//湿度 
}HTU21D_Value;


/*软件复位*/
void HTU21D_SoftReset(void);
/*读用户寄存器*/
uint8_t HTU21D_ReadUserReg(void);
/*读温度和湿度(无等待主控芯片)*/
float read_temperture(uint8_t cmd);
float read_humidity(uint8_t cmd);


#endif /*__HTU21D_H_*/

  • htu21d.c
#include "HTU21D.h"

static HTU21D_Value HTU21DValue;

/*外部函数*/

/*软件复位*/
void HTU21D_SoftReset(void)
{
	HAL_I2C_Master_Transmit(&HTU21D_I2C, HTU21D_WRITE_CMD<<1, (uint8_t *)HTU21D_SOFT_RESER, 1, 100);//发送软件复位
}

/*读用户寄存器*/
uint8_t HTU21D_ReadUserReg(void)
{
	uint8_t data=0;
	HAL_I2C_Master_Transmit(&HTU21D_I2C, HTU21D_WRITE_CMD<<1, (uint8_t *)HTU21D_READ_USER_REGISTER, 1, 100);//发送读用户寄存器指令
	
	HAL_I2C_Master_Receive(&HTU21D_I2C, HTU21D_WRITE_CMD<<1, &data, 1, 100);
	return data;
}

/*读温度和湿度*/
float read_temperture(uint8_t cmd)
{
	uint8_t data = cmd;
	uint8_t tempBuff[2];
	uint16_t temp1=0;
	
	HAL_I2C_Master_Transmit(&HTU21D_I2C, HTU21D_WRITE_CMD, &data, 1, 100);
	HAL_I2C_Master_Receive(&HTU21D_I2C, HTU21D_READ_CMD, tempBuff, 2, 100);
	
	temp1 = (uint16_t)tempBuff[0];
	temp1 <<= 8;
	
	temp1 |= tempBuff[1];
	
	HTU21DValue.temperature = -46.85 + 175.72*((float)temp1/(1<<16));		//数据手册温度转换公式
	
	return HTU21DValue.temperature;
}

float read_humidity(uint8_t cmd)
{
	uint8_t data = cmd;
	uint8_t humiBuff[2];
	
	uint16_t humi1=0;
	
	HAL_I2C_Master_Transmit(&HTU21D_I2C, HTU21D_WRITE_CMD, &data, 1, 100);
	HAL_I2C_Master_Receive(&HTU21D_I2C, HTU21D_READ_CMD, humiBuff, 2, 100);
	
	humi1 = (uint16_t)humiBuff[0];
	humi1 <<= 8;
	
	humi1 |= humiBuff[1];
	
	HTU21DValue.humidity = -6 + 125*((float)humi1/(1<<16));						//数据手册湿度转换公式
	
	return HTU21DValue.humidity;
}

  • 在主函数main.c中添加代码:
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  float temperture;	//接收温度
  float humidity;//接收湿度
  uint8_t cmd;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C2_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
    cmd = HTU21D_ReadUserReg();
    temperture = read_temperture(cmd);
    humidity = read_humidity(cmd);
    
    printf("读取当前环境状态:\r\n");
    printf("温度为:%f 摄氏度\r\n",temperture);
    printf("湿度:%f RH\r\n",humidity);
    printf("\n");
    
    HAL_Delay(10000);
  }
  /* USER CODE END 3 */
}

五、实验结果

STM32CubeMX——HTU21D温湿度传感器测温湿度_第15张图片

谢谢阅读!!!

在这里插入图片描述

你可能感兴趣的:(STM32模块学习,stm32,单片机,嵌入式硬件)