【杰发科技AC7802x测评】11.硬件IIC读取HS3003温湿度传感器数据

1 HS3003介绍

HS3003是瑞萨的一款温湿度传感器,基于IIC通信,采用7为地址,地址为0x44。

1.1 原理图

 



可见,只能使用IIC通信,因为AC7802X只有一路IIC,之前用来驱动OLED,所以将HS3003X也接到了这路IIC上,因为OLED和HS3003的地址不一样,所以可以同时驱动。

硬件连接如下:

- SCL - PB7
- SDA - PB8

1.2 HS3003操作方式

虽然知道了HS300X是IIC接口,但是我们还不知道该如何操作,需要了解HS300X的操作方式,寄存器,IIC地址等,查看官方提供的手册《REN_HS300x-Datasheet_DST_20210809.pdf》。

1.2.1 测量请求

直接通过IIC总线写HS300X地址就可以唤醒传感器自动采集数据,说明见下:

> 从下图中可以看到IIC地址为0x44,然后加一个低位1表示写。

 



1.2.2 数据获取

从下图可以看出,发送HS300X地址+低位读就可以获取采集的数据。
**注:重点说明,默认采样精度为14bit,可以通过配置修改,精度越高,采样时间越长,下图中有说明,默认精度下的采样时间为33ms左右,所以在测量请求发出之后,需要等待33毫秒之后在读取。**

 



采集数据分析,从图中可以清楚看出,默认温度和湿度数据都为14bit数据,都占用了两个字节。

其中湿度的高两位为状态为状态位,表示采集数据状态是否有效,见下图:

- 0表示数据采集完成
- 1表示没有完成有效采集。
- 温度的低两位没有任何用处。

 



1.2.3 采样精度修改

采样精度可以修改,精度越低,采样时间越快。可以通过下述寄存器进行修改,该部分本文不会实现,只作为功能描述其有这个功能。
修改方式也很简单,IIC地址+低位写0+修改精度寄存器地址+精度即可完成修改,详情参考数据手册。

 



1.2.4 采样数据处理

采集到的数据为原始数据,需要进行计算得出真实的温湿度数据,计算公式如下:

 



即:
湿度值(%):采样值/(16383) * 100
温度值(摄氏度):采样值/(16383) * 165 - 40


2 软件编写

知道了硬件设置以及原理,现在可以看是编写软件了,如下:
app_hs3003.c
 

复制
/*

@hehung

2023-6-30

email: 1398660197@qq.com

wechat: hehung95

reproduced and please indicate the source @hehung

*/





#include "app_hs3003.h"

#include "app_hw_i2c.h"







#define HS300x_I2C_SLAVE_ADDR_7BIT           (0x44U)



#define HS300X_DATA_VALID                    (0x00U)

#define HS300X_DATA_STALE                    (0x01U)

#define HS300X_STATUS_MASK                   (0xC0000000U)

#define HS300X_STATUS_POS                    (30U)



#define HS300X_DATA_MASK                     (0x3FFFFFFCU)

#define HS300X_HUMI_DATA_MASK                (0x3FFF0000U)

#define HS300X_HUMI_DATA_POS                 (16U)

#define HS300X_TEMP_DATA_MASK                (0x0000FFFCU)

#define HS300X_TEMP_DATA_POS                 (2U)



/* calculation formula, 2^14 - 1 */

#define HS300X_DATA_FACTOR                   (16383U)







static uint8_t Hs300x_DataConvert(uint32_t read_data, s_Hs300xDataType *cal_result);







static uint8_t Hs300x_DataConvert(uint32_t read_data, s_Hs300xDataType *cal_result)

{

    uint32_t humi_data;

    uint32_t temp_data;



    if (((read_data & HS300X_STATUS_MASK) >> HS300X_STATUS_POS) == HS300X_DATA_VALID)

    {

        // Data is valid

        humi_data = (read_data & HS300X_HUMI_DATA_MASK) >> HS300X_HUMI_DATA_POS;

        temp_data = (read_data & HS300X_TEMP_DATA_MASK) >> HS300X_TEMP_DATA_POS;



        // Calculate the humidity: humi_data/(2^14-1) * 100

        cal_result->humi = (double)humi_data/(double)(HS300X_DATA_FACTOR) * 100.0;

        // Calculate the temperature: temp_data/(2^14-1) * 165 - 40

        cal_result->temp = (double)temp_data/(double)(HS300X_DATA_FACTOR) * 165.0 - 40;

#ifdef HS300X_DEBUG

        printf("humidity:%f, temperature:%f\n", cal_result->humi, cal_result->temp);

#endif

    

        return 1;

    }

    else

    {

        return 0;

    }

}



void Hs300x_Init(void)

{

    // Do not settings, keep default settings in sensor device

}



void Hs300x_StartSample(void)

{

    uint8_t data = 0;



    // Only send the address to start HS300X convert

    I2C_MasterTransmitPoll(I2C0, HS300x_I2C_SLAVE_ADDR_7BIT, &data, 0, ENABLE);

}



s_Hs300xDataType Hs300x_ReadData(void)

{

    uint8_t data[4];  // one address + 4bytes data

    uint32_t data_u32;

    s_Hs300xDataType humi_temp;



//  Read measurement from sensor HS300X

    I2C_MasterReceivePoll(I2C0, HS300x_I2C_SLAVE_ADDR_7BIT, data, 4);

    // Convert the data to 32bit

    data_u32 = (uint32_t)((data[0] << 24U) | 

                          (data[1] << 16U) | 

                          (data[2] << 8U) | 

                          (data[3]));

    // Read the temperature and hunidity

    (void)Hs300x_DataConvert(data_u32, &humi_temp);



//#ifdef HS300X_DEBUG

    printf ("HS300X origin data1:%x%x%x%x\r\n", data[0],data[1],data[2],data[3]);

    // printf("HS300X origin data2:%x\n", data_u32);

    printf ("Temp:%f--Humi:%f\r\n", humi_temp.temp, humi_temp.humi);

//#endif



    return humi_temp;

}






app_hs3003.h

/*

@hehung

2023-6-30

email: 1398660197@qq.com

wechat: hehung95

reproduced and please indicate the source @hehung

*/



#ifndef APP_HS3003_H__

#define APP_HS3003_H__







typedef struct 

{

    double humi;

    double temp;

} s_Hs300xDataType;



extern void Hs300x_Init(void);

extern s_Hs300xDataType Hs300x_ReadData(void);

extern void Hs300x_StartSample(void);





#endif


主函数实现如下,其中40ms的延时是必须的。
 

        Hs300x_StartSample();

        mdelay(40);

        Hs300x_ReadData();

        mdelay(1000);


如下,将手放到传感器上,影响传感器采集数据,温湿度都有所增加。
 

---------------------
作者:hehung
链接:https://bbs.21ic.com/icview-3312082-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。 

以下是一份基于STM32的硬件IIC读取湿度传感器的代码示例: ```c #include "main.h" #include "i2c.h" #define HTU21D_ADDRESS 0x80 // HTU21D传感器地址 // HTU21D传感器命令 #define HTU21D_TRIGGER_TEMP_HOLD 0xE3 #define HTU21D_TRIGGER_HUMI_HOLD 0xE5 #define HTU21D_READ_TEMP_HOLD 0xE0 #define HTU21D_READ_HUMI_HOLD 0xE0 uint8_t i2c_buffer[4]; // I2C接收数据缓存 /** * @brief 读取HTU21D传感器数据 * @return 度值,单位:0.01℃ */ uint16_t HTU21D_Read_Temperature(void) { uint16_t temperature = 0; // 发送度测量命令 i2c_buffer[0] = HTU21D_TRIGGER_TEMP_HOLD; HAL_I2C_Master_Transmit(&hi2c1, HTU21D_ADDRESS, i2c_buffer, 1, 1000); // 等待传感器测量完成 HAL_Delay(50); // 读取数据 HAL_I2C_Master_Receive(&hi2c1, HTU21D_ADDRESS, i2c_buffer, 3, 1000); // 计算度值 temperature = ((uint16_t)i2c_buffer[0] << 8) | (uint16_t)i2c_buffer[1]; temperature &= 0xFFFC; // 数据的最后两位为小数位,需要清零 temperature = (uint16_t)((float)temperature * 175.72 / 65536.0 - 46.85) * 100; return temperature; } /** * @brief 读取HTU21D传感器湿度数据 * @return 湿度值,单位:0.01% */ uint16_t HTU21D_Read_Humidity(void) { uint16_t humidity = 0; // 发送湿度测量命令 i2c_buffer[0] = HTU21D_TRIGGER_HUMI_HOLD; HAL_I2C_Master_Transmit(&hi2c1, HTU21D_ADDRESS, i2c_buffer, 1, 1000); // 等待传感器测量完成 HAL_Delay(50); // 读取湿度数据 HAL_I2C_Master_Receive(&hi2c1, HTU21D_ADDRESS, i2c_buffer, 3, 1000); // 计算湿度值 humidity = ((uint16_t)i2c_buffer[0] << 8) | (uint16_t)i2c_buffer[1]; humidity &= 0xFFFC; // 湿度数据的最后两位为小数位,需要清零 humidity = (uint16_t)((float)humidity * 125.0 / 65536.0 - 6.0) * 100; return humidity; } ``` 需要注意的是,以上代码中的`hi2c1`变量为`I2C_HandleTypeDef`类型,需要在`main.c`文件中定义并初始化。此外,还需要在`main.c`文件中调用`MX_I2C1_Init()`函数初始化I2C接口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值