开发环境:
IDE:MKD 5.38a
Renesas RA Smart Configurator:v5.1.0
开发板:RA-Eco-RA4M2
MCU:R7FA4M2AD3CFP
1 理论分析
2.1 HS3003介绍
HS3003是一款高精度的温湿度传感器,标准I2C格式。
HS3003配有一个全新设计的ASIC专用芯片、一个经过改进的MEMS半导体电容式湿度传感元件和一个标准的片上温度传感元件,其性能已经大大提升甚至超出了前一代传感器的可靠性水平,新一代温湿度传感器,经过改进使其在恶劣环境下的性能更稳定。
2.2 HS3003采集温湿度
温度湿度读取时序如下:

Figure 1‑1 HS3003读取时序
HS3003在睡眠模式下,传感器一直等待主机发送测量命令。CPU此时只执行温湿度测量指令,其余指令无法唤醒传感器进行数据采集。
主机发送采集命令后即可唤醒HS3003进行数据采集,启动采集只需要发送7位从机地址,第八位写0即可。
采集数据时,传感器内部的数字信号处理器会对采集到的温湿度数据进行计算,并且内部算法对数据进行校正运算:采集结束后,传感器的输出寄存器会将数据进行更新,
测量周期由湿度和温度转换后的数字信号处理器(DSP)校正计算。在测量周期结束时,数字电源关闭之前输出寄存器将被更新。测量数据以14位的输出,数据位以右对齐。
HS3003输出的真实的相对湿度(%)和温度(℃)数据通过以下公式进行计算。
相对湿度:

温度转换:

2 实验详解
2.1 实验目的
1) 通过实验掌握I2C的配置方法
2) 掌握温湿度传感器HS3003的原理与使用
2.2 实验设备
硬件:PC 机一台;RA-Eco-RA4M2开发板一套;HS3003模块一个
软件:Windows 10系统,Keil5集成开发环境、串口助手
2.3 实验相关电路图
HS3003模块相关电路如下图所示:

Figure 2‑1 HS3003模块相关电路图
根据可知HS300x Datasheet,HS3003的地址为0x44。本文将使用I2C0。
2.4 HS3003采集温湿度实现
2.4.1 RA Smart Configurator配置I2C
打开RA Smart Configurator,根据硬件连接,I2C使用的是IIC0,因此在配置界面里面依次打开“Pins->Peripherals->Connectivity:IIC>IIC0”配置IIC模块,选择开发板所用的IIC引脚,这里SCL和SDA分别接的是P400和P401引脚。
Figure 2‑2 I2C引脚设置
接下来就是添加I2C的stack。
Figure 2‑3 添加I2C的stack步骤
接下来需要配置I2C的参数。
Figure 2‑4 I2C参数设置
这里可以设置I2C的参数,我这里设置I2C的变量名、通道以及从机地址,I2C的编号和Channel编号是一一对应的,因此需要设置为3,回调函数依据C语言命名规范任意编译一个就行。
值得注意的是,这里的从机地址是7位,代码中自动左移了。
然后让软件自动生成配置代码即可。
2.4.2 HS3003采集温度代码实现
R_IIC_MASTER_Open()函数为执行IIC初始化,开启配置如下所示。
err =R_IIC_MASTER_Open(&g_i2c_master0_ctrl, &g_i2c_master0_cfg);
assert(FSP_SUCCESS == err);
R_IIC_MASTER_Write()函数是向IIC设备中写入数据,写入格式如下所示。
err = R_IIC_MASTER_Write(&g_i2c_device_ctrl_1, &g_i2c_tx_buffer[0], I2C_BUFFER_SIZE_BYTES, false);
assert(FSP_SUCCESS == err);
R_IIC_MASTER_Read()函数是向IIC设备中读数据,读数据的格式如下所示。
err = R_IIC_MASTER_Read(&g_i2c_device_ctrl_1, &g_i2c_rx_buffer[0], I2C_BUFFER_SIZE_BYTES, false);
assert(FSP_SUCCESS == err);
首先是HS3003的初始化,主要是打开I2C。
void BSP_HS3003_Init(void)
{
fsp_err_t err;
err = R_IIC_MASTER_Open(&g_i2c_master0_ctrl, &g_i2c_master0_cfg);
assert(FSP_SUCCESS == err);
}
然后就是温湿度读取。
fsp_err_t BSP_HS3003_Get_data(ST_HS3003_Data *HS3003_Data)
{
fsp_err_t err;
uint8_t r_buf[4] = {0};
uint16_t humi, temp;
uint8_t data = 0x00;
err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, &data, 1, true);
R_BSP_SoftwareDelay(50, BSP_DELAY_UNITS_MILLISECONDS);
err = R_IIC_MASTER_Read(&g_i2c_master0_ctrl, r_buf,4 , false);
R_BSP_SoftwareDelay(50, BSP_DELAY_UNITS_MILLISECONDS);
err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, &data, 1, true);
R_BSP_SoftwareDelay(50, BSP_DELAY_UNITS_MILLISECONDS);
err = R_IIC_MASTER_Read(&g_i2c_master0_ctrl, r_buf,4 , false);
if(err == FSP_SUCCESS)
{
if ((r_buf[0] & RM_HS300X_MASK_STATUS_0XC0) != RM_HS300X_DATA_STATUS_VALID)
{
printf("The conversion time is short\r\n");
}
humi = (uint16_t)((r_buf[0] & RM_HS300X_MASK_HUMIDITY_UPPER_0X3F) << 8 | r_buf[1]);
temp = (uint16_t)(r_buf[2] << 8 | (r_buf[3] & RM_HS300X_MASK_TEMPERATURE_LOWER_0XFC)) >> 2;
HS3003_Data->humi = ((float)humi * RM_HS300X_CALC_HUMD_VALUE_100) / RM_HS300X_CALC_STATIC_VALUE;
HS3003_Data->temp = (((float)temp * RM_HS300X_CALC_TEMP_C_VALUE_165) / RM_HS300X_CALC_STATIC_VALUE) - RM_HS300X_CALC_TEMP_C_VALUE_40;
R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS);
}
return err;
}
最后看下hal_entry()函数。
void hal_entry(void)
{
ST_HS3003_Data HS3003_Data;
fsp_err_t err;
SysTick_Init();
R_SCI_UART_Open (g_uart9.p_ctrl, g_uart9.p_cfg);
BSP_HS3003_Init();
while(1)
{
Delay_ms(500);
R_IOPORT_PinWrite(&g_ioport_ctrl, GPIO_LED1, BSP_IO_LEVEL_HIGH);
Delay_ms(500);
R_IOPORT_PinWrite(&g_ioport_ctrl, GPIO_LED1, BSP_IO_LEVEL_LOW);
err = BSP_HS3003_Get_data(&HS3003_Data);
if(err == FSP_SUCCESS)
{
printf("Humidity: %.2f%%\r\n",HS3003_Data.humi);
printf("Temperature: %.2f°C\r\n", HS3003_Data.temp);
}
else
{
printf("Read hs3003 data error\r\n");
}
}
#if BSP_TZ_SECURE_BUILD
R_BSP_NonSecureEnter();
#endif
}
2.5 实现现象
接上设备,串口打印信息如下:

Figure 2‑5 实验现象