预定义条件仅在第一时间计算

时间:2016-01-08 08:09:44

标签: c gpio

我已经实现了一个必须执行操作的功能,然后按下并释放按钮。

void debouncedAction(bool condition, void (* action)()) {
    if(condition) {
        HAL_Delay(DEBOUNCE_TIME);
        if(condition) {
            while(condition) {
            }
            action();
        }
    }
}

预定义条件

#define BTN_PUSHED              (HAL_GPIO_ReadPin(BTN_PORT, BTN_PIN) == GPIO_PIN_SET)

调试时我发现每次都没有计算条件(正如我想的那样),但只是在第一次调用时。因此,循环变得无限。错误在哪里?

3 个答案:

答案 0 :(得分:2)

“错误”是调用函数时使用的表达式仅计算一次,并且该表达式的结果作为参数的值传递。这就是按值传递的方式,它传递一个值。

如果希望在函数中多次调用表达式,则应该使条件成为可以调用的函数的指针,如action参数。

答案 1 :(得分:0)

虽然约阿希姆提供的答案是正确的,但这可能会提供更多的亮点。当您调用去抖动例程时,它可能看起来像这样(我假设您有一个名为onButtonAction的函数来处理'动作'):

debouncedAction(BTN_PUSHED, onButtonAction);

预编译器将替换此行中BTN_PUSHED宏的主体:

debouncedAction((HAL_GPIO_ReadPin(BTN_PORT, BTN_PIN) == GPIO_PIN_SET),
    onButtonAction);

因此评估(HAL_GPIO_ReadPin(BTN_PORT, BTN_PIN) == GPIO_PIN_SET)条件并通过值'传递给函数。

如果' debouncedAction'函数需要是通用的,考虑将函数指针作为条件参数传递,方法与action参数相同。

void debouncedAction(bool (* condition)(), void (* action)())

然后定义一个函数来测试GPIO状态:

bool buttonPushed(void){ return BTN_PUSHED; }

debouncedAction函数的调用现在看起来像这样:

debouncedAction(buttonPushed, onButtonAction);

答案 2 :(得分:0)

工作版本是

void debouncedAction(bool (* condition)(), void (* action)()) {
    if(condition()) {
        HAL_Delay(DEBOUNCE_TIME);
        if(condition()) {
            while(condition()) {
            }
            action();
        }
    }
}

void debouncedAction(bool (* condition)(), void (* action)()) {
    if(!condition()) {
        return;
    }
    HAL_Delay(DEBOUNCE_TIME);
    if(!condition()) {
        return;
    }
    while(condition()) {
    }
    action();
}