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 实验结果如下
如下,将手放到传感器上,影响传感器采集数据,温湿度都有所增加。
|