读取HS3003温度传感器的数据
支持I2C接口的传感器种类有很多,本文对使用STM32U5的I2C读取HS3003温湿度传感器的数据进行介绍。
1.硬件配置
HS3003传感器模块的原理图如图所示。
开发板与传感器器模块的接线图如图所示。
2.软件编写
首先,在STM32 CubeIDE中创建开发板的工程,选择根据开发板创建工程,
在CubeMX界面中会自动初始化开发板上的部分外设,比如串口、调试口、LED等,本文通过I2C1控制传感器,使用的PB8和PB9,选择对应管脚的复用功能,并在I2C的配置界面选择相应的I2C通讯参数。
完成上述操作后,保存配置并生成相应的外设初始化代码。
通过查看数据手册可知,传感器的从机地址为0x44。
由于STM32 HAL接口的实现问题,在传入从机地址时,需要将第8位的读写控制位作为从机地址作为函数的参数传入。相关的宏定义如下
HS3003默认状态位睡眠模式。在睡眠模式下,在进行测量前,传感器等待从主机发送过来的指令。当传感器接收到测量请求指令后,数字核进行数模转换,否则,传感器处于关机状态。
主机通过发送7位从机地址和第八位写标记来启动测量请求。
这里的表述表示测量请求时,I2C发出的数据长度为零,只包含从机地址和写标志位。按照上述要求发出控制指令后,传感器会进行一次ADC数据转换,转换结果会存放在数据寄存器中。
使用数据抓取指令,可以从传感器获取转换后的湿度和温度数据。读取数据操作的各字节数据的含义如下图所示,其中除了温湿度数据外,在传感返回的第一字节的高两位表示数据是否被读取。
传感器中的指定几个寄存器可以用于配置传感器的湿度分辨率和温度分辨率,在修改其中的配置参数前,需要控制传感器进入编程模式。设置其进入编程模式的指令如下。
修改测量分辨率的操作,根据数据手册中的说明,进入编程模式后,读取指定寄存器中数据,然后根据需要修改相应的数据位,将数据写入寄存器中。
读取到的ADC数据值根据下图中的公式进行转换,得到可读的温湿度数据。
基于上述从数据手册得到的信息,可以编写以下几个函数。
首先是基本的读取和写入指定寄存器
uint32_t Humiture_HS3003_readRegister32(uint8_t reg_address) {
uint32_t value;
uint8_t data[4];
/* Read data from I2C slave */
if (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)HS300X_ADR_R, (uint8_t *)data, 0x04,10000) != HAL_OK)
{
/* Error_Handler() function is called when error occurs. */
Error_Handler();
}
/*##- Wait for the end of the transfer #################################*/
/* Before starting a new communication transfer, you need to check the current
state of the peripheral; if it�s busy you need to wait for the end of current
transfer before starting a new one.
For simplicity reasons, this example is just waiting till the end of the
transfer, but application may perform other tasks while transfer operation
is ongoing. */
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
{
}
value=data[0];
value<<=8;
value|=data[1];
value<<=8;
value|=data[2];
value<<=8;
value|=data[3];
return value;
}
void Humiture_HS3003_writeRegister( uint8_t reg_address, uint8_t *buffer, uint8_t len)
{
if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)HS300X_ADR_W, buffer, len,10000) != HAL_OK)
{
/* Error_Handler() function is called when error occurs. */
Error_Handler();
}
/*##- Wait for the end of the transfer #################################*/
/* Before starting a new communication transfer, you need to check the current
state of the peripheral; if it�s busy you need to wait for the end of current
transfer before starting a new one.
For simplicity reasons, this example is just waiting till the end of the
transfer, but application may perform other tasks while transfer operation
is ongoing. */
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
{
}
}
接下来是初始化传感器和读取温湿度传感器数据的函数。
void Humiture_HS3003_init(void)
{
Humiture_HS3003_writeRegister(HS300X_ADR,NULL,0);
}
//读取原始的数据
uint32_t Humiture_HS3003_ReadData_Raw(uint8_t resolution )
{
uint32_t data=0;
Humiture_HS3003_init();//唤醒
//8bit->1.2ms
//10bit->2.72ms
//12bit->9.10ms
//14bit->33.90ms
if(resolution==8)
HAL_Delay(1200);
else if(resolution==10)
HAL_Delay(2720);
else if(resolution==12)
HAL_Delay(9100);
else
HAL_Delay(34);
data=Humiture_HS3003_readRegister32(HS300X_ADR);
return data;
}
在主函数中,对读取到的传感器数据按照上图中计算公式进行转换,得到相应的可读温湿度数据。
/* USER CODE BEGIN 2 */
Humiture_HS3003_init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_Delay(1000);
Data=Humiture_HS3003_ReadData_Raw(14);
Temp = (float)( (Data & 0xFFFF) >> 2);//只要低十六位
Temp = Temp*HS300X_TEMP_MULTY*165-40;//HS300X_TEMP_MULTY->0.00006163516(1/(2^14-1) )
Humidity = (float)( (Data >> 16) &0x3FFF );//只要高十六位,且最高2位不要
Humidity = Humidity*HS300X_HUMD_MULTY*100;//HS300X_HUMD_MULTY->0.00006163516(1/(2^14-1) )
printf("temp is %f,humidity is %f\r\n",Temp,Humidity);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
输出的温湿度数据如下。
3.总结
传感器的数据读取在低功耗应用很广泛,这里和大家分享HS3003的使用方法。
|