预定义条件仅在第一次计算
predefined condition calculates at first time only
我已经实现了一个函数,它必须执行按钮被按下和释放的动作。
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)
在调试时我发现条件不是每次都计算(正如我所想的那样),而是只在第一次调用时计算。因此while循环变为无限。哪里出错了?
"error"是调用函数时使用的表达式只计算一次,该表达式的结果作为参数的值传递。这就是 按值传递 的工作原理,它传递单个值。
如果你想在一个函数中多次调用一个表达式,你应该使条件成为一个指向可以调用的函数的指针,比如你的 action
参数。
虽然 Joachim 提供的答案是正确的,但这可能会提供更多信息。当您调用去抖例程时,它可能看起来像这样(我假设您有一个名为 onButtonAction
的函数来处理 'action'):
debouncedAction(BTN_PUSHED, onButtonAction);
pre-compiler 将替换此行中 BTN_PUSHED 宏的主体:
debouncedAction((HAL_GPIO_ReadPin(BTN_PORT, BTN_PIN) == GPIO_PIN_SET),
onButtonAction);
因此 (HAL_GPIO_ReadPin(BTN_PORT, BTN_PIN) == GPIO_PIN_SET)
条件被评估并传递给函数 'by value'。
如果 'debouncedAction' 函数需要通用,请考虑将函数指针作为条件参数传递,方法与操作参数相同。
void debouncedAction(bool (* condition)(), void (* action)())
然后定义一个函数来测试GPIO状态:
bool buttonPushed(void){ return BTN_PUSHED; }
对 debouncedAction
函数的调用现在如下所示:
debouncedAction(buttonPushed, onButtonAction);
工作版本是
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();
}
我已经实现了一个函数,它必须执行按钮被按下和释放的动作。
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)
在调试时我发现条件不是每次都计算(正如我所想的那样),而是只在第一次调用时计算。因此while循环变为无限。哪里出错了?
"error"是调用函数时使用的表达式只计算一次,该表达式的结果作为参数的值传递。这就是 按值传递 的工作原理,它传递单个值。
如果你想在一个函数中多次调用一个表达式,你应该使条件成为一个指向可以调用的函数的指针,比如你的 action
参数。
虽然 Joachim 提供的答案是正确的,但这可能会提供更多信息。当您调用去抖例程时,它可能看起来像这样(我假设您有一个名为 onButtonAction
的函数来处理 'action'):
debouncedAction(BTN_PUSHED, onButtonAction);
pre-compiler 将替换此行中 BTN_PUSHED 宏的主体:
debouncedAction((HAL_GPIO_ReadPin(BTN_PORT, BTN_PIN) == GPIO_PIN_SET),
onButtonAction);
因此 (HAL_GPIO_ReadPin(BTN_PORT, BTN_PIN) == GPIO_PIN_SET)
条件被评估并传递给函数 'by value'。
如果 'debouncedAction' 函数需要通用,请考虑将函数指针作为条件参数传递,方法与操作参数相同。
void debouncedAction(bool (* condition)(), void (* action)())
然后定义一个函数来测试GPIO状态:
bool buttonPushed(void){ return BTN_PUSHED; }
对 debouncedAction
函数的调用现在如下所示:
debouncedAction(buttonPushed, onButtonAction);
工作版本是
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();
}