水流量传感器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
相关产品推荐
相关产品推荐

