#include "sht30.h" #include "i2c.h" #include "pdebug.h" #include "assertions.h" #include "filter.h" #include "cmsis_os.h" #if 0 stTempHumiSensor g_stTempHumiSensor={ .i2c_reg_addr = 0x44<<1, .cmd_init_mode = 0x2320, //repeat medium_4 .cmd_read_data = 0xe000, }; #endif stTempHumiSensor g_stTempHumiSensor={ .i2c_reg_addr = 0x44<<1, .cmd_init_mode = 0x2c06, .cmd_read_data = 0x2c06, }; stTempHumiData g_stTempHumiData; /** * @brief 写命令,(两个命令时间间隔至少1ms) * @param * @retval */ static u_int8_t i2c_write_cmd(u_int8_t addr,u_int16_t cmd) { u_int8_t cmd_buff[2]={0x00}; cmd_buff[0] = cmd>>8; cmd_buff[1] = cmd; u_int8_t ret = HAL_I2C_Master_Transmit(&hi2c1,addr,cmd_buff,2,0xff); return ret; } /** * @brief CRC校验 * @param * @retval */ #define CRC8_POLYNOMIAL 0x31 u_int8_t CheckCrc8(u_int8_t* message, u_int8_t initial_value) { u_int8_t remainder; u_int8_t i = 0, j = 0; remainder = initial_value; for(j = 0; j < 2;j++){ remainder ^= message[j]; for (i = 0; i < 8; i++){ if (remainder & 0x80){ remainder = (remainder << 1)^CRC8_POLYNOMIAL; } else { remainder = (remainder << 1); } } } return remainder; } /** * @brief 初始化代码 * @param * @retval */ u_int8_t sht30_init() { float temp,humi; uint8_t ret; // soft reset // i2c_write_cmd(0x30a2); // HAL_Delay(25); HAL_GPIO_WritePin(GPIOB, GPIO_SHT_PWR_EN_Pin, GPIO_PIN_SET); HAL_Delay(1); //u_int8_t ret = i2c_write_cmd(g_stTempHumiSensor.i2c_reg_addr, g_stTempHumiSensor.cmd_init_mode); ret = get_temp_humi_data(&temp, &humi); if(ret == TRUE) term_printf("Sensor Sht30 Check OK.\r\n Temp:%.2f,Humi:%.2f\r\n", temp,humi); else // term_printf("Sensor Sht30 Check Err.\r\n"); return 0; } /** * @brief 温湿度数据采集 * @param * @retval */ u_int8_t sht30_collect_data(stTempHumiSensor stSensorDev, float *temp, float *humi) { u_int8_t read_buff[6] = {0}; u_int16_t temp_value; u_int16_t humi_value; i2c_write_cmd(stSensorDev.i2c_reg_addr,stSensorDev.cmd_read_data); if(HAL_I2C_Master_Receive(&hi2c1,stSensorDev.i2c_reg_addr,read_buff,6,0xff) != HAL_OK){ return HAL_ERROR; } if(CheckCrc8(read_buff, 0xFF) != read_buff[2] && CheckCrc8(&read_buff[3], 0xFF) != read_buff[5]){ return HAL_ERROR; } temp_value = ((u_int16_t)read_buff[0]<<8)|read_buff[1]; *temp = -45 + 175*((float)temp_value/65535); humi_value = ((u_int16_t)read_buff[3]<<8)|read_buff[4]; *humi = 100 * ((float)humi_value / 65535); return HAL_OK; } /** * @brief 温湿度数据采集 * @param * @retval */ u_int8_t sht45_collect_data(stTempHumiSensor stSensorDev, float *temp, float *humi) { u_int8_t read_buff[6] = {0}; uint8_t _cmd[] = {0xFD}; u_int16_t temp_value; u_int16_t humi_value; HAL_I2C_Master_Transmit(&hi2c1,stSensorDev.i2c_reg_addr,_cmd,1,0xff); osDelay(15); if(HAL_I2C_Master_Receive(&hi2c1,stSensorDev.i2c_reg_addr,read_buff,6,0xff) != HAL_OK){ return HAL_ERROR; } if(CheckCrc8(read_buff, 0xFF) != read_buff[2] && CheckCrc8(&read_buff[3], 0xFF) != read_buff[5]){ return HAL_ERROR; } temp_value = ((u_int16_t)read_buff[0]<<8)|read_buff[1]; *temp = -45 + 175*((float)temp_value/65535); humi_value = ((u_int16_t)read_buff[3]<<8)|read_buff[4]; *humi = -6 + 125*((float)humi_value / 65535); return HAL_OK; } static float calculateAverage(float arr[], int avgLength) { float sum = 0; // 遍历数组(最多10个元素),收集非零值直到达到指定数量 for (int i = 0; i < 10; ++i) { sum += arr[i]; } // 计算平均值并限制最大值 float average = sum / avgLength; return average; } /** * @brief 获取温湿度数据 * @param * @retval */ #define COLLECT_DATA_NUM 10 HAL_StatusTypeDef get_temp_humi_data(float* temdata, float* humidata) { float collect_temdata[COLLECT_DATA_NUM] = {0}; float collect_humidata[COLLECT_DATA_NUM] = {0}; float tmp_temdata,tmp_humidata; uint8_t ret_falt = 0; for(int i=0; i= COLLECT_DATA_NUM) { goto error_return; } tmp_temdata = calculateAverage(collect_temdata,COLLECT_DATA_NUM - ret_falt); tmp_humidata = calculateAverage(collect_humidata,COLLECT_DATA_NUM - ret_falt); if(tmp_temdata < -50.0) { tmp_temdata = -50.0; } if(tmp_temdata > 125.0) { tmp_temdata = 125.0; } if(tmp_humidata < 0.0) { tmp_humidata = 0.0; } if(tmp_humidata > 100.0) { tmp_humidata = 100.0; } *temdata = tmp_temdata; *humidata = tmp_humidata; return HAL_OK; error_return: *temdata = 0; *humidata = 0; return HAL_ERROR; } #if 0 /** * @brief 测试用例 * @param * @retval */ void TEST_read_sht30_value() { float temp,humi; AssertError(get_temp_humi_data(&temp, &humi),return,"采集sht30温湿度数据失败" ); term_printf("temp:%.2f, humi:%.2f\r\n", temp, humi); } #endif