IoT_SCV_CH584M/bsp/src/bsp_bmp390.c

1184 lines
41 KiB
C
Raw Normal View History

#include "bsp_bmp390.h"
#include "bsp_motor.h"
#include "bsp_led.h"
#include "bsp_key.h"
#include "CONFIG.h"
#include "log.h"
#include "bsp_ml307r.h"
#include "SLEEP.h"
#include "bsp_valve.h"
uint8_t flag;
2025-05-22 17:59:32 +08:00
uint8_t keydown_flag = 0;
uint8_t keydown_time = 0;
uint8_t volatile fault_state = 0;
2025-05-22 14:08:24 +08:00
2025-05-22 17:59:32 +08:00
// 安全阈值参数统一定义
#define SAFETY_AUTO_OPEN_THRESHOLD 3 // 自动开阀阈值(连续检测次数)
#define SAFETY_MICRO_LEAK_THRESHOLD 5 // 微泄漏检测阈值(连续检测次数)
#define SAFETY_MICRO_LEAK_PRESS_DIFF 15 // 微泄漏压力差阈值(Pa)对应流量约0.3L/min
#define SAFETY_OVER_TEMP_THRESHOLD 65 // 超温阈值(℃)
#define SAFETY_GAS_REQUEST_PRESS_DIFF 50 // 用气请求压力差阈值(Pa)
typedef struct
{
int in_press_raw;
int out_press_raw;
int8_t in_temp;
int8_t out_temp;
int8_t atom_temp;
int in_press; // 表压 单位Pa
int out_press;
int atom_press;
// 进气端和出气端压力差值 单位Pa
int in_out_press_diff;
} TsValveRawData;
TsValveRawData ValveRawData;
TsValveRawData ValveRawData_buffer[5];
typedef struct
{
uint16_t over_press;
uint16_t low_press;
uint8_t over_temp;
int over_flow_press_diff_1kpa;
int over_flow_press_diff_2kpa;
int over_flow_press_diff_3kpa;
} TsValveInfo;
TsValveInfo ValveInfo;
// 安全保护状态结构体
typedef struct
{
// 自动开阀相关
uint8_t auto_open_count; // 自动开阀检测计数
uint8_t auto_open_flag; // 自动开阀标志
// 微泄漏相关
uint8_t micro_leak_count; // 微泄漏检测计数
uint8_t micro_leak_flag; // 微泄漏标志
// 超温相关
uint8_t over_temp_flag; // 超温标志
2025-05-22 14:08:24 +08:00
} TsValveSafetyStatus;
2025-05-22 17:59:32 +08:00
// 安全状态全局变量
2025-05-22 14:08:24 +08:00
TsValveSafetyStatus valve_safety = {0};
extern uint8_t motor_flag;
2025-03-21 11:44:42 +08:00
extern Shell shell;
static tmosTaskID check_task_id = INVALID_TASK_ID;
typedef enum
{
kPressIn = 0,
kPressOut = 1,
kPressAtom = 2,
kPressMaxIndex
} TePressSensorIndex;
static tmosTaskID press_task_id = INVALID_TASK_ID;
2025-05-13 17:29:54 +08:00
#define PRESS_IN_CS_HIGH() GPIOA_SetBits(GPIO_Pin_8)
#define PRESS_IN_CS_LOW() GPIOA_ResetBits(GPIO_Pin_8)
2025-05-13 17:29:54 +08:00
#define PRESS_OUT_CS_HIGH() GPIOA_SetBits(GPIO_Pin_2)
#define PRESS_OUT_CS_LOW() GPIOA_ResetBits(GPIO_Pin_2)
2025-05-13 17:29:54 +08:00
#define PRESS_ATOM_CS_HIGH() GPIOA_SetBits(GPIO_Pin_0)
#define PRESS_ATOM_CS_LOW() GPIOA_ResetBits(GPIO_Pin_0)
uint8_t volatile press_done_flag = 0;
uint8_t SPI0_SendByte(uint8_t data);
void SPI_CsStart(TePressSensorIndex index);
void SPI_CsStop(TePressSensorIndex index);
/* Variable to store the device address */
static uint8_t dev_in_addr;
static uint8_t dev_out_addr;
static uint8_t dev_atom_addr;
uint8_t Bmp_ReadData(uint8_t *reg_data, uint32_t len)
{
while (len--)
{
*reg_data = SPI0_SendByte(0x00);
reg_data++;
}
return BMP3_INTF_RET_SUCCESS;
}
BMP3_INTF_RET_TYPE Bmp_WriteData(const uint8_t *reg_data, uint32_t len)
{
uint8_t i = 0;
for (i = 0; i < len; i++)
{
SPI0_SendByte(reg_data[i]);
}
return BMP3_INTF_RET_SUCCESS;
}
BMP3_INTF_RET_TYPE BMP390_IN_SPI_Read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
BMP3_INTF_RET_TYPE rslt = 0;
uint8_t reg_spi[1] = {(reg_addr & 0x7F) | 0x80};
2025-05-22 17:59:32 +08:00
SPI_CsStart(kPressIn); // 拉低片选
Bmp_WriteData(reg_spi, 1); // 写入控制字节
rslt = Bmp_ReadData(reg_data, len);
SPI_CsStop(kPressIn);
return rslt;
}
/*!
* SPI write function map to COINES platform
*/
BMP3_INTF_RET_TYPE BMP390_IN_SPI_Write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t reg_spi[1] = {reg_addr & 0x7f};
BMP3_INTF_RET_TYPE rslt = 0;
SPI_CsStart(kPressIn);
Bmp_WriteData(reg_spi, 1);
rslt = Bmp_WriteData(reg_data, len);
SPI_CsStop(kPressIn);
// printf("BMP390_OUT_SPI_Write: %d" , rslt);
return rslt;
}
/*!
* SPI read function map to COINES platform
*/
BMP3_INTF_RET_TYPE BMP390_OUT_SPI_Read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
BMP3_INTF_RET_TYPE rslt = 0;
uint8_t reg_spi[1] = {(reg_addr & 0x7F) | 0x80};
2025-05-22 17:59:32 +08:00
SPI_CsStart(kPressOut); // 拉低片选
Bmp_WriteData(reg_spi, 1); // 写入控制字节
rslt = Bmp_ReadData(reg_data, len);
SPI_CsStop(kPressOut);
return rslt;
}
/*!
* SPI write function map to COINES platform
*/
BMP3_INTF_RET_TYPE BMP390_OUT_SPI_Write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t reg_spi[1] = {reg_addr & 0x7f};
BMP3_INTF_RET_TYPE rslt = 0;
SPI_CsStart(kPressOut);
Bmp_WriteData(reg_spi, 1);
rslt = Bmp_WriteData(reg_data, len);
SPI_CsStop(kPressOut);
// printf("BMP390_OUT_SPI_Write: %d" , rslt);
return rslt;
}
BMP3_INTF_RET_TYPE BMP390_ATOM_SPI_Read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
BMP3_INTF_RET_TYPE rslt = 0;
uint8_t reg_spi[1] = {(reg_addr & 0x7F) | 0x80};
2025-05-22 17:59:32 +08:00
SPI_CsStart(kPressAtom); // 拉低片选
Bmp_WriteData(reg_spi, 1); // 写入控制字节
rslt = Bmp_ReadData(reg_data, len);
SPI_CsStop(kPressAtom);
return rslt;
}
/*!
* SPI write function map to COINES platform
*/
BMP3_INTF_RET_TYPE BMP390_ATOM_SPI_Write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t reg_spi[1] = {reg_addr & 0x7f};
BMP3_INTF_RET_TYPE rslt = 0;
SPI_CsStart(kPressAtom);
Bmp_WriteData(reg_spi, 1);
rslt = Bmp_WriteData(reg_data, len);
SPI_CsStop(kPressAtom);
// printf("BMP390_OUT_SPI_Write: %d" , rslt);
return rslt;
}
void bmp3_delay_us(uint32_t period, void *intf_ptr)
{
DelayUs(period);
}
void bmp3_check_rslt(const char api_name[], int8_t rslt)
{
switch (rslt)
{
case BMP3_OK:
/* Do nothing */
break;
case BMP3_E_NULL_PTR:
printf("API [%s] Error [%d] : Null pointer\r\n", api_name, rslt);
break;
case BMP3_E_COMM_FAIL:
printf("API [%s] Error [%d] : Communication failure\r\n", api_name, rslt);
break;
case BMP3_E_INVALID_LEN:
printf("API [%s] Error [%d] : Incorrect length parameter\r\n", api_name, rslt);
break;
case BMP3_E_DEV_NOT_FOUND:
printf("API [%s] Error [%d] : Device not found\r\n", api_name, rslt);
break;
case BMP3_E_CONFIGURATION_ERR:
printf("API [%s] Error [%d] : Configuration Error\r\n", api_name, rslt);
break;
case BMP3_W_SENSOR_NOT_ENABLED:
printf("API [%s] Error [%d] : Warning when Sensor not enabled\r\n", api_name, rslt);
break;
case BMP3_W_INVALID_FIFO_REQ_FRAME_CNT:
printf("API [%s] Error [%d] : Warning when Fifo watermark level is not in limit\r\n", api_name, rslt);
break;
default:
printf("API [%s] Error [%d] : Unknown error code\r\n", api_name, rslt);
break;
}
}
BMP3_INTF_RET_TYPE BMP390_IN_InterfaceInit(struct bmp3_dev *bmp3, uint8_t intf)
{
int8_t rslt = BMP3_OK;
/* Bus configuration : SPI */
if (intf == BMP3_SPI_INTF)
{
printf("SPI Interface\n");
bmp3->read = BMP390_IN_SPI_Read;
bmp3->write = BMP390_IN_SPI_Write;
bmp3->intf = BMP3_SPI_INTF;
printf("spi init ok\r\n");
}
DelayMs(100);
bmp3->delay_us = bmp3_delay_us;
bmp3->intf_ptr = &dev_in_addr;
return rslt;
}
BMP3_INTF_RET_TYPE BMP390_OUT_InterfaceInit(struct bmp3_dev *bmp3, uint8_t intf)
{
int8_t rslt = BMP3_OK;
/* Bus configuration : SPI */
if (intf == BMP3_SPI_INTF)
{
printf("SPI Interface\n");
bmp3->read = BMP390_OUT_SPI_Read;
bmp3->write = BMP390_OUT_SPI_Write;
bmp3->intf = BMP3_SPI_INTF;
printf("spi init ok\r\n");
}
DelayMs(100);
bmp3->delay_us = bmp3_delay_us;
bmp3->intf_ptr = &dev_out_addr;
return rslt;
}
BMP3_INTF_RET_TYPE BMP390_ATOM_InterfaceInit(struct bmp3_dev *bmp3, uint8_t intf)
{
int8_t rslt = BMP3_OK;
/* Bus configuration : SPI */
if (intf == BMP3_SPI_INTF)
{
printf("SPI Interface\n");
bmp3->read = BMP390_ATOM_SPI_Read;
bmp3->write = BMP390_ATOM_SPI_Write;
bmp3->intf = BMP3_SPI_INTF;
printf("spi init ok\r\n");
}
DelayMs(100);
bmp3->delay_us = bmp3_delay_us;
bmp3->intf_ptr = &dev_atom_addr;
return rslt;
}
void SPI_CsStart(TePressSensorIndex index)
{
switch (index)
{
case kPressIn:
PRESS_IN_CS_LOW();
break;
case kPressOut:
PRESS_OUT_CS_LOW();
break;
case kPressAtom:
PRESS_ATOM_CS_LOW();
break;
default:
break;
}
}
void SPI_CsStop(TePressSensorIndex index)
{
switch (index)
{
case kPressIn:
PRESS_IN_CS_HIGH();
break;
case kPressOut:
PRESS_OUT_CS_HIGH();
break;
case kPressAtom:
PRESS_ATOM_CS_HIGH();
break;
default:
break;
}
}
uint8_t SPI0_SendByte(uint8_t data)
{
R8_SPI0_BUFFER = data;
while (!(R8_SPI0_INT_FLAG & RB_SPI_FREE));
return (R8_SPI0_BUFFER);
}
void PRESS_IO_SPI_Init(void)
{
/**
* CSB1: PA3
* CSB2: PA5
* CSB3: PA0
* SCL: PA13
* SDA: PA14
* SDO: PA15
*/
// SDA: MOSI
// SDO: MISO
2025-05-13 17:29:54 +08:00
GPIOA_SetBits(GPIO_Pin_2);
GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeOut_PP_5mA);
2025-05-13 17:29:54 +08:00
GPIOA_SetBits(GPIO_Pin_8);
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeOut_PP_5mA);
2025-05-13 17:29:54 +08:00
GPIOA_SetBits(GPIO_Pin_0);
GPIOA_ModeCfg(GPIO_Pin_0, GPIO_ModeOut_PP_5mA);
SPI_CsStop(kPressIn);
SPI_CsStop(kPressOut);
SPI_CsStop(kPressAtom);
2025-05-22 17:59:32 +08:00
// spi初始化模式0
GPIOA_ModeCfg(GPIO_Pin_13 | GPIO_Pin_14, GPIO_ModeOut_PP_5mA);
GPIOA_ModeCfg(GPIO_Pin_15, GPIO_ModeIN_PU);
SPI0_MasterDefInit();
}
void PRESS_LowerIO_Init(void)
{
2025-05-22 17:59:32 +08:00
// BMP390默认供电时其他IO都是高电平,INT引脚为低电平
// SPI
GPIOA_SetBits(GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
GPIOA_ModeCfg(GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15, GPIO_ModeIN_PU);
// CSB3: PA0
2025-05-13 17:29:54 +08:00
GPIOA_SetBits(GPIO_Pin_2);
GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_PU);
// CSB2: PA5
2025-05-13 17:29:54 +08:00
GPIOA_SetBits(GPIO_Pin_8);
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
// CSB1: PA3
2025-05-13 17:29:54 +08:00
GPIOA_SetBits(GPIO_Pin_0);
GPIOA_ModeCfg(GPIO_Pin_0, GPIO_ModeIN_PU);
}
void Lower_IO_Deinit(void)
{
// LED
2025-05-13 17:29:54 +08:00
GPIOB_ResetBits(LED_VALVE_R_PIN | LED_VALVE_G_PIN);
GPIOB_ModeCfg(LED_VALVE_R_PIN | LED_VALVE_G_PIN, GPIO_ModeIN_PD);
GPIOA_ResetBits(LED_VBAT_PIN | LED_ALARM_PIN);
GPIOA_ModeCfg(LED_VBAT_PIN | LED_ALARM_PIN, GPIO_ModeIN_PD);
// KEY | RESET KEY | boot KEY
2025-05-23 10:19:17 +08:00
GPIOA_ResetBits(KEY_BPIN);
GPIOA_ModeCfg(KEY_BPIN, GPIO_ModeIN_PU);
// GPIOB_ResetBits(GPIO_Pin_23 | GPIO_Pin_22);
// GPIOB_ModeCfg(GPIO_Pin_23 | GPIO_Pin_22, GPIO_ModeIN_PD);
// ADC
GPIOA_ResetBits(GPIO_Pin_4);
2025-03-21 11:44:42 +08:00
GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_Floating);
ADC_DisablePower();
// BMP390
// INT1: PA2 | INT2: PA6 | INT3: PA12
2025-05-13 17:29:54 +08:00
GPIOA_ModeCfg(GPIO_Pin_6 | GPIO_Pin_9 | GPIO_Pin_3, GPIO_ModeIN_PD);
2025-05-22 17:59:32 +08:00
// spi初始化
GPIOA_ModeCfg(GPIO_Pin_13 | GPIO_Pin_14, GPIO_ModeIN_PD);
GPIOA_ModeCfg(GPIO_Pin_15, GPIO_ModeIN_PD);
2025-05-22 17:59:32 +08:00
// 4G
// 关闭3.8V供电
GPIOB_ResetBits(ENABLE_3_8_V);
GPIOB_ModeCfg(ENABLE_3_8_V, GPIO_ModeIN_PD);
2025-05-22 17:59:32 +08:00
// 将控制引脚设为下拉,减少漏电流
GPIOB_ModeCfg(ML307_PWR_PIN | ML307_RST_PIN, GPIO_ModeIN_PD);
2025-05-22 17:59:32 +08:00
// UART引脚
GPIOB_ModeCfg(ML307_UART_TX_PIN, GPIO_ModeIN_PD);
GPIOB_ModeCfg(ML307_UART_RX_PIN, GPIO_ModeIN_PU);
2025-05-22 17:59:32 +08:00
// SIM卡检测引脚配置为下拉输入
GPIOB_ModeCfg(USIM_DECT_PIN, GPIO_ModeIN_PD);
2025-05-22 17:59:32 +08:00
// motor
// GPIOA_ResetBits(COIL_ADC);
// GPIOA_ModeCfg(COIL_ADC, GPIO_ModeIN_PD);
// IN1 + ; IN2 +
// GPIOB_SetBits(COIL_A);
// GPIOB_SetBits(COIL_B);
// GPIOB_ModeCfg(COIL_A | COIL_B, GPIO_ModeIN_PD);
2025-03-21 11:44:42 +08:00
// UART3
// GPIOB_ModeCfg(GPIO_Pin_21 | GPIO_Pin_20, GPIO_ModeIN_PD);
2025-05-22 17:59:32 +08:00
// // 关闭UART3时钟
// sys_safe_access_enable();
// R8_SLP_CLK_OFF0 |= RB_SLP_CLK_UART3;
// sys_safe_access_disable();
2025-05-22 17:59:32 +08:00
// // 关闭shell和日志系统
// shell.write = NULL; // 禁用shell输出
2025-05-22 17:59:32 +08:00
// 关闭外部低速晶振
// GPIOA_ModeCfg(GPIO_Pin_10 | GPIO_Pin_11, GPIO_ModeIN_PD);
}
void PRESS_LowPower(void)
{
Lower_IO_Deinit();
if (press_done_flag == 1)
{
PRESS_LowerIO_Init();
}
}
int8_t ret = 0;
uint8_t loop = 0;
struct bmp3_dev DevIn;
struct bmp3_dev DevOut;
struct bmp3_dev DevAtom;
uint16_t settings_sel;
struct bmp3_data data = {0};
struct bmp3_settings settings = {0};
struct bmp3_status status = {{0}};
2025-05-22 17:59:32 +08:00
// T,P
int32_t T[3] = {0};
int32_t P[3] = {0};
2025-05-22 17:59:32 +08:00
// 定义滑动窗口函数
void slideValveRawDataBuffer(TsValveRawData *newData)
{
// 将数组元素左移一位
for (int i = 0; i < 4; i++)
{
tmos_memcpy(&ValveRawData_buffer[i], &ValveRawData_buffer[i + 1], sizeof(TsValveRawData));
}
// 将新数据存入数组[4]
tmos_memcpy(&ValveRawData_buffer[4], &newData[0], sizeof(TsValveRawData));
// for (int i = 0; i < 5; i++)
// {
// logDebug("Buffer[%d]: in_press=%d, out_press=%d, diff=%d",
// i,
// ValveRawData_buffer[i].in_press,
// ValveRawData_buffer[i].out_press,
// ValveRawData_buffer[i].in_out_press_diff);
// }
}
__HIGH_CODE
__attribute__((noinline))
uint16_t
BMP390_ProcessEvent(uint8_t task_id, uint16_t events)
{
if (events & BMP390_IN_START)
{
press_done_flag = 0;
PRESS_IO_SPI_Init();
settings.op_mode = BMP3_MODE_FORCED;
ret = bmp3_set_op_mode(&settings, &DevIn);
bmp3_check_rslt("bmp3_set_op_mode", ret);
return (events ^ BMP390_IN_START);
}
2025-05-22 17:59:32 +08:00
else if (events & BMP390_OUT_START)
{
press_done_flag = 0;
PRESS_IO_SPI_Init();
settings.op_mode = BMP3_MODE_FORCED;
ret = bmp3_set_op_mode(&settings, &DevOut);
bmp3_check_rslt("bmp3_set_op_mode", ret);
return (events ^ BMP390_OUT_START);
}
2025-05-22 17:59:32 +08:00
else if (events & BMP390_ATOM_START)
{
press_done_flag = 0;
PRESS_IO_SPI_Init();
settings.op_mode = BMP3_MODE_FORCED;
ret = bmp3_set_op_mode(&settings, &DevAtom);
bmp3_check_rslt("bmp3_set_op_mode", ret);
return (events ^ BMP390_ATOM_START);
}
else if (events & BMP390_EVT_READ)
{
PRESS_IO_SPI_Init();
#if 0
PRESS_IO_SPI_Init();
// IN
ret = bmp3_get_status(&status, &DevIn);
bmp3_check_rslt("bmp3_get_status", ret);
/* Read temperature and pressure data iteratively based on data ready interrupt */
if ((ret == BMP3_OK) && (status.intr.drdy == BMP3_ENABLE))
{
/*
* First parameter indicates the type of data to be read
* BMP3_PRESS_TEMP : To read pressure and temperature data
* BMP3_TEMP : To read only temperature data
* BMP3_PRESS : To read only pressure data
*/
ret = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &DevIn);
bmp3_check_rslt("bmp3_get_sensor_data", ret);
/* NOTE : Read status register again to clear data ready interrupt status */
ret = bmp3_get_status(&status, &DevIn);
bmp3_check_rslt("bmp3_get_status", ret);
2025-05-22 17:59:32 +08:00
#ifdef BMP3_FLOAT_COMPENSATION
printf("IN[%d] T: %.2f deg C, P: %.2f Pa\n", loop, (data.temperature), (data.pressure));
2025-05-22 17:59:32 +08:00
#else
printf("IN[%d] T: %ld deg C, P: %lu Pa\n", loop, (long int)(int32_t)(data.temperature / 100),
(long unsigned int)(uint32_t)(data.pressure / 100));
2025-05-22 17:59:32 +08:00
#endif
}
// OUT
ret = bmp3_get_status(&status, &DevOut);
bmp3_check_rslt("bmp3_get_status", ret);
/* Read temperature and pressure data iteratively based on data ready interrupt */
if ((ret == BMP3_OK) && (status.intr.drdy == BMP3_ENABLE))
{
/*
* First parameter indicates the type of data to be read
* BMP3_PRESS_TEMP : To read pressure and temperature data
* BMP3_TEMP : To read only temperature data
* BMP3_PRESS : To read only pressure data
*/
ret = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &DevOut);
bmp3_check_rslt("bmp3_get_sensor_data", ret);
/* NOTE : Read status register again to clear data ready interrupt status */
ret = bmp3_get_status(&status, &DevOut);
bmp3_check_rslt("bmp3_get_status", ret);
2025-05-22 17:59:32 +08:00
#ifdef BMP3_FLOAT_COMPENSATION
printf("OUT[%d] T: %.2f deg C, P: %.2f Pa\n", loop, (data.temperature), (data.pressure));
2025-05-22 17:59:32 +08:00
#else
printf("OUT[%d] T: %ld deg C, P: %lu Pa\n", loop, (long int)(int32_t)(data.temperature / 100),
(long unsigned int)(uint32_t)(data.pressure / 100));
2025-05-22 17:59:32 +08:00
#endif
loop = loop + 1;
}
tmos_start_task(press_task_id, WF5803_EVT_START, MS1_TO_SYSTEM_TIME(2000));
#endif
2025-05-22 17:59:32 +08:00
if (flag == 1)
{
ret = bmp3_get_status(&status, &DevIn); // 配置中断引脚为锁存模式需要读取int_status.drdy位才能清除中断状态标志
bmp3_check_rslt("bmp3_get_status", ret);
if (status.intr.drdy == BMP3_ENABLE)
{
/*
* First parameter indicates the type of data to be read
* BMP3_PRESS_TEMP : To read pressure and temperature data
* BMP3_TEMP : To read only temperature data
* BMP3_PRESS : To read only pressure data
*/
ret = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &DevIn);
bmp3_check_rslt("bmp3_get_sensor_data", ret);
/* NOTE : Read status register again to clear data ready interrupt status */
ret = bmp3_get_status(&status, &DevIn);
bmp3_check_rslt("bmp3_get_status", ret);
// printf("IN[%d] T: %ld deg C, P: %lu Pa\r\n", loop, (long int)(int32_t)(data.temperature / 100),
// (long unsigned int)(uint32_t)(data.pressure / 100));
T[0] = (int32_t)(data.temperature / 100);
P[0] = (uint32_t)(data.pressure / 100);
}
// tmos_start_task(press_task_id, BMP390_ATOM_START, MS1_TO_SYSTEM_TIME(100));
tmos_start_task(press_task_id, BMP390_OUT_START, MS1_TO_SYSTEM_TIME(500)); // 100
// tmos_start_task(press_task_id, BMP390_IN_START, MS1_TO_SYSTEM_TIME(1000));
}
else if (flag == 2)
{
2025-05-22 17:59:32 +08:00
ret = bmp3_get_status(&status, &DevOut); // 配置中断引脚为锁存模式需要读取int_status.drdy位才能清除中断状态标志
bmp3_check_rslt("bmp3_get_status", ret);
if (status.intr.drdy == BMP3_ENABLE)
{
2025-05-22 17:59:32 +08:00
/*
* First parameter indicates the type of data to be read
* BMP3_PRESS_TEMP : To read pressure and temperature data
* BMP3_TEMP : To read only temperature data
* BMP3_PRESS : To read only pressure data
*/
ret = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &DevOut);
bmp3_check_rslt("bmp3_get_sensor_data", ret);
/* NOTE : Read status register again to clear data ready interrupt status */
ret = bmp3_get_status(&status, &DevOut);
bmp3_check_rslt("bmp3_get_status", ret);
// printf("OUT[%d] T: %ld deg C, P: %lu Pa\r\n", loop, (long int)(int32_t)(data.temperature / 100),
// (long unsigned int)(uint32_t)(data.pressure / 100));
T[1] = (int32_t)(data.temperature / 100);
P[1] = (uint32_t)(data.pressure / 100);
}
2025-05-22 17:59:32 +08:00
tmos_start_task(press_task_id, BMP390_ATOM_START, MS1_TO_SYSTEM_TIME(500)); // 100
// tmos_start_task(press_task_id, BMP390_OUT_START, MS1_TO_SYSTEM_TIME(1000));
}
else if (flag == 3)
{
ret = bmp3_get_status(&status, &DevAtom); // 配置中断引脚为锁存模式需要读取int_status.drdy位才能清除中断状态标志
bmp3_check_rslt("bmp3_get_status", ret);
if (status.intr.drdy == BMP3_ENABLE)
{
2025-05-22 17:59:32 +08:00
/*
* First parameter indicates the type of data to be read
* BMP3_PRESS_TEMP : To read pressure and temperature data
* BMP3_TEMP : To read only temperature data
* BMP3_PRESS : To read only pressure data
*/
ret = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &DevAtom);
bmp3_check_rslt("bmp3_get_sensor_data", ret);
/* NOTE : Read status register again to clear data ready interrupt status */
ret = bmp3_get_status(&status, &DevAtom);
bmp3_check_rslt("bmp3_get_status", ret);
// printf("ATOM[%d] T: %ld deg C, P: %lu Pa\r\n", loop, (long int)(int32_t)(data.temperature / 100),
// (long unsigned int)(uint32_t)(data.pressure / 100));
T[2] = (int32_t)(data.temperature / 100);
P[2] = (uint32_t)(data.pressure / 100);
logDebug("**********************************");
logDebug("%d, %d, %d, %d, %d, %d \r\n", T[0], T[1], T[2], P[0], P[1], P[2]);
logDebug("P1: %d,P2: %d ,^P: %d \r\n", P[0] - P[2], P[1] - P[2], P[0] - P[1]);
logDebug("**********************************");
}
2025-05-22 17:59:32 +08:00
tmos_start_task(press_task_id, BMP390_IN_START, MS1_TO_SYSTEM_TIME(500)); // 100
// tmos_start_task(press_task_id, BMP390_ATOM_START, MS1_TO_SYSTEM_TIME(1000));
}
2025-05-22 17:59:32 +08:00
flag = 0;
press_done_flag = 1;
// TODO:读完三个气压传感器数据后在做计算
ValveRawData.in_press_raw = P[0];
ValveRawData.out_press_raw = P[1];
ValveRawData.atom_press = P[2];
ValveRawData.in_temp = T[0];
ValveRawData.out_temp = T[1];
ValveRawData.atom_temp = T[2];
ValveRawData.in_press = ValveRawData.in_press_raw - ValveRawData.atom_press;
ValveRawData.out_press = ValveRawData.out_press_raw - ValveRawData.atom_press;
ValveRawData.in_out_press_diff = ValveRawData.in_press - ValveRawData.out_press;
logDebug("in_press: %d, out_press: %d, atom_press: %d\r\n", ValveRawData.in_press, ValveRawData.out_press, ValveRawData.atom_press);
logDebug("in_temp: %d, out_temp: %d, atom_temp: %d\r\n", ValveRawData.in_temp, ValveRawData.out_temp, ValveRawData.atom_temp);
logDebug("in_out_press_diff: %d\r\n", ValveRawData.in_out_press_diff);
// 刷新ValveRawData_buffer,把之前的ValveRawData按时间顺序向右滑动
// 最新的ValveRawData 存在数组[4]
slideValveRawDataBuffer(&ValveRawData);
loop = loop + 1;
return (events ^ BMP390_EVT_READ);
}
return 0;
}
2025-05-22 17:59:32 +08:00
void VALVE_SetInfo()
{
ValveInfo.over_press = 6200;
ValveInfo.low_press = 800;
ValveInfo.over_temp = 65;
ValveInfo.over_flow_press_diff_1kpa = 500;
ValveInfo.over_flow_press_diff_2kpa = 500;
ValveInfo.over_flow_press_diff_3kpa = 500;
}
void BSP_PRESS_Init(void)
{
PRESS_IO_SPI_Init();
2025-05-22 17:59:32 +08:00
// 中断引脚的配置
2025-05-13 17:29:54 +08:00
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeIN_PD);
GPIOA_ITModeCfg(GPIO_Pin_9, GPIO_ITMode_RiseEdge);
2025-05-13 17:29:54 +08:00
GPIOA_ModeCfg(GPIO_Pin_3, GPIO_ModeIN_PD);
GPIOA_ITModeCfg(GPIO_Pin_3, GPIO_ITMode_RiseEdge);
2025-05-13 17:29:54 +08:00
GPIOA_ModeCfg(GPIO_Pin_6, GPIO_ModeIN_PD);
GPIOA_ITModeCfg(GPIO_Pin_6, GPIO_ITMode_RiseEdge);
PWR_PeriphWakeUpCfg(ENABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
PFIC_EnableIRQ(GPIO_A_IRQn);
// IN
ret = BMP390_IN_InterfaceInit(&DevIn, BMP3_SPI_INTF);
bmp3_check_rslt("BMP390_OUT_InterfaceInit", ret);
ret = bmp3_init(&DevIn);
bmp3_check_rslt("bmp3_init", ret);
settings.int_settings.drdy_en = BMP3_ENABLE;
settings.int_settings.latch = BMP3_INT_PIN_LATCH;
settings.int_settings.level = BMP3_INT_PIN_ACTIVE_HIGH;
settings.int_settings.output_mode = BMP3_INT_PIN_PUSH_PULL;
settings.press_en = BMP3_ENABLE;
settings.temp_en = BMP3_ENABLE;
2025-05-22 17:59:32 +08:00
settings.odr_filter.press_os = BMP3_OVERSAMPLING_2X; // BMP3_OVERSAMPLING_2X
settings.odr_filter.temp_os = BMP3_OVERSAMPLING_2X; // BMP3_OVERSAMPLING_2X
settings.odr_filter.odr = BMP3_ODR_0_39_HZ; // BMP3_ODR_1_5_HZ
settings.odr_filter.iir_filter = BMP3_IIR_FILTER_COEFF_1; // BMP3_IIR_FILTER_COEFF_3
settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN | BMP3_SEL_PRESS_OS | BMP3_SEL_TEMP_OS | BMP3_SEL_ODR | BMP3_SEL_DRDY_EN | BMP3_SEL_IIR_FILTER | BMP3_SEL_OUTPUT_MODE | BMP3_SEL_LEVEL | BMP3_SEL_LATCH;
ret = bmp3_set_sensor_settings(settings_sel, &settings, &DevIn);
bmp3_check_rslt("bmp3_set_sensor_settings", ret);
// OUT
ret = BMP390_OUT_InterfaceInit(&DevOut, BMP3_SPI_INTF);
bmp3_check_rslt("BMP390_OUT_InterfaceInit", ret);
ret = bmp3_init(&DevOut);
bmp3_check_rslt("bmp3_init", ret);
settings.int_settings.drdy_en = BMP3_ENABLE;
settings.int_settings.latch = BMP3_INT_PIN_LATCH;
settings.int_settings.level = BMP3_INT_PIN_ACTIVE_HIGH;
settings.int_settings.output_mode = BMP3_INT_PIN_PUSH_PULL;
settings.press_en = BMP3_ENABLE;
settings.temp_en = BMP3_ENABLE;
settings.odr_filter.press_os = BMP3_OVERSAMPLING_2X;
settings.odr_filter.temp_os = BMP3_OVERSAMPLING_2X;
2025-03-21 11:44:42 +08:00
settings.odr_filter.odr = BMP3_ODR_0_39_HZ;
settings.odr_filter.iir_filter = BMP3_IIR_FILTER_COEFF_1;
settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN | BMP3_SEL_PRESS_OS | BMP3_SEL_TEMP_OS | BMP3_SEL_ODR | BMP3_SEL_DRDY_EN | BMP3_SEL_IIR_FILTER | BMP3_SEL_OUTPUT_MODE | BMP3_SEL_LEVEL | BMP3_SEL_LATCH;
ret = bmp3_set_sensor_settings(settings_sel, &settings, &DevOut);
bmp3_check_rslt("bmp3_set_sensor_settings", ret);
// ATOM
ret = BMP390_ATOM_InterfaceInit(&DevAtom, BMP3_SPI_INTF);
bmp3_check_rslt("BMP390_ATOM_InterfaceInit", ret);
ret = bmp3_init(&DevAtom);
bmp3_check_rslt("bmp3_init", ret);
settings.int_settings.drdy_en = BMP3_ENABLE;
settings.int_settings.latch = BMP3_INT_PIN_LATCH;
settings.int_settings.level = BMP3_INT_PIN_ACTIVE_HIGH;
settings.int_settings.output_mode = BMP3_INT_PIN_PUSH_PULL;
settings.press_en = BMP3_ENABLE;
settings.temp_en = BMP3_ENABLE;
settings.odr_filter.press_os = BMP3_OVERSAMPLING_2X;
settings.odr_filter.temp_os = BMP3_OVERSAMPLING_2X;
2025-03-21 11:44:42 +08:00
settings.odr_filter.odr = BMP3_ODR_0_39_HZ;
settings.odr_filter.iir_filter = BMP3_IIR_FILTER_COEFF_1;
settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN | BMP3_SEL_PRESS_OS | BMP3_SEL_TEMP_OS | BMP3_SEL_ODR | BMP3_SEL_DRDY_EN | BMP3_SEL_IIR_FILTER | BMP3_SEL_OUTPUT_MODE | BMP3_SEL_LEVEL | BMP3_SEL_LATCH;
ret = bmp3_set_sensor_settings(settings_sel, &settings, &DevAtom);
bmp3_check_rslt("bmp3_set_sensor_settings", ret);
press_task_id = TMOS_ProcessEventRegister(BMP390_ProcessEvent);
tmos_set_event(press_task_id, BMP390_IN_START);
2025-05-22 17:59:32 +08:00
// tmos_set_event(press_task_id, BMP390_OUT_START);
// tmos_set_event(press_task_id, BMP390_ATOM_START);
VALVE_SetInfo();
}
/**
* @brief
*
* @param ref_value
* @param measured_value
* @param tolerance
*
* @return uint8_t 1 0
*/
uint8_t isWithinTolerance(int32_t ref_value, int32_t measured_value, uint8_t tolerance)
{
if ((measured_value - tolerance <= ref_value) && (ref_value <= measured_value + tolerance))
{
return 1; // 在范围内
}
else
{
return 0; // 不在范围内
}
}
uint16_t Check_ProcessEvent(uint8_t task_id, uint16_t events)
{
if (events & CHECK_EVT_START)
{
// logDebug("fault_state = %d \r\n",fault_state);
2025-05-22 17:59:32 +08:00
if (!fault_state)
{
2025-05-22 17:59:32 +08:00
// TODO:状态切换不对
if (gValveData.switch_status == kOpened)
{
2025-05-22 17:59:32 +08:00
// 超压检测
// 后端关阀进气端压力超过阈值6200关阀
// 流量0.45时候进气端压力超过阈值6200关阀
if (ValveRawData.in_press >= ValveInfo.over_press)
{
logError("******************************");
logError("超压关阀");
logDebug("in_press = %d; over_press = %d", ValveRawData.in_press, ValveInfo.over_press);
VALVE_CLOSE();
fault_state = 1;
tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS));
}
// 欠压检测
else if (ValveRawData.in_press <= ValveInfo.low_press)
{
VALVE_CLOSE();
fault_state = 2;
tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS));
logError("******************************");
logError("欠压关阀");
}
if (isWithinTolerance(ValveRawData_buffer[2].in_press, ValveRawData_buffer[4].in_press, 50)
&& ValveRawData_buffer[4].in_out_press_diff >= 900)
{
logError("******************************");
logError("点火开阀");
for (int i = 2; i < 5; i++)
{
logDebug("[%d]: in_press = %d; out_press = %d; in_out_press_diff = %d", i, ValveRawData_buffer[i].in_press, ValveRawData_buffer[i].out_press, ValveRawData_buffer[i].in_out_press_diff);
}
VALVE_OPEN();
tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS));
}
else
{
logDebug("点火开阀失败");
for (int i = 2; i < 5; i++)
{
logDebug("[%d]: in_press = %d; out_press = %d; in_out_press_diff = %d", i
, ValveRawData_buffer[i].in_press, ValveRawData_buffer[i].out_press, ValveRawData_buffer[i].in_out_press_diff);
}
}
#if 0
// 1、过流自动关闭
// 进气端压力2kpa时额定流量调到0.9
// 进气端压力升到 3kpa左右时阀门不能关流量不超过1.4
// 3、进气端压力 1kpa左右时出气端阀口全开需要关闭(过流自动关闭)
// if (isWithinTolerance(1000, ValveRawData.in_press, 50)
// && ValveRawData.in_out_press_diff)
// {
// /* code */
// }
// 进气端压力2kpa时额定流量调到1.4(切断流量)要关阀
if (ValveRawData.in_out_press_diff >= ValveInfo.over_flow_press_diff_2kpa)
{
if (keydown_flag > 0)
{
logDebug("keydown_time !%d", keydown_time);
keydown_time++;
if (keydown_time > 25)
{
keydown_time = 0;
keydown_flag = 0;
}
}
else
{
keydown_time = 0;
VALVE_CLOSE();
logError("******************************");
fault_state = 3;
tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS));
logDebug("Over current status !");
}
}
#endif
}
2025-05-22 17:59:32 +08:00
else if (gValveData.switch_status == kClosed)
{
2025-05-22 17:59:32 +08:00
// 点火开阀
// 监测ValveRawData_buffer当前最新的压差值大于上一秒的压差
if (isWithinTolerance(ValveRawData_buffer[2].in_press, ValveRawData_buffer[4].in_press, 50)
&& ValveRawData_buffer[4].in_out_press_diff >= 900)
{
2025-05-22 17:59:32 +08:00
logError("******************************");
logError("点火开阀");
for (int i = 2; i < 5; i++)
{
2025-05-22 17:59:32 +08:00
logDebug("[%d]: in_press = %d; out_press = %d; in_out_press_diff = %d", i, ValveRawData_buffer[i].in_press, ValveRawData_buffer[i].out_press, ValveRawData_buffer[i].in_out_press_diff);
}
2025-05-22 17:59:32 +08:00
VALVE_OPEN();
tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS));
}
else
{
2025-05-22 17:59:32 +08:00
logDebug("点火开阀失败");
for (int i = 2; i < 5; i++)
{
logDebug("[%d]: in_press = %d; out_press = %d; in_out_press_diff = %d", i
, ValveRawData_buffer[i].in_press, ValveRawData_buffer[i].out_press, ValveRawData_buffer[i].in_out_press_diff);
}
}
}
2025-05-22 17:59:32 +08:00
// 点火开阀
// 超温关阀功能:检测至少两个传感器的温度超过阈值
if (!valve_safety.over_temp_flag && gValveData.switch_status == kOpened)
2025-05-22 14:08:24 +08:00
{
2025-05-22 17:59:32 +08:00
// 计算超过阈值的传感器数量
2025-05-22 14:08:24 +08:00
uint8_t over_temp_count = 0;
2025-05-22 17:59:32 +08:00
// 检查三个传感器的温度是否超过阈值
if (T[0] > SAFETY_OVER_TEMP_THRESHOLD) over_temp_count++;
if (T[1] > SAFETY_OVER_TEMP_THRESHOLD) over_temp_count++;
if (T[2] > SAFETY_OVER_TEMP_THRESHOLD) over_temp_count++;
// 如果至少有两个传感器超过阈值,触发关阀
if (over_temp_count >= 2)
2025-05-22 14:08:24 +08:00
{
logDebug("Over temperature detected! T1=%d, T2=%d, T3=%d", T[0], T[1], T[2]);
valve_safety.over_temp_flag = 1;
2025-05-22 17:59:32 +08:00
motor_flag = 2; // 触发关阀
2025-05-22 14:08:24 +08:00
}
}
2025-05-22 17:59:32 +08:00
#if 0
// 点火开阀功能:检测燃气灶打开但阀门关闭的情况
// 当阀门关闭时,检测用气需求
if (gValveData.switch_status == kClosed)
2025-05-22 14:08:24 +08:00
{
2025-05-22 17:59:32 +08:00
// 检测用气特征:出口压力比大气压低一定值,表示下游有用气需求
// P[1]为出口压力P[2]为大气压
if (P[2] > P[1] && (P[2] - P[1] >= SAFETY_GAS_REQUEST_PRESS_DIFF))
2025-05-22 14:08:24 +08:00
{
valve_safety.auto_open_count++;
logDebug("Auto open detect: %d", valve_safety.auto_open_count);
2025-05-22 17:59:32 +08:00
// 连续多次检测到用气需求,触发开阀
if (valve_safety.auto_open_count >= SAFETY_AUTO_OPEN_THRESHOLD && !valve_safety.auto_open_flag)
2025-05-22 14:08:24 +08:00
{
logDebug("Auto opening valve due to gas usage detected!");
valve_safety.auto_open_flag = 1;
2025-05-22 17:59:32 +08:00
// 设置motor_flag为1触发开阀
2025-05-22 14:08:24 +08:00
motor_flag = 1;
}
}
else
{
2025-05-22 17:59:32 +08:00
// 重置计数器
2025-05-22 14:08:24 +08:00
valve_safety.auto_open_count = 0;
}
}
else
{
2025-05-22 17:59:32 +08:00
// 阀门开启状态,重置检测计数和标志
2025-05-22 14:08:24 +08:00
valve_safety.auto_open_count = 0;
2025-05-22 17:59:32 +08:00
valve_safety.auto_open_flag = 0;
2025-05-22 14:08:24 +08:00
}
2025-05-22 17:59:32 +08:00
// 微泄漏关阀功能:检测微小气流并自动关闭阀门
// 当阀门打开时,检测微泄漏情况
if (gValveData.switch_status == kOpened)
2025-05-22 14:08:24 +08:00
{
2025-05-22 17:59:32 +08:00
// 检测微泄漏特征:入口和出口压差非常小,但存在持续的小气流
// P[0]为入口压力P[1]为出口压力
// 压差范围大于0确保有流量但小于阈值表示流量低于0.3L/min
if (P[0] > P[1] && (P[0] - P[1] > 0) && (P[0] - P[1] < SAFETY_MICRO_LEAK_PRESS_DIFF))
2025-05-22 14:08:24 +08:00
{
valve_safety.micro_leak_count++;
logDebug("Micro leak detect: %d, pressure diff: %d", valve_safety.micro_leak_count, P[0] - P[1]);
2025-05-22 17:59:32 +08:00
// 连续多次检测到微泄漏,触发关阀
if (valve_safety.micro_leak_count >= SAFETY_MICRO_LEAK_THRESHOLD && !valve_safety.micro_leak_flag)
2025-05-22 14:08:24 +08:00
{
logDebug("Auto closing valve due to micro leak detected!");
valve_safety.micro_leak_flag = 1;
2025-05-22 17:59:32 +08:00
// 设置motor_flag为2触发关阀
2025-05-22 14:08:24 +08:00
motor_flag = 2;
}
}
else
{
2025-05-22 17:59:32 +08:00
// 不满足微泄漏条件,重置计数器
2025-05-22 14:08:24 +08:00
valve_safety.micro_leak_count = 0;
}
}
else
{
2025-05-22 17:59:32 +08:00
// 阀门关闭状态,重置检测计数和标志
2025-05-22 14:08:24 +08:00
valve_safety.micro_leak_count = 0;
2025-05-22 17:59:32 +08:00
valve_safety.micro_leak_flag = 0;
2025-05-22 14:08:24 +08:00
}
2025-05-22 17:59:32 +08:00
#endif
// 关灶关火 ^P很小延时后关闭
//^p与大气压
}
2025-05-22 17:59:32 +08:00
// logDebug("motor_flag_end = %d",motor_flag);
2025-05-22 17:59:32 +08:00
// 手动关阀
if (motor_flag == 1)
{
motor_flag = 0;
2025-05-13 18:04:46 +08:00
LED_VALVE_OPEN;
VALVE_OPEN();
2025-05-22 17:59:32 +08:00
keydown_flag = 1;
IotFlag_t.Valve_Open_flag = 1;
2025-05-22 17:59:32 +08:00
fault_state = 0;
logDebug("motor/LED open!!!");
tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS));
}
2025-05-22 17:59:32 +08:00
else if (motor_flag == 2)
{
motor_flag = 0;
LED_VALVE_CLOSE;
2025-05-13 18:04:46 +08:00
VALVE_CLOSE();
2025-05-22 17:59:32 +08:00
// fault_state = 4;
// 微泄漏关阀后重置标志
if (valve_safety.micro_leak_flag)
2025-05-22 14:08:24 +08:00
{
valve_safety.micro_leak_flag = 0;
logDebug("Micro leak protection activated");
}
2025-05-22 17:59:32 +08:00
// 超温关阀后重置标志
if (valve_safety.over_temp_flag)
2025-05-22 14:08:24 +08:00
{
valve_safety.over_temp_flag = 0;
logDebug("Over temperature protection activated");
}
logDebug("motor/LED close!!!");
tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS));
}
2025-05-22 17:59:32 +08:00
else if (motor_flag == 3)
{
motor_flag = 0;
2025-05-22 17:59:32 +08:00
if (gValveData.switch_status == kOpened)
{
LED_VALVE_OPEN;
2025-05-22 17:59:32 +08:00
}
else
{
LED_VALVE_CLOSE;
}
// DelayMs(500);
}
2025-05-22 17:59:32 +08:00
tmos_start_task(check_task_id, CHECK_EVT_START, MS1_TO_SYSTEM_TIME(200)); // 100
return (events ^ CHECK_EVT_START);
}
if (events & MOTOR_STOP_EVT)
{
VALVE_STOP();
2025-05-22 17:59:32 +08:00
if (gValveData.switch_status == kClosed)
{
gValveData.switch_status = kOpened;
}
else if (gValveData.switch_status == kOpened)
{
gValveData.switch_status = kClosed;
}
logDebug("motor STOP");
// DelayMs(1500);
// if(fault_state == 4)
// {
// IotFlag_t.Valve_Close_flag = 1;
// Iot_Send_Data();
// }
return (events ^ MOTOR_STOP_EVT);
}
return 0;
}
void Function_Check(void)
{
check_task_id = TMOS_ProcessEventRegister(Check_ProcessEvent);
tmos_set_event(check_task_id, CHECK_EVT_START);
}
__INTERRUPT
__HIGH_CODE
void GPIOA_IRQHandler(void)
{
2025-05-13 17:29:54 +08:00
if (R16_PA_INT_IF & GPIO_Pin_9)
{
2025-05-13 17:29:54 +08:00
R16_PA_INT_IF = GPIO_Pin_9;
2025-05-22 17:59:32 +08:00
flag = 1;
tmos_set_event(press_task_id, BMP390_EVT_READ);
}
2025-05-13 17:29:54 +08:00
else if (R16_PA_INT_IF & GPIO_Pin_3)
{
2025-05-13 17:29:54 +08:00
R16_PA_INT_IF = GPIO_Pin_3;
2025-05-22 17:59:32 +08:00
flag = 2;
tmos_set_event(press_task_id, BMP390_EVT_READ);
}
2025-05-13 17:29:54 +08:00
else if (R16_PA_INT_IF & GPIO_Pin_6)
{
2025-05-13 17:29:54 +08:00
R16_PA_INT_IF = GPIO_Pin_6;
2025-05-22 17:59:32 +08:00
flag = 3;
tmos_set_event(press_task_id, BMP390_EVT_READ);
}
}