STM32驱动 HTU21D温湿度传感器
STM32驱动 HTU21D温湿度传感器
温湿度传感器模块HTU21D产品简介
基于法国Humirel公司高性能的湿度感应元件制成,新一代HTU21D温度和湿度传感器在尺寸与智能方面建立了新的标准:它嵌入了适于回流焊的双列扁平无引脚DFN 封装, 底面3x3mm,高度1.1mm。传感器输出经过标定的数字信号,标准 I2C格式。多样化的输出方式,宽的工作电压范围,同时具有很高的温度精度和湿度精度。HTU21系列模块专为低功耗小体积应用设计,具有良好的品质、快的响应速度、抗干扰能力强、性价比高等优点,微小的体积(3x3mm)、极低的功耗
数字输出温湿度传感器模块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 0x40//查询数据手册或者看时序图得到 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个字节 */
/* 每读完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
简单的处理方法为:按字节写操作模式,没写1个字节,都发送地址
为了提高连续写的效率: 本函数采用page wirte操作。
*/
Addr = Address;
for (i = 0; i < Size; i++)
{
/* 当发送第1个字节或是页面首地址时,需要重新发起启动信号和地址 */
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();
/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
i2c_SendByte(HTDU21D_ADDRESS | I2C_WR); /* 此处是写指令 */
/* 第3步:发送一个时钟,判断器件是否正确应答 */
if (i2c_WaitAck() == 0)
{
break;
}
}
if (m == 1000)
{
goto cmd_fail; /* EEPROM器件写超时 */
}
/* 第4步:发送字节地址,24C02只有256字节,因此1个字节就够了,如果是24C04以上,那么此处需要连发多个地址 */
i2c_SendByte((uint8_t)Addr);
/* 第5步:等待ACK */
if (i2c_WaitAck() != 0)
{
goto cmd_fail; /* EEPROM器件无应答 */
}
}
/* 第6步:开始写入数据 */
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;
}
测试展示
参考:
posted on 2024-08-21 17:18 naive156 阅读(80) 评论(0) 编辑 收藏 举报 来源
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用