Files
JBao_Temp_Humi_Fan_FW/apps/usr_app/app_th.c
T

184 lines
4.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/******************************************************************************
* @file app_th.c
* @brief CBR3 温湿度采集实现
* @author cyWu <1917507415@qq.com>
* @date 2026.08.31
* @version V1.1.0,发令阶段 nack 也计入连续失败;fault_code 由上层映射为 1
* (规格书 V3.0.0:fault 编号不变,DP 号随协议右移为 DP24)
******************************************************************************/
#include "app_th.h"
#include "bsp_aht20.h"
#include "board_pin.h"
#include "system/includes.h"
#define LOG_TAG_CONST APP
#define LOG_TAG "[APP_TH]"
#define LOG_ERROR_ENABLE
#define LOG_INFO_ENABLE
#include "debug.h"
extern u32 timer_get_ms(void);
extern void clr_wdt(void);
/** 采样状态机 */
typedef enum {
TH_ST_IDLE = 0, /**< 空闲,等待下一个采样周期 */
TH_ST_WAIT_DATA /**< 命令已发出,等 ≥80ms 后读数 */
} ThState_t;
typedef struct {
uint8_t inited;
ThState_t state;
uint16_t poll_ms; /**< 距上次采样的累计毫秒 */
uint32_t wait_t0; /**< 测量命令发出时刻 */
int16_t temp_x10; /**< 最近有效温度 ×10 */
uint8_t humi; /**< 最近有效湿度 % */
uint8_t valid; /**< 1=有有效采样 */
uint8_t fail_cnt; /**< 连续失败次数 */
uint8_t last_ok; /**< 最近一次采样是否成功(app_linkage 8.4 用) */
} AppThCtx_t;
static AppThCtx_t s_th;
/**
* @brief 记一次采样失败(发令 nack / 读数失败共用)
* @return 无
*/
static void th_on_fail(void)
{
if (s_th.fail_cnt < 0xFF) {
s_th.fail_cnt++;
}
s_th.last_ok = 0;
log_error("th sample fail %d\n", s_th.fail_cnt);
}
/**
* @brief 初始化温湿度模块
* @return 无
*/
void app_th_init(void)
{
#if !BOARD_TH_ENABLE
log_info("th disabled\n");
return;
#endif
if (s_th.inited) {
return;
}
bsp_aht20_init();
s_th.state = TH_ST_IDLE;
s_th.poll_ms = 0;
s_th.valid = 0;
s_th.fail_cnt = 0;
s_th.last_ok = 0;
s_th.inited = 1;
log_info("th init period=%ums\n", (unsigned)BOARD_TH_PERIOD_MS);
}
/**
* @brief 业务节拍:内部 2s 才真正采一次;IO 分离后采集与显示互不干扰
* @param dt 距上次调用的毫秒数
* @return 无
*/
void app_th_poll(uint16_t dt)
{
#if !BOARD_TH_ENABLE
(void)dt;
return;
#endif
if (!s_th.inited) {
return;
}
if (s_th.state == TH_ST_IDLE) {
s_th.poll_ms = (uint16_t)(s_th.poll_ms + dt);
if (s_th.poll_ms >= BOARD_TH_PERIOD_MS) {
s_th.poll_ms = 0;
if (bsp_aht20_measure_start() == 0) {
s_th.state = TH_ST_WAIT_DATA;
s_th.wait_t0 = timer_get_ms();
} else {
/* 发令阶段 addr nack(未插/脱落)也算一次采样失败,不能直接跳过 */
th_on_fail();
}
}
} else if (s_th.state == TH_ST_WAIT_DATA) {
clr_wdt();
if ((timer_get_ms() - s_th.wait_t0) >= BOARD_AHT20_WAIT_MS) {
int16_t t = 0;
uint8_t h = 0;
int8_t ret = bsp_aht20_measure_finish(&t, &h);
/* IO 分离后无总线竞争,finish 不会返回 -2;0=成功,-1=通讯失败 */
s_th.state = TH_ST_IDLE;
if (ret == 0) {
s_th.temp_x10 = t;
s_th.humi = h;
s_th.fail_cnt = 0;
s_th.valid = 1;
s_th.last_ok = 1;
log_info("th %d.%dC %d%%\n",
(int)(t / 10), (int)((t < 0) ? (-t % 10) : (t % 10)), h);
} else {
th_on_fail();
}
}
}
}
/**
* @brief 是否已有有效采样
* @return 1=有效,0=从未成功
*/
uint8_t app_th_get_valid(void)
{
return s_th.valid;
}
/**
* @brief 最近一次有效温度
* @return 温度 ×10
*/
int16_t app_th_get_temp_x10(void)
{
return s_th.temp_x10;
}
/**
* @brief 最近一次有效湿度
* @return 湿度 0~100 整数 %
*/
uint8_t app_th_get_humi(void)
{
return s_th.humi;
}
/**
* @brief 连续失败次数
* @return 连续失败次数
*/
uint8_t app_th_get_fail_cnt(void)
{
return s_th.fail_cnt;
}
/**
* @brief 传感器故障(连续失败 ≥ BOARD_TH_FAIL_MAX
* @return 1=故障(显示 --、fault_code=1),0=正常
*/
uint8_t app_th_is_fault(void)
{
return (s_th.fail_cnt >= BOARD_TH_FAIL_MAX) ? 1 : 0;
}
/**
* @brief 最近一次采样是否成功(规格书 8.4:联动只用本次成功值判)
* @return 1=成功,0=失败/未采样过
*/
uint8_t app_th_last_sample_ok(void)
{
return s_th.last_ok;
}