207 lines
5.0 KiB
C
207 lines
5.0 KiB
C
|
/*
|
|||
|
* @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);
|
|||
|
}
|