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?

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Is encVal recognized as a global outside the routine? \$\endgroup\$
    – Andy aka
    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\$
    – user16324
    Dec 1, 2020 at 14:33
  • 1
    \$\begingroup\$ Maybe show more code \$\endgroup\$
    – Mike
    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\$ 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\$
    – Lundin
    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).

\$\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

\$\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\$
    – Oskar Skog
    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\$
    – Justme
    Oct 23, 2022 at 8:14

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.