Reputation: 183
I've implemented a function which must perform the action then button was pressed and released.
void debouncedAction(bool condition, void (* action)()) {
if(condition) {
HAL_Delay(DEBOUNCE_TIME);
if(condition) {
while(condition) {
}
action();
}
}
}
Predefined condition is
#define BTN_PUSHED (HAL_GPIO_ReadPin(BTN_PORT, BTN_PIN) == GPIO_PIN_SET)
While debugging I was found that condition does not calculated each time (as I thought) but only at the first call. Therefore while cycle becomes infinite. Where is the error?
Upvotes: 0
Views: 66
Reputation: 183
Working version is
void debouncedAction(bool (* condition)(), void (* action)()) {
if(condition()) {
HAL_Delay(DEBOUNCE_TIME);
if(condition()) {
while(condition()) {
}
action();
}
}
}
or
void debouncedAction(bool (* condition)(), void (* action)()) {
if(!condition()) {
return;
}
HAL_Delay(DEBOUNCE_TIME);
if(!condition()) {
return;
}
while(condition()) {
}
action();
}
Upvotes: 0
Reputation: 2320
While the answer provided by Joachim is correct, this may provide a little more light. When you make the call to the debounce routine it will probably look like this (I have assumed that you have a function called onButtonAction
to handle the 'action'):
debouncedAction(BTN_PUSHED, onButtonAction);
The pre-compiler will substitue the body of the BTN_PUSHED macro in this line:
debouncedAction((HAL_GPIO_ReadPin(BTN_PORT, BTN_PIN) == GPIO_PIN_SET),
onButtonAction);
So the (HAL_GPIO_ReadPin(BTN_PORT, BTN_PIN) == GPIO_PIN_SET)
condition is evaluated and passed to the function 'by value'.
If the 'debouncedAction' function needs to be generic, consider passing a function pointer as the condition argument, in the same way as the action argument.
void debouncedAction(bool (* condition)(), void (* action)())
And then define a function to test the GPIO state:
bool buttonPushed(void){ return BTN_PUSHED; }
The call to the debouncedAction
function now looks like this:
debouncedAction(buttonPushed, onButtonAction);
Upvotes: 1
Reputation: 409404
The "error" is that the expressions used when calling a function are evaluated only once, and the result of that expression is passed as the value of the argument. That's how pass by value works, it passes a single value.
If you want an expression to be called multiple times within a function, you should probably make the condition a pointer to a function that can be called, like your action
argument.
Upvotes: 3