暂存,io模拟iic

This commit is contained in:
stark1898y 2025-06-04 12:54:03 +08:00
parent 1738e85dce
commit 581ff87077
9 changed files with 459 additions and 10 deletions

View File

@ -283,7 +283,7 @@
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="HAL/Profile|HAL/KEY.c|HAL/LED.c|StdPeriphDriver/CH59x_pwm.c|StdPeriphDriver/CH59x_usbdev.c|StdPeriphDriver/CH59x_usbhostClass.c|StdPeriphDriver/CH59x_usbhostBase.c|StdPeriphDriver/CH59x_spi0.c|StdPeriphDriver/CH59x_timer0.c|StdPeriphDriver/CH59x_timer1.c|StdPeriphDriver/CH59x_timer2.c|StdPeriphDriver/CH59x_timer3.c|StdPeriphDriver/CH59x_uart2.c|StdPeriphDriver/CH59x_uart3.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry excluding="HAL/Profile|HAL/KEY.c|HAL/LED.c|StdPeriphDriver/CH59x_pwm.c|StdPeriphDriver/CH59x_usbdev.c|StdPeriphDriver/CH59x_usbhostClass.c|StdPeriphDriver/CH59x_usbhostBase.c|StdPeriphDriver/CH59x_spi0.c|StdPeriphDriver/CH59x_timer0.c|StdPeriphDriver/CH59x_timer1.c|StdPeriphDriver/CH59x_timer2.c|StdPeriphDriver/CH59x_timer3.c|StdPeriphDriver/CH59x_uart2.c|StdPeriphDriver/CH59x_uart3.c|BSP/src/bsp_i2c.c|BSP/inc/bsp_i2c.h" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>

View File

@ -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;
}

View File

@ -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"

View File

@ -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",

41
BSP/inc/bsp_gxhtc3c.h Normal file
View File

@ -0,0 +1,41 @@
#ifndef __BSP_GXHTC3C_H__
#define __BSP_GXHTC3C_H__
#include "CONFIG.h"
#include <stdbool.h>
#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__

44
BSP/inc/bsp_soft_i2c.h Normal file
View File

@ -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__

206
BSP/src/bsp_gxhtc3c.c Normal file
View File

@ -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);
}

142
BSP/src/bsp_soft_i2c.c Normal file
View File

@ -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时发送ACKack=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;
}

View File

@ -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