2
\$\begingroup\$

I'm working on some embedded software and I ran into a problem and I cannot figure out why this block isn't working.

I set up interrupts to for several buttons, including a mechanical encoder. I used breakpoints and debugging to determine the code flow. The block that isn't working as it should is super simple.

uint8_t calcEncoderValue(void)
{
 int encVal = 0;
 if (gpio_get_pin_level(ENC_A))
 {
 encVal = 2;
 }
 
 if (gpio_get_pin_level(ENC_B))
 {
 encVal = encVal + 1;
 }
 
 return (uint8_t) encVal;
}

The code goes into the first if statement when A is HIGH, but value for encVal remains 0.

Coding doesn't get much simpler than this block, so I'm absolutely stumped. Does anyone have any idea what is going wrong here?

Mike
2,6192 gold badges17 silver badges31 bronze badges
asked Dec 1, 2020 at 14:13
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Is encVal recognized as a global outside the routine? \$\endgroup\$ Commented Dec 1, 2020 at 14:17
  • 2
    \$\begingroup\$ If this is an interrupt routine, where does it return the value to??? Presumably this is a function called by an ISR : the error may lie in the calling ISR. But if this IS the ISR it needs to update something externally visible (and declared volatile). \$\endgroup\$ Commented Dec 1, 2020 at 14:33
  • 1
    \$\begingroup\$ Maybe show more code \$\endgroup\$ Commented Dec 1, 2020 at 14:35
  • 3
    \$\begingroup\$ If this is in an ISR, then it is perfectly possible the compiler has optimised it out as it may not apparently be used elsewhere. The volatile keyword is your friend in that case. \$\endgroup\$ Commented Dec 1, 2020 at 14:39
  • 1
    \$\begingroup\$ This isn't a valid ISR on any microcontroller system I've ever heard of. Post the actual code, including which device this is for, how you set the interrupt & vector table, as well as a valid ISR. If you have no clue about any of that, you need to study the basics first. \$\endgroup\$ Commented Dec 2, 2020 at 7:42

2 Answers 2

8
\$\begingroup\$

This line:

int encVal = 0;

Creates a variable local to the ISR.

If you expect that variable name to be globally accessible then you could have problems.

Even if you have declared a global variable by that name, the local version of encVal will be changed inside the ISR and then will be discarded when the ISR returns.

As Peter comments, in the global declaration it should be declared with the volatile keyword so the compiler knows it may change at any time (changed by the ISR, in this case).

answered Dec 1, 2020 at 14:25
\$\endgroup\$
-2
\$\begingroup\$

Just another perspective. Take it with a grain of salt.

In C, when a logical operation is being evaluated, if the result is known before all subexpressions have been evaluated, then the evaluation stops, or short circuits.

A "Short Circuit Evaluation" might have happened in the "if (gpio_get_pin_level(ENC_x))".

Refer to this article https://microchipdeveloper.com/c:short-circuit-evaluation

enter image description here

answered Oct 23, 2022 at 8:02
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Short circuit evaluation refers to && and ||. There's no way for the function calls to not occur in these expressions. And declaring a temporary variable for their return values as volatile does nothing useful. \$\endgroup\$ Commented Oct 23, 2022 at 8:11
  • 1
    \$\begingroup\$ If there is a theoretical possibility for this to be a short circui evaluation problem, please at least mention where would the short circuit happen and why. \$\endgroup\$ Commented Oct 23, 2022 at 8:14

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.