增加I2C 使用SHT40温湿度传感器上传TCP客户端数据
This commit is contained in:
243
app/sht40.c
Normal file
243
app/sht40.c
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* SHT40 温湿度传感器驱动
|
||||
* 功能:通过I2C1读取SHT40传感器的温湿度数据
|
||||
* 依赖:STM32 HAL库
|
||||
* 跨平台:仅适用于STM32F4系列,使用HAL库的I2C接口
|
||||
*/
|
||||
|
||||
#include "sht40.h"
|
||||
#include "board.h"
|
||||
#include "osal.h"
|
||||
|
||||
/* 外部I2C句柄 */
|
||||
extern I2C_HandleTypeDef hi2c1;
|
||||
|
||||
/* CRC校验函数 */
|
||||
static uint8_t sht40_crc8(const uint8_t *data, uint8_t len)
|
||||
{
|
||||
const uint8_t POLYNOMIAL = 0x31;
|
||||
uint8_t crc = 0xFF;
|
||||
|
||||
for (uint8_t i = 0; i < len; i++)
|
||||
{
|
||||
crc ^= data[i];
|
||||
for (uint8_t j = 0; j < 8; j++)
|
||||
{
|
||||
if (crc & 0x80)
|
||||
{
|
||||
crc = (crc << 1) ^ POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化SHT40传感器
|
||||
* @return 0成功,-1失败
|
||||
*/
|
||||
int sht40_init(void)
|
||||
{
|
||||
return sht40_reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 重置SHT40传感器
|
||||
* @return 0成功,-1失败
|
||||
*/
|
||||
int sht40_reset(void)
|
||||
{
|
||||
uint8_t cmd = SHT40_CMD_RESET;
|
||||
osal_log_i("SHT40: Sending reset command 0x%02X", cmd);
|
||||
if (HAL_I2C_Master_Transmit(&hi2c1, SHT40_I2C_ADDR << 1, &cmd, 1, 1000) != HAL_OK)
|
||||
{
|
||||
osal_log_e("SHT40 reset failed");
|
||||
return -1;
|
||||
}
|
||||
osal_thread_mdelay(1); // 重置需要<1ms
|
||||
osal_log_i("SHT40: Reset successful");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 读取SHT40传感器的序列号
|
||||
* @param serial 序列号(4字节)
|
||||
* @return 0成功,-1失败
|
||||
*/
|
||||
int sht40_read_serial(uint32_t *serial)
|
||||
{
|
||||
uint8_t cmd = SHT40_CMD_READ_SERIAL;
|
||||
uint8_t data[6];
|
||||
|
||||
//osal_log_i("SHT40: Sending read serial command 0x%02X", cmd);
|
||||
if (HAL_I2C_Master_Transmit(&hi2c1, SHT40_I2C_ADDR << 1, &cmd, 1, 1000) != HAL_OK)
|
||||
{
|
||||
osal_log_e("SHT40 send read serial command failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
osal_thread_mdelay(1);
|
||||
|
||||
if (HAL_I2C_Master_Receive(&hi2c1, SHT40_I2C_ADDR << 1, data, 6, 1000) != HAL_OK)
|
||||
{
|
||||
osal_log_e("SHT40 read serial data failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 校验数据 */
|
||||
if (sht40_crc8(&data[0], 2) != data[2])
|
||||
{
|
||||
osal_log_e("SHT40 serial CRC error (bytes 0-2)");
|
||||
return -1;
|
||||
}
|
||||
if (sht40_crc8(&data[3], 2) != data[5])
|
||||
{
|
||||
osal_log_e("SHT40 serial CRC error (bytes 3-5)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*serial = (uint32_t)(data[0] << 24) | (data[1] << 16) | (data[3] << 8) | data[4];
|
||||
//osal_log_i("SHT40: Serial number: 0x%08X", *serial);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 开启SHT40传感器的加热器
|
||||
* @param power_level 功率级别:0=低功率(20mW), 1=中功率(110mW), 2=高功率(200mW)
|
||||
* @return 0成功,-1失败
|
||||
*/
|
||||
int sht40_heater_enable(uint8_t power_level)
|
||||
{
|
||||
uint8_t cmd;
|
||||
|
||||
switch (power_level)
|
||||
{
|
||||
case 0:
|
||||
cmd = SHT40_CMD_HEATER_LOW;
|
||||
//osal_log_i("SHT40: Enabling heater (low power, 20mW)");
|
||||
break;
|
||||
case 1:
|
||||
cmd = SHT40_CMD_HEATER_MED;
|
||||
//osal_log_i("SHT40: Enabling heater (medium power, 110mW)");
|
||||
break;
|
||||
case 2:
|
||||
cmd = SHT40_CMD_HEATER_HIGH;
|
||||
//osal_log_i("SHT40: Enabling heater (high power, 200mW)");
|
||||
break;
|
||||
default:
|
||||
osal_log_e("SHT40: Invalid heater power level");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (HAL_I2C_Master_Transmit(&hi2c1, SHT40_I2C_ADDR << 1, &cmd, 1, 1000) != HAL_OK)
|
||||
{
|
||||
osal_log_e("SHT40 heater enable failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
osal_thread_mdelay(1000); // 加热器持续1秒
|
||||
//osal_log_i("SHT40: Heater operation completed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 读取SHT40传感器的温湿度数据(支持不同精度)
|
||||
* @param temperature 温度值(摄氏度)
|
||||
* @param humidity 湿度值(百分比)
|
||||
* @param precision 精度级别:0=低精度, 1=中精度, 2=高精度
|
||||
* @return 0成功,-1失败
|
||||
*/
|
||||
int sht40_read_temperature_humidity_with_precision(float *temperature, float *humidity, uint8_t precision)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint16_t delay_ms;
|
||||
|
||||
switch (precision)
|
||||
{
|
||||
case 0:
|
||||
cmd = SHT40_CMD_MEASURE_LOW_PRECISION;
|
||||
delay_ms = 2; // 1.8ms
|
||||
//osal_log_i("SHT40: Using low precision measurement");
|
||||
break;
|
||||
case 1:
|
||||
cmd = SHT40_CMD_MEASURE_MED_PRECISION;
|
||||
delay_ms = 5; // 4.5ms
|
||||
//osal_log_i("SHT40: Using medium precision measurement");
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
cmd = SHT40_CMD_MEASURE_HIGH_PRECISION;
|
||||
delay_ms = 10; // 8.2ms
|
||||
//osal_log_i("SHT40: Using high precision measurement");
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t data[6];
|
||||
|
||||
//osal_log_i("SHT40: Sending measure command 0x%02X to address 0x%02X", cmd, SHT40_I2C_ADDR);
|
||||
/* 发送测量命令 */
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, SHT40_I2C_ADDR << 1, &cmd, 1, 1000);
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
osal_log_e("SHT40 send measure command failed, status: %d", status);
|
||||
return -1;
|
||||
}
|
||||
//osal_log_i("SHT40: Measure command sent successfully");
|
||||
|
||||
/* 等待测量完成 */
|
||||
osal_thread_mdelay(delay_ms);
|
||||
|
||||
/* 读取测量结果 */
|
||||
//osal_log_i("SHT40: Reading 6 bytes of data");
|
||||
status = HAL_I2C_Master_Receive(&hi2c1, SHT40_I2C_ADDR << 1, data, 6, 1000);
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
osal_log_e("SHT40 read data failed, status: %d", status);
|
||||
return -1;
|
||||
}
|
||||
//osal_log_i("SHT40: Data read successfully: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X",
|
||||
// data[0], data[1], data[2], data[3], data[4], data[5]);
|
||||
|
||||
/* 校验温度数据 */
|
||||
if (sht40_crc8(&data[0], 2) != data[2])
|
||||
{
|
||||
osal_log_e("SHT40 temperature CRC error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 校验湿度数据 */
|
||||
if (sht40_crc8(&data[3], 2) != data[5])
|
||||
{
|
||||
osal_log_e("SHT40 humidity CRC error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 计算温度值 */
|
||||
uint16_t temp_raw = (data[0] << 8) | data[1];
|
||||
*temperature = -45.0f + 175.0f * (float)temp_raw / 65535.0f;
|
||||
|
||||
/* 计算湿度值 */
|
||||
uint16_t hum_raw = (data[3] << 8) | data[4];
|
||||
*humidity = -6.0f + 125.0f * (float)hum_raw / 65535.0f;
|
||||
|
||||
/* 湿度值范围限制 */
|
||||
if (*humidity < 0.0f) *humidity = 0.0f;
|
||||
if (*humidity > 100.0f) *humidity = 100.0f;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 读取SHT40传感器的温湿度数据(默认高精度)
|
||||
* @param temperature 温度值(摄氏度)
|
||||
* @param humidity 湿度值(百分比)
|
||||
* @return 0成功,-1失败
|
||||
*/
|
||||
int sht40_read_temperature_humidity(float *temperature, float *humidity)
|
||||
{
|
||||
return sht40_read_temperature_humidity_with_precision(temperature, humidity, 2); // 默认使用高精度
|
||||
}
|
||||
Reference in New Issue
Block a user