锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

STM32驱动 HTU21D温湿度传感器

时间:2023-09-02 01:07:01 返出传感器频率温湿度传感器

STM32驱动 HTU21D温湿度传感器

温湿度传感器模块HTU21D产品简介

基于法国Humirel由新一代制成的高性能湿度感应元件HTU21D温湿度传感器在尺寸和智能方面建立了新的标准:嵌入了适合回流焊的双列扁平无引脚DFN 封装, 底面3x3mm,高度1.1mm。传感器输出标准数字信号 I2C格式。输出方式多样,工作电压范围宽,温度精度和湿度精度高。HTU21系列模块专为低功耗小体积应用设计,质量好,响应速度快,抗干扰能力强,性价比高,体积小(3x3mm)、极低的功耗
HTU21D封装
数字输出温湿度传感器模块HTU21D重要的传感器参数
供电电压:1.5V—3.6V

湿度测量范围:0-100%RH

温度测量范围: -40℃—125℃

最大消耗功率: 2.7uW

通信方式:I2C

湿度精度范围(10%)RH to 95%RH): ±2%RH

湿度迟滞:±1%RH

测量时间:50ms

年漂移量:-0.5%RH/year

响应时间:5 s

main函数

/// 主函数     LED_GPIO_Config();   LED_BLUE;  //串口初始化  USART_Config();  //I2C初始化  i2c_Config();  printf("开始温湿度检测\n");  printf("\n");  while(1)  {   HTU21D_Display();  }   

部分地址封装

#define HTDU21D_ADDRESS     0x查询数据手册或查看时序图  HTDU21D_ADDRESS是7位地址1000000 #define SOFT_RESET                    0xFE//软件复位 #define NOHOLD_TEMP_MEASURE           0xF3//非主机模式下的温度测量 #define NOHOLD_HUMI_MEASURE           0xF5//非主机模式下湿度测量  #define HTDU21D_ADDRESS_WR    0x80//7位地址1000000 0写 #define HTDU21D_ADDRESS_RD        0x81//7位地址1000000 1读 

从外设指定的地址读取若干数据

/******************************************************* **函数   ReadBytes **功能   从外设指定的地址读取若干数据 **形参   Address 起始地址  **    Size  数据长度 **    *pReadBuf 缓冲区指针(用于存储读取的数据) **返回值   1、正常运行 **    0、运行异常 *******************************************************/  uint8_t ReadBytes(uint8_t *pReadBuf, uint16_t Address, uint16_t Size) {  uint16_t i;    /* 发起I2C总线启动信号 */  i2c_Start();    /* 发起控制字节,高7bit是地址,bit0是读写控制位,0表示写作,1表示读 */  i2c_SendByte(HTDU21D_ADDRESS | I2C_WR);      /*等待ACK */  if (i2c_WaitAck() != 0)  {   goto cmd_fail; /* 器件无应答 */  }   /* 发送字节地址 */  i2c_SendByte((uint8_t)Address);    /* 等待ACK */  if (i2c_WaitAck() != 0)  {   goto cmd_fail; /* 器件无应答 */  }    /*重新启动I2C总线。前代码的目的是将地址传输到外设,下面开始读取数据 */  i2c_Start();    /* 发起控制字节,高7bit是地址,bit0是读写控制位,0表示写作,1表示读 */  i2c_SendByte(HTDU21D_ADDRESS | I2C_RD); /* 这是阅读指令 */    /* 发送ACK */  if (i2c_WaitAck() != 0)  {   goto cmd_fail; /* 器件无应答 */  }     /*循环读取数据 */  for (i = 0; i < Size; i  )  {   pReadBuf[i] = i2c_ReadByte(); /* 读1个字节 */      /* 每读一个字节后,需要发送Ack, 不需要最后一个字节Ack,发Nack */   if (i != Size - 1)   {    i2c_Ack(); /* 读完中间字节后,CPU产生ACK信号(驱动SDA = 0) */   }   else   {    i2c_NAck(); /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */   }  }  /* 发送I2C总线停止信号 */  i2c_Stop();  return 1; /* 执行成功 */  cmd_fail: /* 命令执行失败后,记得发送停止信号,避免影响I2C其他总线设备 */  /* 发送I2C总线停止信号 */  i2c_Stop();  return 0; }  

向外设指定的地址处开始写入若干数据

/************************************************************************* **函数   WriteBytes                    **功能   向外设置指定的地址开始写入数据          **形参   Address   起始地址               **    Size   数据长度                **    *pWriteBuf  缓冲区指针(用于存储需要写入的数据)   **返回值   1、正常运行 **    0、运行异常 ***********************************************************************/  uint8_t WriteBytes(uint8_t *pWriteBuf, uint16_t Address, uint16_t Size) {  uint16_t i,m;  uint16_t Addr;  uint8_t PAGE_SIZE=8;    /*    写串行EEPROM与阅读操作不同,许多字节可以连续阅读,每次写作操作只能在同一个字节中page。   对于24xx02,page size = 8   简单的处理方法是:按字节写操作模式,不写字节,发送地址   为提高连续写作效率: 本函数采用page wirte操作。  */   Addr = Address;   for (i = 0; i < Size; i  )  {   /* 当发送第一个字节或页面的第一个地址时,启动信号和地址需要重启 */   if ((i == 0) || (Addr & (PAGE_SIZE - 1)) == 0)   {    /* 第0步:发送停止信号,启动内部写作操作 */    i2c_Stop();        /* 判断内部写作操作是否通过检查器件响应来完成, 一般小于 10ms         CLK频率为200KHz时,查询次数约为30次    */    for (m = 0; m < 1000; m  )    {         /* 第1步:发起I2C总线启动信号 */     i2c_Start();          /* 第二步:启动控制字节,高7bit是地址,bit0是读写控制位,0表示写作,1表示读 */     i2c_SendByte(HTDU21D_ADDRESS | I2C_WR); /* 这是写指令 */          /* 第三步:发送一个时钟,判断器件是否正确响应 */     if (i2c_WaitAck() == 0)     {      break;     }    }    if (m  == 1000)    {     goto cmd_fail; /* EEPROM器件写超时 */    }       /* 第4步:发送字节地址,24C02只有256字节,所以一个字节就够了,如果是24C04以上,这里需要连发多个地址 */    i2c_SendByte((uint8_t)Addr);        /* 第5步:等待ACK */    if (i2c_WaitAck() != 0)    {     goto cmd_fail; /* EEPROM器件无应答 */    }   }     /* 第六步:开始写入数据 */   i2c_SendByte(pWriteBuf[i]);      /* 第7步:发送ACK */   if (i2c_WaitAck() != 0)   {    goto cmd_fail; /* EEPROM器件无应答 */   }    Addr  ; /* 地址增1 */    }    /* 成功执行命令,发送I2C总线停止信号 */  i2c_Stop();  return 1;  cmd_fail: /* 命令执行失败后切记发送停止信号,避免影响I2C总线上其他设备 */
	/* 发送I2C总线停止信号 */
	i2c_Stop();
	return 0;
}

获取温湿度数据

/*************************************************
**函数名称 : float Htu_Measure(uint8_t order
**功    能 : htu21d测量温湿度
**参    数 : order:测量触发命令
**返 回 值 : temp--温度值  humi--湿度值
*************************************************/
float Htu_Measure(uint8_t _ucOrder)
 {
	 uint8_t ucMsb,ucLsb;
	 volatile float f_Temp,f_Humi,f_RetVal;
	 
	 i2c_Start();
	 i2c_SendByte(HTDU21D_ADDRESS_WR);		//地址+写命令
	 
	 i2c_WaitAck();
// 	 if(i2c_WaitAck()==0)
//		 printf("3应答\n");
//   else
//		 printf("3不应答\n");
	 
	 SysTick_Delay_ms(4);	
	 i2c_SendByte(_ucOrder);		//触发测量命令
	
	 i2c_WaitAck();

// 	 if(i2c_WaitAck()==0)
//		 printf("4应答\n");
//	 else printf("4不应答\n");
	 
	 
	 do{
		 SysTick_Delay_ms(5);
		 i2c_Start();
		 i2c_SendByte(HTDU21D_ADDRESS_RD);		//地址+读命令
	 }while(i2c_WaitAck() == 1);
	 
	 ucMsb = i2c_ReadByte();
	 i2c_Ack();
	 SysTick_Delay_ms(5);
	 ucLsb = i2c_ReadByte();
	 i2c_Ack();
	 SysTick_Delay_ms(5);
	 i2c_NAck();
	 i2c_Stop();
	 
	 ucLsb &= 0xfc;		//设置分辨率,最低两位为0,温度:14位;湿度:12位 	
	 f_RetVal = ucMsb * 256 + ucLsb;/*MSB=(MSB<<=8)+LSB;即将MSB移位到高8位*/
	 
	 if(_ucOrder == NOHOLD_TEMP_MEASURE)
	 {
		 f_Temp = (175.72)*f_RetVal/65536-46.85;//温度:T= -46.85 + 175.72 * ST/2^16
		 return f_Temp;
	 }
	 else if(_ucOrder == NOHOLD_HUMI_MEASURE)
	 {
		 f_Humi = (f_RetVal*125)/65536-6;//湿度: RH%= -6 + 125 * SRH/2^16
		 return f_Humi;
	 }
	 else
		 return 0;
} 

测试展示

参考:

  1. STM32 驱动温湿度传感器 HTU21D
  2. 野火I2C相关视频
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章