BLE_DCF_TYQ_CH592F/BSP/src/bsp_gxhtc3c.c

207 lines
5.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @Author : stark1898y 1658608470@qq.com
* @Date : 2025-06-04 11:18:42
* @LastEditors : stark1898y 1658608470@qq.com
* @LastEditTime : 2025-06-04 12:16:03
* @FilePath : \BLE_TYQ_CH584M\BSP\src\bsp_gxhtc3c.c
* @Description :
*
* Copyright (c) 2025 by yzy, All Rights Reserved.
*/
#include "bsp_gxhtc3c.h"
#include "bsp_soft_i2c.h"
#include "bsp_uart.h"
#include "log.h"
#undef LOG_ENABLE
#define LOG_ENABLE 1
#define LOG_LVL LOG_DEBUG
#undef LOG_TAG
#define LOG_TAG "gxhtc3c"
// GXHTC3C_CMD_LOW_CLK_STRE_OFF_HUMI_FRONT
void _GXHTC3C_SendCmd(uint16_t cmd)
{
int ret;
uint8_t i2c_tx_data[2];
i2c_tx_data[0] = HI_UINT16(cmd);
i2c_tx_data[1] = LO_UINT16(cmd);
// ret = I2C_Write(GXHTC3C_ADDR, (const uint8_t *)&i2c_tx_data, 2, true, true);
// logDebug("_GXHTC3C_SendCmd %s", ret ? "failed" : "success");
IIC_Init();
// 发送测量命令
IIC_Start();
IIC_Send_Byte(GXHTC3C_ADDR << 1); // 发送写命令(设备地址 + 写位)
if (IIC_Wait_Ack())
{
IIC_Stop();
return; // 如果没有收到应答,停止
}
IIC_Send_Byte(i2c_tx_data[0]); // 发送测量命令
if (IIC_Wait_Ack())
{
IIC_Stop();
return; // 如果没有收到应答,停止
}
IIC_Send_Byte(i2c_tx_data[1]); // 发送测量命令
if (IIC_Wait_Ack())
{
IIC_Stop();
return; // 如果没有收到应答,停止
}
IIC_Stop();
}
void _GXHTC3C_Sleep(void)
{
_GXHTC3C_SendCmd(GXHTC3C_CMD_SLEEP);
IIC_Deinit();
}
void _GXHTC3C_Wakeup(void)
{
_GXHTC3C_SendCmd(GXHTC3C_CMD_WAKEUP);
}
void _GXHTC3C_GetStart(void)
{
// 低功耗、Clock stretching关闭、湿度在前
_GXHTC3C_SendCmd(GXHTC3C_CMD_LOW_CLK_STRE_OFF_HUMI_FRONT);
}
// 定义CRC-8参数
#define POLYNOMIAL 0x31 // 生成多项式x8+x5+x4+1 (省略最高位1)
#define INIT_VALUE 0xFF // 初始化值
#define REFLECT_IN false // 不反射输入
#define REFLECT_OUT false // 不反射输出
uint8_t _GXHTC3C_CRC_8(uint8_t *p_crc, uint8_t len)
{
uint8_t crc = INIT_VALUE;
for (size_t i = 0; i < len; ++i)
{
crc ^= p_crc[i]; // 异或当前字节
for (uint8_t j = 0; j < 8; ++j)
{
if (crc & 0x80)
{ // 如果最高位是1
crc = (crc << 1) ^ POLYNOMIAL; // 左移一位并异或多相式
}
else
{
crc <<= 1; // 否则只左移一位
}
// 确保crc保持在8位内
crc &= 0xFF;
}
}
// 最终返回CRC值
return crc;
}
// GXHTC3C_CMD_LOW_CLK_STRE_OFF_HUMI_FRONT
uint8_t GXHTC3C_GetTempHumi(float *humi, float *temp)
{
int ret;
uint8_t i2c_rx_data[6];
// 重新启动I2C并设置为读模式
IIC_Start();
IIC_Send_Byte((GXHTC3C_ADDR << 1) | 1); // 设备地址 + 读位
if (IIC_Wait_Ack())
{
IIC_Stop();
logError("read failed");
return 1; // 如果没有收到应答,停止
}
for (uint8_t i = 0; i < 6; i++)
{
i2c_rx_data[i] = IIC_Read_Byte(i != 5); // 读取6个字节
}
IIC_Stop();
IIC_Deinit();
// logHexDumpAll(i2c_rx_data, 6);
// 低功耗、Clock stretching关闭、湿度在前
uint8_t humi_raw_data[2];
uint8_t temp_raw_data[2];
humi_raw_data[0] = i2c_rx_data[0];
humi_raw_data[1] = i2c_rx_data[1];
uint16_t raw_humi = (humi_raw_data[0] << 8) | humi_raw_data[1];
uint8_t crc_humi = _GXHTC3C_CRC_8(humi_raw_data, 2);
temp_raw_data[0] = i2c_rx_data[3];
temp_raw_data[1] = i2c_rx_data[4];
uint16_t raw_temp = (temp_raw_data[0] << 8) | temp_raw_data[1];
uint8_t crc_temp = _GXHTC3C_CRC_8(temp_raw_data, 2);
if ((crc_humi == i2c_rx_data[2]) && (crc_temp == i2c_rx_data[5]))
{
// logDebug("crc ok");
// logHexDumpAll(i2c_rx_data, 6);
*humi = (100.0 * raw_humi) / 65536.0; // 湿度真实值
*temp = (175.0 * raw_temp) / 65536.0 - 45.0; // 温度真实值
// logDebug("humi %f, temp %f", *humi, *temp);
}
else
{
logHexDumpAll(i2c_rx_data, 6);
logError("crc_temp 0x%02x, crc_humi 0x%02x", crc_temp, crc_humi);
logError("crc error");
return 2;
}
// logDebug("0 success");
return 0;
}
int BSP_ReadTempHumi(float *humi, float *temp)
{
int ret;
_GXHTC3C_Wakeup();
DelayMs(1);
_GXHTC3C_GetStart();
DelayMs(3);
float _humi, _temp;
ret = GXHTC3C_GetTempHumi(&_humi, &_temp);
if (ret == 0)
{
*humi = _humi;
*temp = _temp;
// gValveData.temp = (int8_t)temp;
// gValveData.humi = (uint8_t)humi;
// logDebug("humi %.2f %, temp %.2f C", *humi, *temp);
}
_GXHTC3C_Sleep();
return ret;
}
void GXHTC3C_Init(void)
{
// IIC_Init();
_GXHTC3C_Sleep();
float _humi, _temp;
BSP_ReadTempHumi(&_humi, &_temp);
logDebug("humi = %.1f %%, temp = %.1f C", _humi, _temp);
}