/****************************************************************************** * @file app_zc.c * @brief 过零业务:20ms 节拍判定 100ms 无沿超时 * @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_zc.h" #include "app_relay.h" #include "bsp_zc.h" #include "board_pin.h" #define LOG_TAG_CONST APP #define LOG_TAG "[APP_ZC]" #define LOG_INFO_ENABLE #include "debug.h" typedef struct { uint8_t initialized; uint8_t last_request; uint8_t timeout_evt; /**< 1=开放弃 2=关强断,任务上下文取走打印 */ uint16_t pending_ms; } AppZcCtx_t; static AppZcCtx_t s_zc; /** * @brief 初始化过零业务并挂继电器沿回调 * @return 无 */ void app_zc_init(void) { if (s_zc.initialized) { return; } #if BOARD_ZC_ENABLE bsp_zc_init(app_relay_zc_edge); s_zc.pending_ms = 0; s_zc.last_request = app_relay_get_request(); s_zc.initialized = 1; log_info("zc init ok\n"); #else log_info("zc disabled\n"); #endif } /** * @brief 20ms 节拍:pending 满 100ms 无沿则超时处理 * @param dt 距上次调用的毫秒数 * @return 无 */ void app_zc_poll(uint16_t dt) { #if !BOARD_ZC_ENABLE (void)dt; return; #endif if (!s_zc.initialized) { return; } if (app_relay_get_request() != s_zc.last_request) { s_zc.pending_ms = 0; s_zc.last_request = app_relay_get_request(); } if (!app_relay_synced()) { s_zc.pending_ms = (uint16_t)(s_zc.pending_ms + dt); if (s_zc.pending_ms >= BOARD_ZC_TIMEOUT_MS) { s_zc.pending_ms = 0; s_zc.timeout_evt = app_relay_get_request() ? 1 : 2; app_relay_zc_timeout(); } } else { s_zc.pending_ms = 0; } } /** * @brief 取走一次超时事件(任务上下文打印) * @return 0=无 1=开放弃 2=关强断 */ uint8_t app_zc_consume_timeout(void) { uint8_t evt = s_zc.timeout_evt; s_zc.timeout_evt = 0; return evt; }