diff --git a/.cproject b/.cproject index 976b44e..dafc162 100644 --- a/.cproject +++ b/.cproject @@ -283,7 +283,7 @@ - + diff --git a/APP/peripheral.c b/APP/peripheral.c index 429b583..910e860 100644 --- a/APP/peripheral.c +++ b/APP/peripheral.c @@ -24,7 +24,9 @@ #include "bsp_uart.h" #include "log.h" -#include "bsp_i2c.h" +// #include "bsp_i2c.h" +#include "bsp_gxhtc3c.h" + #include "bsp_adc.h" #include "bsp_beep_led_emv.h" @@ -367,6 +369,7 @@ uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events) peripheralChar4Notify((uint8_t *)&RelyData.buf[0], RelyData.len); BSP_NoNeeedReplyCMd(); + tmos_set_event(led_task_id, LED_SHOW_START_EVT); return (events ^ SBP_REPLY_CMD_EVT); } if (events & SBP_PERIODIC_EVT) @@ -744,10 +747,14 @@ static void performPeriodicTask(void) { logDebug("高温关阀"); tmos_set_event(vavle_task_id, VAVLE_CLOSE_START_EVT); + // 给个回应 + tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, MS1_TO_SYSTEM_TIME(6000)); } } else { + gValveData.temp = -100; + gValveData.humi = 100; logError("Read TempHumi Err"); // return; } diff --git a/APP/peripheral_main.c b/APP/peripheral_main.c index 6671280..5d5b08a 100644 --- a/APP/peripheral_main.c +++ b/APP/peripheral_main.c @@ -12,7 +12,8 @@ #include "log.h" #include "bsp_uart.h" -#include "bsp_i2c.h" +// #include "bsp_i2c.h" +#include "bsp_gxhtc3c.h" #include "bsp_iwdg.h" #include "bsp_flash.h" diff --git a/BLE_TYQ_CH584M.wvproj b/BLE_TYQ_CH584M.wvproj index f89e9e9..c834419 100644 --- a/BLE_TYQ_CH584M.wvproj +++ b/BLE_TYQ_CH584M.wvproj @@ -52,7 +52,9 @@ "${project}/StdPeriphDriver/CH59x_timer2.c", "${project}/StdPeriphDriver/CH59x_timer3.c", "${project}/StdPeriphDriver/CH59x_uart2.c", - "${project}/StdPeriphDriver/CH59x_uart3.c" + "${project}/StdPeriphDriver/CH59x_uart3.c", + "${project}/BSP/src/bsp_i2c.c", + "${project}/BSP/inc/bsp_i2c.h" ], "riscvTargetProcessor": { "architecture": "rv32i", diff --git a/BSP/inc/bsp_gxhtc3c.h b/BSP/inc/bsp_gxhtc3c.h new file mode 100644 index 0000000..27cb009 --- /dev/null +++ b/BSP/inc/bsp_gxhtc3c.h @@ -0,0 +1,41 @@ +#ifndef __BSP_GXHTC3C_H__ +#define __BSP_GXHTC3C_H__ + +#include "CONFIG.h" +#include + +#define GXHTC3C_ADDR 0x70 +// #define GXHTC3C_7BIT_ADDR 0x38 // (GXHTC3C_ADDR >> 1) + +// 供电电压VDD从0上升上电电压VPOR,芯片会进入空闲状态。然后应该通过发送命令让芯片进入休眠状态以降低芯片功耗 +#define GXHTC3C_CMD_SLEEP 0xB098 +// 当芯片处于休眠状态时,如果要进行其它的命令操作,需要发送唤醒命令 +#define GXHTC3C_CMD_WAKEUP 0x3517 + +#define GXHTC3C_CMD_NORMAL_CLK_STRE_ON_TEMP_FRONT 0x7CA2 +#define GXHTC3C_CMD_NORMAL_CLK_STRE_ON_HUMI_FRONT 0x5C24 + +#define GXHTC3C_CMD_NORMAL_CLK_STRE_OFF_TEMP_FRONT 0x7866 +#define GXHTC3C_CMD_NORMAL_CLK_STRE_OFF_HUMI_FRONT 0x58E0 + +#define GXHTC3C_CMD_LOW_CLK_STRE_ON_TEMP_FRONT 0x6458 +#define GXHTC3C_CMD_LOW_CLK_STRE_ON_HUMI_FRONT 0x44DE + +#define GXHTC3C_CMD_LOW_CLK_STRE_OFF_TEMP_FRONT 0x609C +#define GXHTC3C_CMD_LOW_CLK_STRE_OFF_HUMI_FRONT 0x401A + +#define GXHTC3C_CMD_SOFT_REST 0x805D + +// 读传感器序列号 +#define GXHTC3C_CMD_READ_ID 0xEFC8 + + + + + +int BSP_ReadTempHumi(float *humi, float *temp); +void GXHTC3C_Init(void); + + + +#endif // !__BSP_GXHTC3C_H__ diff --git a/BSP/inc/bsp_soft_i2c.h b/BSP/inc/bsp_soft_i2c.h new file mode 100644 index 0000000..fcf63af --- /dev/null +++ b/BSP/inc/bsp_soft_i2c.h @@ -0,0 +1,44 @@ +/* + * @Author : stark1898y 1658608470@qq.com + * @Date : 2024-12-15 15:42:00 + * @LastEditors : stark1898y 1658608470@qq.com + * @LastEditTime : 2025-06-04 11:58:48 + * @FilePath : \BLE_TYQ_CH584M\BSP\inc\bsp_soft_i2c.h + * @Description : + * + * Copyright (c) 2024 by yzy, All Rights Reserved. + */ +#ifndef __BSP_I2C_H__ +#define __BSP_I2C_H__ + +#include "CONFIG.h" + + +#define IIC_SCL_BPIN bSCL // PB13-SCL +#define IIC_SDA_BPIN bSDA // PB12-SDA + +// IO方向设置 +#define IIC_SDA_IN() GPIOB_ModeCfg(IIC_SDA_BPIN, GPIO_ModeIN_PU) +#define IIC_SDA_OUT() GPIOB_ModeCfg(IIC_SDA_BPIN, GPIO_ModeOut_PP_5mA) + +#define IIC_SCL_H() GPIOB_SetBits(IIC_SCL_BPIN) +#define IIC_SCL_L() GPIOB_ResetBits(IIC_SCL_BPIN) + +#define IIC_SDA_H() GPIOB_SetBits(IIC_SDA_BPIN) +#define IIC_SDA_L() GPIOB_ResetBits(IIC_SDA_BPIN) + +#define IIC_READ_SDA() ((GPIOB_ReadPortPin(IIC_SDA_BPIN) ? 1 : 0)) + + +void IIC_Init(void); +void IIC_Deinit(void); +void IIC_Start(void); +void IIC_Stop(void); +uint8_t IIC_Wait_Ack(void); +void IIC_Ack(void); +void IIC_NAck(void); +void IIC_Send_Byte(uint8_t txd); +uint8_t IIC_Read_Byte(unsigned char ack); + +#endif // !__BSP_I2C_H__ + diff --git a/BSP/src/bsp_gxhtc3c.c b/BSP/src/bsp_gxhtc3c.c new file mode 100644 index 0000000..c6adc1c --- /dev/null +++ b/BSP/src/bsp_gxhtc3c.c @@ -0,0 +1,206 @@ +/* + * @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); +} diff --git a/BSP/src/bsp_soft_i2c.c b/BSP/src/bsp_soft_i2c.c new file mode 100644 index 0000000..453664d --- /dev/null +++ b/BSP/src/bsp_soft_i2c.c @@ -0,0 +1,142 @@ +#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 "i2c" + + + +//初始化IIC +void IIC_Init(void) +{ + GPIOB_ModeCfg(IIC_SCL_BPIN | IIC_SDA_BPIN, GPIO_ModeOut_PP_5mA); + + IIC_SCL_H(); + IIC_SDA_H(); +} + +void IIC_Deinit(void) +{ + GPIOB_ModeCfg(IIC_SCL_BPIN | IIC_SDA_BPIN, GPIO_ModeIN_PU); +} + +// 产生IIC起始信号 +void IIC_Start(void) +{ + IIC_SDA_OUT(); //sda线输出 + + IIC_SDA_H(); + IIC_SCL_H(); + DelayUs(4); + IIC_SDA_L(); // START: when CLK is high, DATA changes from high to low + DelayUs(4); + IIC_SCL_L(); //钳住I2C总线,准备发送或接收数据 +} + +//产生IIC停止信号 +void IIC_Stop(void) +{ + IIC_SDA_OUT(); //sda线输出 + + IIC_SCL_L(); + IIC_SDA_L(); //STOP: when CLK is high DATA changes from low to high + DelayUs(4); + IIC_SCL_H(); + IIC_SDA_H(); //发送I2C总线结束信号 + DelayUs(4); +} + +//等待应答信号到来 +//返回值:1,接收应答失败 +// 0,接收应答成功 +uint8_t IIC_Wait_Ack(void) +{ + uint8_t ucErrTime = 0; + IIC_SDA_IN(); //SDA设置为输入 + IIC_SDA_H(); DelayUs(1); + IIC_SCL_H(); DelayUs(1); + while (IIC_READ_SDA()) + { + ucErrTime++; + if (ucErrTime > 250) + { + IIC_Stop(); + return 1; + } + } + IIC_SCL_L(); //时钟输出0 + return 0; +} + +//产生ACK应答 +void IIC_Ack(void) +{ + IIC_SCL_L(); + IIC_SDA_OUT(); + IIC_SDA_L(); + DelayUs(2); + IIC_SCL_H(); + DelayUs(2); + IIC_SCL_L(); +} + +//不产生ACK应答 +void IIC_NAck(void) +{ + IIC_SCL_L(); + IIC_SDA_OUT(); + IIC_SDA_H(); + DelayUs(2); + IIC_SCL_H(); + DelayUs(2); + IIC_SCL_L(); +} + +//IIC发送一个字节 +//返回从机有无应答 +//1,有应答 +//0,无应答 +void IIC_Send_Byte(uint8_t txd) +{ + uint8_t t; + IIC_SDA_OUT(); + IIC_SCL_L(); //拉低时钟开始数据传输 + for (t = 0; t < 8; t++) + { + ((txd & 0x80) >> 7) == 0 ? IIC_SDA_L() : IIC_SDA_H(); + txd <<= 1; + DelayUs(2); //对TEA5767这三个延时都是必须的 + IIC_SCL_H(); + DelayUs(2); + IIC_SCL_L(); + DelayUs(2); + } +} + +//读1个字节,ack=1时,发送ACK,ack=0,发送nACK +uint8_t IIC_Read_Byte(unsigned char ack) +{ + unsigned char i, receive = 0; + IIC_SDA_IN(); //SDA设置为输入 + for (i = 0; i < 8; i++) + { + IIC_SCL_L(); + DelayUs(2); + IIC_SCL_H(); + receive <<= 1; + if (IIC_READ_SDA()) receive++; + DelayUs(1); + } + if (!ack) + IIC_NAck(); //发送nACK + else + IIC_Ack(); //发送ACK + return receive; +} + diff --git a/BSP/src/bsp_valve.c b/BSP/src/bsp_valve.c index caf956f..f1eac9f 100644 --- a/BSP/src/bsp_valve.c +++ b/BSP/src/bsp_valve.c @@ -2,7 +2,7 @@ * @Author : stark1898y 1658608470@qq.com * @Date : 2024-12-15 15:01:15 * @LastEditors : stark1898y 1658608470@qq.com - * @LastEditTime : 2025-06-03 10:43:05 + * @LastEditTime : 2025-06-04 12:33:17 * @FilePath : \BLE_TYQ_CH584M\BSP\src\bsp_valve.c * @Description : * @@ -11,7 +11,8 @@ #include "bsp_valve.h" #include "bsp_flash.h" -#include "bsp_i2c.h" +// #include "bsp_i2c.h" +#include "bsp_gxhtc3c.h" #include "bsp_beep_led_emv.h" // 0xAA CMD/DATA/ DATA_LEN (DATA) checksum 0x55 @@ -454,6 +455,7 @@ static uint16_t VAVLE_Task_ProcessEvent(uint8_t task_id, uint16_t events) } if (events & VAVLE_CLOSE_END_EVT) { + BSP_NoNeedBoost(); BEEP_OFF_DEINIT; EMV_CHARGE_OFF_DEINIT; @@ -461,8 +463,6 @@ static uint16_t VAVLE_Task_ProcessEvent(uint8_t task_id, uint16_t events) LED_ALL_OFF_DEINIT; - BSP_NoNeedBoost(); - gValveData.switch_status = kClosed; tmos_memset(&RelyData, 0, sizeof(RelyData)); @@ -565,10 +565,14 @@ static uint16_t VAVLE_Task_ProcessEvent(uint8_t task_id, uint16_t events) { logDebug("高温关阀"); tmos_start_task(vavle_task_id, VAVLE_CLOSE_START_EVT, MS1_TO_SYSTEM_TIME(1000)); + // 给个回应 + tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, MS1_TO_SYSTEM_TIME(8000)); } } else { + gValveData.temp = -100; + gValveData.humi = 100; logError("Read TempHumi Err"); } tmos_start_task(vavle_task_id, VAVLE_LOOP_DECT_EVT, MS1_TO_SYSTEM_TIME(VALVE_DECT_PERIOD_MS)); @@ -667,6 +671,7 @@ void BSP_VAVLE_Init(void) gValveData.switch_status = kClosed; gValveData.temp = -100; + gValveData.humi = 100; gValveData.in_pressure = 0; gValveData.out_pressure = 0; gValveData.atm_pressure = 0; @@ -726,8 +731,7 @@ void BSP_VAVLE_Init(void) logInfo("BSP_Valve_Init"); } - - +#if 0 /********************************************************************* * @fn TMR3_IRQHandler * @@ -746,3 +750,5 @@ void TMR3_IRQHandler(void) // TMR3 定时中断 cap_flag = 1; } } +#endif +