P0/P1/P2功能实现:接入业务组合根(按键/LED/过零/配网/OTA),联动、11B定时、运行记录、灯泡寿命(DP3/DP4/DP25)、CBR0 VM、512分包
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
/******************************************************************************
|
||||
* @file app_relay.c
|
||||
* @brief 继电器:请求等过零执行;超时则关强断、开放弃
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.09.04
|
||||
* @version V1.1.0
|
||||
* @history
|
||||
* - V1.1.0, 2026.09.04, cyWu, 去掉未使用计数,精简注释
|
||||
* - V1.0.0, 2026.09.04, cyWu, 首次发布
|
||||
******************************************************************************/
|
||||
|
||||
#include "system/includes.h"
|
||||
#include "app_relay.h"
|
||||
#include "bsp_hw.h"
|
||||
#include "board_pin.h"
|
||||
#include "jb_product.h"
|
||||
|
||||
#define LOG_TAG_CONST APP
|
||||
#define LOG_TAG "[RELAY]"
|
||||
#define LOG_INFO_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t request; /**< 上层意图:0=关 1=开 */
|
||||
uint8_t actual; /**< 过零后的 GPIO 真值 */
|
||||
} AppRelayCtx_t;
|
||||
|
||||
static AppRelayCtx_t s_relay;
|
||||
|
||||
/**
|
||||
* @brief 写继电器 GPIO 并更新 actual(过零 ISR / 超时路径)
|
||||
* @param on 1=吸合 0=断开
|
||||
* @return 无
|
||||
*/
|
||||
static void relay_apply(uint8_t on)
|
||||
{
|
||||
bsp_relay_set(on);
|
||||
s_relay.actual = on;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化继电器:GPIO 上电默认关;P0 无 VM,请求=实际=关
|
||||
* @return 无
|
||||
*/
|
||||
void app_relay_init(void)
|
||||
{
|
||||
s_relay.request = 0;
|
||||
s_relay.actual = 0;
|
||||
bsp_relay_set(0);
|
||||
log_info("relay init, request=off actual=off\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 请求加热开/关(手动/APP 写 DP0/定时/联动统一入口)
|
||||
* @param on 1=开 0=关
|
||||
* @return 无
|
||||
*/
|
||||
void app_relay_request(uint8_t on)
|
||||
{
|
||||
on = on ? 1 : 0;
|
||||
|
||||
if (on == s_relay.request) {
|
||||
return; /* 意图没变:不重复发起(避免连续同向请求反复计超时) */
|
||||
}
|
||||
s_relay.request = on;
|
||||
|
||||
#if BOARD_ZC_ENABLE
|
||||
if (on == s_relay.actual) {
|
||||
/* 例如 PC3 已因超时强关(actual=0),收到关请求:无需等沿,直接同步 */
|
||||
log_info("request %s but actual already %d, sync\n", on ? "ON" : "OFF",
|
||||
s_relay.actual);
|
||||
return;
|
||||
}
|
||||
log_info("request %s, wait zc edge\n", on ? "ON" : "OFF");
|
||||
/* 等 app_zc_poll 计数 / bsp_zc 沿回调执行 */
|
||||
#else
|
||||
/* 无过零(调试):开不吸合,关立即强断(规格书 7.2 / 4 章) */
|
||||
if (on) {
|
||||
gDevData.fault_code = 2;
|
||||
log_info("zc disabled: open request rejected, stay off\n");
|
||||
s_relay.request = 0; /* 放弃开请求,回落到实际(不吸合) */
|
||||
} else {
|
||||
log_info("zc disabled: force relay off\n");
|
||||
relay_apply(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 过零沿:有 pending 则切 GPIO
|
||||
* @note FPIN ISR 上下文,禁止 printf / 写 VM / 切 BLE
|
||||
* @return 无
|
||||
*/
|
||||
void app_relay_zc_edge(void)
|
||||
{
|
||||
if (s_relay.request == s_relay.actual) {
|
||||
return; /* 无 pending,仅记录过零(由 app_zc 管超时) */
|
||||
}
|
||||
relay_apply(s_relay.request);
|
||||
/* 7.2:下一次成功过零切变后清设备故障(RAM 写,ISR 安全) */
|
||||
gDevData.fault_code = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 过零超时:关则强断,开则放弃并保持关,fault_code=2
|
||||
* @note 20ms 节拍调用;与 FPIN ISR 抢状态,关中断后复检
|
||||
* @return 无
|
||||
*/
|
||||
void app_relay_zc_timeout(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
if (s_relay.request == s_relay.actual) {
|
||||
local_irq_enable();
|
||||
return;
|
||||
}
|
||||
gDevData.fault_code = 2;
|
||||
|
||||
if (s_relay.request) {
|
||||
/* 开请求超时:禁止无过零吸合,放弃本次开请求,保持关 */
|
||||
s_relay.request = 0;
|
||||
s_relay.actual = 0;
|
||||
bsp_relay_set(0);
|
||||
} else {
|
||||
/* 关请求超时:强制断开(安全路径,规格书 7.2) */
|
||||
bsp_relay_set(0);
|
||||
s_relay.actual = 0;
|
||||
}
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 当前请求态
|
||||
* @return 1=请求开,0=请求关
|
||||
*/
|
||||
uint8_t app_relay_get_request(void)
|
||||
{
|
||||
return s_relay.request;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 当前实际吸合态
|
||||
* @return 1=已吸合,0=已断开
|
||||
*/
|
||||
uint8_t app_relay_get_actual(void)
|
||||
{
|
||||
return s_relay.actual;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 是否已同步(无 pending)
|
||||
* @return 1=request==actual
|
||||
*/
|
||||
uint8_t app_relay_synced(void)
|
||||
{
|
||||
return (s_relay.request == s_relay.actual) ? 1 : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user