打印
[活动专区]

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

[复制链接]
1143|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hehung|  楼主 | 2023-7-1 10:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
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);



3 实验结果如下

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





使用特权

评论回复

相关帖子

沙发
louliana| | 2023-7-6 12:10 | 只看该作者
学习I2C总线通信协议              

使用特权

评论回复
板凳
sesefadou| | 2023-7-6 15:11 | 只看该作者
使用单片机中的IIC接口读取温湿度传感器的数据,可以通过读取IIC总线上的数据来实现

使用特权

评论回复
地板
minzisc| | 2023-7-6 15:17 | 只看该作者
I2C硬件的操作函数在哪查找的              

使用特权

评论回复
评论
hehung 2023-7-8 19:20 回复TA
官方提供的i2c库里就可以找到 
5
rosemoore| | 2023-7-6 15:37 | 只看该作者
硬件I2C 到底怎么样?               

使用特权

评论回复
评论
hehung 2023-7-8 19:21 回复TA
AC7802X的硬件I2C还是很好用的,使用简单方便,通信速度可以打打400K 
6
vivilyly| | 2023-7-6 15:47 | 只看该作者
模拟的iic时序读取数据的时候错误,有什么办法防止

使用特权

评论回复
评论
hehung 2023-7-8 19:22 回复TA
可能是时间延时不太对,硬件IIC很好用,用硬件就可以 
7
minzisc| | 2023-7-6 16:00 | 只看该作者
硬件IIC怎么接收不同字节的长度的数据

使用特权

评论回复
评论
hehung 2023-7-8 19:23 回复TA
I2C_MasterReceivePoll(I2C0, HS300x_I2C_SLAVE_ADDR_7BIT, data, 4); 这个函数的最后一个参数就是长度 
8
10299823| | 2023-7-6 16:45 | 只看该作者
为啥硬件实现时读数据0xFF               

使用特权

评论回复
评论
hehung 2023-7-8 19:24 回复TA
可能是通信不对,查一下从机地址是不是对的 
9
adolphcocker| | 2023-7-6 16:54 | 只看该作者
为什么不使用DS18B20呢              

使用特权

评论回复
评论
hehung 2023-7-8 19:24 回复TA
手头有什么用什么,哈哈哈,没有DS18B20 
10
uptown| | 2023-7-6 17:05 | 只看该作者
硬件i2c读取一次HS3003数据大概多长时间

使用特权

评论回复
评论
hehung 2023-7-8 19:26 回复TA
没具体测试过,和I2c通信速度有关,也和从机的响应速度有关我设置的400K,还是很快的。但是HS3003发送了启动信号之后,需要等待33ms之后再读取数据,转换是需要时间的 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

66

帖子

1

粉丝