删除条件配置功能,修改成联动配置DP,并且增加31天运行记录,修改程序需求

This commit is contained in:
2026-09-03 10:21:11 +08:00
parent 5377186cfb
commit d56d8204e1
31 changed files with 1609 additions and 1430 deletions
+65 -61
View File
@@ -2,17 +2,18 @@
* @file app_disp.c
* @brief CBR3 数码管显示实现
* @author cyWu <1917507415@qq.com>
* @date 2026.08.31
* @version V1.1.0,动态扫描(20ms 算段码写缓冲 + BOARD_DISP_SCAN_MS 快节拍
* 轮询点亮 1 位)+ 告警闪烁(温度/湿度管独立 500ms 亮灭,
* BOARD_DISP_ALARM_TEST 宏可强制模拟超限;fault 时 "--" 优先)
* @date 2026.09.02
* @version V2.0.0(规格书 V3.0.0):闪烁按第 8.2 节改——有**有效联动配置**
* 就按是否落在 [min,max] 闭区间闪(温度/湿度管独立 500ms 亮灭
* 出范围就闪、与风扇是否在转、联动是否被手动作废无关;无有效
* 联动不因温湿度闪;fault 时 "--" 优先。闪烁源由 app_linkage
* 500ms 任务上下文)喂 app_disp_set_temp/humi_alarm。
*
* @note ⚠ CT1642 内部只有单个 12 位锁存器(4 位选 + 8 段码),无按位显示 RAM、
* 不自动扫描,一次只点亮当前锁存的那 1 位。要让 4 位都亮且不闪,必须由 MCU
* 持续轮询:本模块用 app_disp_run()20ms)算好 4 位段码放进 s_disp_buf
* 持续轮询:本模块用 app_disp_run()20ms)算好 4 位段码放进 s_disp.buf
* 用 app_disp_scan()BOARD_DISP_SCAN_MS)每次点亮 1 位、4 位轮询。
* 告警闪烁(规格书 8.2):比较成立侧 500ms 亮/500ms 灭,与吹风解耦;
* 闪烁触发源由 app_disp_set_temp/humi_alarm 喂入(P2 条件引擎),
* 传感器故障(连续 3 次失败)优先显示 "--" 不闪。
******************************************************************************/
@@ -26,21 +27,22 @@
#define LOG_INFO_ENABLE
#include "debug.h"
static uint8_t s_inited;
/** 显示运行时:段码缓冲 + 扫描指针 + 8.2 告警闪烁 */
typedef struct {
uint8_t inited;
uint8_t buf[4]; /* 段码,下标 = com 顺序:0 温度十 / 1 温度个 / 2 湿度十 / 3 湿度个 */
uint8_t scan_idx; /* 动态扫描轮询指针 0..3 */
uint8_t temp_alarm; /* 1=温度超范围(app_linkage 喂) */
uint8_t humi_alarm; /* 1=湿度超范围(app_linkage 喂) */
uint8_t blink_phase; /* 0=亮半周期,1=灭半周期 */
uint16_t blink_ms; /* 半周期内累计毫秒 */
} AppDispCtx_t;
/* 4 位段码缓冲,下标顺序 = com 顺序:0 温度十 / 1 温度个 / 2 湿度十 / 3 湿度个 */
static uint8_t s_disp_buf[4];
static AppDispCtx_t s_disp;
static const uint8_t s_com_tbl[4] = {
BOARD_DISP_COM_TEMP_TEN, BOARD_DISP_COM_TEMP_ONE,
BOARD_DISP_COM_HUMI_TEN, BOARD_DISP_COM_HUMI_ONE
};
static uint8_t s_scan_idx; /* 动态扫描轮询指针 0..3 */
/* 告警闪烁(P1,规格书 8.2):比较成立侧 500ms 亮/500ms 灭 */
static uint8_t s_temp_alarm; /* 1=温度比较成立(P2 条件引擎喂) */
static uint8_t s_humi_alarm; /* 1=湿度比较成立(P2 条件引擎喂) */
static uint8_t s_blink_phase; /* 0=亮半周期,1=灭半周期 */
static uint16_t s_blink_ms; /* 半周期内累计毫秒 */
/* 段码索引:bsp_ct1642_seg(0~9)=数字,10='-'11=灭 */
#define SEG_MINUS 10
@@ -104,24 +106,24 @@ void app_disp_init(void)
log_info("disp disabled\n");
return;
#endif
if (s_inited) {
if (s_disp.inited) {
return;
}
s_inited = 1;
s_scan_idx = 0;
s_disp.inited = 1;
s_disp.scan_idx = 0;
bsp_ct1642_init(); /* PG0(CLK)/PG1(DATA) 推挽输出 */
/* 默认写死 25 / 60,供 P0 台上扫段验证(规格书 P0 验收) */
s_disp_buf[0] = bsp_ct1642_seg(2);
s_disp_buf[1] = bsp_ct1642_seg(5);
s_disp_buf[2] = bsp_ct1642_seg(6);
s_disp_buf[3] = bsp_ct1642_seg(0);
s_disp.buf[0] = bsp_ct1642_seg(2);
s_disp.buf[1] = bsp_ct1642_seg(5);
s_disp.buf[2] = bsp_ct1642_seg(6);
s_disp.buf[3] = bsp_ct1642_seg(0);
log_info("disp init, scan %ums\n", (unsigned)BOARD_DISP_SCAN_MS);
/* 注意:快节拍动态扫描定时器在 usr_jb_init 里注册(usr_timer_add 声明在那) */
}
/**
* @brief 业务节拍(20ms):计算 4 位要显示什么,写入段码缓冲(不直接打管)
* @note 软关机由 app_disp_scan 处理。本函数只更新 s_disp_buf。
* @note 软关机由 app_disp_scan 处理。本函数只更新 s_disp.buf。
* @return 无
*/
void app_disp_run(uint16_t dt)
@@ -130,21 +132,21 @@ void app_disp_run(uint16_t dt)
(void)dt;
return;
#endif
if (!s_inited) {
if (!s_disp.inited) {
return;
}
/* 闪烁相位推进:满 BOARD_DISP_BLINK_MS 切换亮/灭半周期 */
s_blink_ms = (uint16_t)(s_blink_ms + dt);
if (s_blink_ms >= BOARD_DISP_BLINK_MS) {
s_blink_ms = 0;
s_blink_phase ^= 1;
s_disp.blink_ms = (uint16_t)(s_disp.blink_ms + dt);
if (s_disp.blink_ms >= BOARD_DISP_BLINK_MS) {
s_disp.blink_ms = 0;
s_disp.blink_phase ^= 1;
}
#if BOARD_DISP_ALARM_TEST == 1
s_temp_alarm = 1; /* P1 调试:强制温度管闪 */
s_disp.temp_alarm = 1; /* P1 调试:强制温度管闪 */
#elif BOARD_DISP_ALARM_TEST == 2
s_humi_alarm = 1; /* P1 调试:强制湿度管闪 */
s_disp.humi_alarm = 1; /* P1 调试:强制湿度管闪 */
#endif
#if BOARD_DISP_SCAN_TEST == 1
@@ -160,45 +162,45 @@ void app_disp_run(uint16_t dt)
step = (uint8_t)((step + 1) % (sizeof(seg_seq) / sizeof(seg_seq[0])));
}
uint8_t s = seg_seq[step];
s_disp_buf[0] = s; s_disp_buf[1] = s; s_disp_buf[2] = s; s_disp_buf[3] = s;
s_disp.buf[0] = s; s_disp.buf[1] = s; s_disp.buf[2] = s; s_disp.buf[3] = s;
return;
}
#elif BOARD_DISP_SCAN_TEST == 2
/* 位扫描:4 位分别显示 1/2/3/4,定性 C1~C4 与物理管位对应 */
s_disp_buf[0] = bsp_ct1642_seg(1);
s_disp_buf[1] = bsp_ct1642_seg(2);
s_disp_buf[2] = bsp_ct1642_seg(3);
s_disp_buf[3] = bsp_ct1642_seg(4);
s_disp.buf[0] = bsp_ct1642_seg(1);
s_disp.buf[1] = bsp_ct1642_seg(2);
s_disp.buf[2] = bsp_ct1642_seg(3);
s_disp.buf[3] = bsp_ct1642_seg(4);
return;
#endif
if (app_th_is_fault()) {
/* 连续失败 3 次:双管 "--"(规格书 8.1;故障优先于闪烁,8.2) */
uint8_t m = bsp_ct1642_seg(SEG_MINUS);
s_disp_buf[0] = m; s_disp_buf[1] = m; s_disp_buf[2] = m; s_disp_buf[3] = m;
s_disp.buf[0] = m; s_disp.buf[1] = m; s_disp.buf[2] = m; s_disp.buf[3] = m;
} else if (app_th_get_valid()) {
/* 有有效采样:显示真实值;比较成立且当前在灭半周期 → 该管熄灭 */
uint8_t t1, t0, h1, h0;
disp_split_temp(app_th_get_temp_x10(), &t1, &t0);
disp_split_humi(app_th_get_humi(), &h1, &h0);
if (s_temp_alarm && s_blink_phase) {
if (s_disp.temp_alarm && s_disp.blink_phase) {
t1 = SEG_OFF;
t0 = SEG_OFF;
}
if (s_humi_alarm && s_blink_phase) {
if (s_disp.humi_alarm && s_disp.blink_phase) {
h1 = SEG_OFF;
h0 = SEG_OFF;
}
s_disp_buf[0] = bsp_ct1642_seg(t1);
s_disp_buf[1] = bsp_ct1642_seg(t0);
s_disp_buf[2] = bsp_ct1642_seg(h1);
s_disp_buf[3] = bsp_ct1642_seg(h0);
s_disp.buf[0] = bsp_ct1642_seg(t1);
s_disp.buf[1] = bsp_ct1642_seg(t0);
s_disp.buf[2] = bsp_ct1642_seg(h1);
s_disp.buf[3] = bsp_ct1642_seg(h0);
} else {
/* 尚未有有效采样:写死 25 / 60,供 P0 台上扫段验证(规格书 P0 验收) */
s_disp_buf[0] = bsp_ct1642_seg(2);
s_disp_buf[1] = bsp_ct1642_seg(5);
s_disp_buf[2] = bsp_ct1642_seg(6);
s_disp_buf[3] = bsp_ct1642_seg(0);
s_disp.buf[0] = bsp_ct1642_seg(2);
s_disp.buf[1] = bsp_ct1642_seg(5);
s_disp.buf[2] = bsp_ct1642_seg(6);
s_disp.buf[3] = bsp_ct1642_seg(0);
}
}
@@ -214,46 +216,48 @@ void app_disp_scan(void)
#if !BOARD_DISP_ENABLE
return;
#endif
if (!s_inited) {
if (!s_disp.inited) {
return;
}
#if BOARD_DISP_SCAN_TEST == 1
/* 段扫描:4 位同显一段。⭐ 值变化才刷(无鬼影),com=0xF 四位全选同显。 */
static uint8_t seg = 0;
if (seg == s_disp_buf[0]) {
if (seg == s_disp.buf[0]) {
return;
}
seg = s_disp_buf[0];
seg = s_disp.buf[0];
bsp_ct1642_send_frame(s_disp_buf[s_scan_idx], 0xF);
s_scan_idx = (uint8_t)((s_scan_idx + 1) % 4);
bsp_ct1642_send_frame(s_disp.buf[s_disp.scan_idx], 0xF);
s_disp.scan_idx = (uint8_t)((s_disp.scan_idx + 1) % 4);
#else
/* 正常显示(0) / 位选验证(2):4 位分显不同数字,必须分时轮询。
* 鬼影(切位杂段)靠 ct1642_delay 8→2 提速缩短杂段窗口来减轻。 */
bsp_ct1642_send_frame(s_disp_buf[s_scan_idx], s_com_tbl[s_scan_idx]);
s_scan_idx = (uint8_t)((s_scan_idx + 1) % 4);
bsp_ct1642_send_frame(s_disp.buf[s_disp.scan_idx], s_com_tbl[s_disp.scan_idx]);
s_disp.scan_idx = (uint8_t)((s_disp.scan_idx + 1) % 4);
#endif
}
/**
* @brief 设置温度比较成立标志:成立时温度管 500ms 闪烁(P2 条件引擎喂)
* @param en 1=成立(闪),0=不成立(常亮数值
* @brief 设置温度超范围标志:超范围时温度管 500ms 闪烁(app_linkage 喂,
* 规格书 8.2T>Tmax 或 T<Tmin;含等于不算超
* @param en 1=超范围(闪),0=带内(常亮数值)
* @return 无
*/
void app_disp_set_temp_alarm(uint8_t en)
{
s_temp_alarm = en ? 1 : 0;
s_disp.temp_alarm = en ? 1 : 0;
}
/**
* @brief 设置湿度比较成立标志:成立时湿度管 500ms 闪烁(P2 条件引擎喂)
* @param en 1=成立(闪),0=不成立(常亮数值
* @brief 设置湿度超范围标志:超范围时湿度管 500ms 闪烁(app_linkage 喂,
* 规格书 8.2H>Hmax 或 H<Hmin
* @param en 1=超范围(闪),0=带内(常亮数值)
* @return 无
*/
void app_disp_set_humi_alarm(uint8_t en)
{
s_humi_alarm = en ? 1 : 0;
s_disp.humi_alarm = en ? 1 : 0;
}
/**
@@ -262,5 +266,5 @@ void app_disp_set_humi_alarm(uint8_t en)
*/
uint8_t app_disp_is_alarm(void)
{
return (s_temp_alarm || s_humi_alarm) ? 1 : 0;
return (s_disp.temp_alarm || s_disp.humi_alarm) ? 1 : 0;
}