You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

水流量传感器water_flow_read函数测试异常求助:预期OKAY却返回ERROR

水流量传感器water_flow_read函数断言失败:期望OKAY(1)却返回ERROR(2)

问题概述

断言错误:C++ FAIL: Expected 1 Was 2,函数运行返回异常值。状态定义:UNINITIALIZED=0,OKAY=1,ERROR=2。

在测试17-500 ml/s的有效流量范围时,water_flow_read函数始终返回ERROR,无法正确识别有效流量区间。

核心问题分析

1. 测试逻辑与函数依赖不匹配

测试代码中调用bsp_set_digital_value(100)模拟流量,但water_flow_read实际依赖的是中断统计的pulse_counter变量,而非引脚电平。如果测试时未正确设置pulse_counter,计算出的flow_rate会是0,远低于最小阈值17,导致状态保持为ERROR。

2. 函数初始化判断逻辑颠倒

函数开头的if (status != UNINITIALIZED)逻辑错误:

  • 若模块未初始化(status == UNINITIALIZED),函数直接返回UNINITIALIZED(0),但测试用例中第一次调用water_flow_read(NULL)期望返回ERROR(2),与预期不符。
  • 正确逻辑应为:模块未初始化时直接返回ERROR;已初始化时再执行流量计算。

3. 整数除法导致计算偏差

流量计算式*flow_rate = WATER_FLOW_MAX_PER_SEC * pulse_counter / cab_factor存在两个问题:

  • 整数溢出:若WATER_FLOW_MAX_PER_SEC * pulse_counter结果超过uint16_t上限(65535),会导致计算结果错误。
  • 精度丢失:先乘后除会直接舍去小数部分,可能导致计算出的流量值低于实际值,无法达到最小阈值17。

修复方案

1. 修正water_flow_read函数逻辑

调整初始化判断顺序,优化计算方式避免精度与溢出问题:

uint8_t water_flow_read(uint16_t *flow_rate)
{
    // 未初始化直接返回ERROR
    if (status == UNINITIALIZED)
    {
        return ERROR;
    }

    uint8_t current_status = ERROR;
    if (flow_rate != NULL)
    {
        // 用浮点计算保证精度,再转成uint16_t
        *flow_rate = (uint16_t)(((float)pulse_counter / cab_factor) * WATER_FLOW_MAX_PER_SEC);
        
        // 校验流量是否在有效区间
        if ((*flow_rate >= WATER_FLOW_MIN_PER_SEC) && (*flow_rate <= WATER_FLOW_MAX_PER_SEC))
        {
            current_status = OKAY;
        }

        // 重置脉冲计数器
        bsp_interrupt_disable();
        pulse_counter = 0;
        bsp_interrupt_enable();
    }

    return current_status;
}

2. 修正测试代码逻辑

测试时直接设置pulse_counter模拟对应流量的脉冲数(需确保该变量在测试环境可访问):

void test_water_flow_read(void)
{
    // 测试未初始化状态
    TEST_ASSERT_EQUAL_UINT8(ERROR, water_flow_read(NULL));

    // 初始化模块(补充初始化函数,将status设为非UNINITIALIZED)
    water_flow_init();

    uint16_t value = 0;
    // 模拟100ml/s对应的脉冲数(根据实际参数计算,示例值)
    pulse_counter = 200;
    TEST_ASSERT_EQUAL_UINT8(OKAY, water_flow_read(&value));
    TEST_ASSERT_EQUAL_UINT16(100, value);

    // 模拟600ml/s对应的脉冲数(超过最大值)
    pulse_counter = 1200;
    TEST_ASSERT_EQUAL_UINT8(ERROR, water_flow_read(&value));
}

额外注意事项

  • 确保pulse_counter为全局变量或通过测试接口可修改。
  • 若坚持使用整数计算,需用32位临时变量存储中间结果避免溢出,例如:*flow_rate = (uint16_t)(((uint32_t)WATER_FLOW_MAX_PER_SEC * pulse_counter) / cab_factor);
  • 补充water_flow_init()函数,将status设置为OKAY或其他非UNINITIALIZED状态。

内容的提问来源于stack exchange,提问作者Bi Tube

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 07:40:39