0
\$\begingroup\$

My question is again about modifying variables inside the ISR. If the variable used only inside of ISR, I don't have to declare it as volatile, right? After some researching, I figured out that variable need to be declared as static, and inside of ISR function. But it also didn't help.
I'm using Arduino Ide, so don't have many debugging options. I'm using an LED indicator for checking if the variable has incremented, as you can see below:

ISR(TIMER2_COMPA_vect) {
 static unsigned int count20ms = 0;
 count20ms += 5;
 PORTD ^= (1 << PD6); // Indicates that ISR executes
 if (count20ms == 10) {
 PORTD ^= (1 << PD7); // Indicates that counter incremented
 count20ms = 0;
 }
}

I can observe that ISR executes through a blinking LED on PD6. But Condition count20ms == 10 is never true . And thus, the LED connected to the PD7 never blinks.
How should a static variable behave ?

Bort
5,3205 gold badges36 silver badges58 bronze badges
asked Jun 16, 2016 at 11:32
\$\endgroup\$
9
  • 1
    \$\begingroup\$ Not sure why this does not work. However here are 2 general comments. First, it is safer to test incrementing variables as ">=" rather than "==". This in case you incremented it unexpectedly past the intended limit. Also, attempt to only do what is necessary in an interrupt. Set a flag and perform time consuming operations like I/O operations in normal code space. \$\endgroup\$ Commented Jun 16, 2016 at 11:53
  • 1
    \$\begingroup\$ It certainly looks like it should work as written. The problem may be in an area that you're not showing us. For example, are you sure that both LEDs are wired and working as intended? \$\endgroup\$ Commented Jun 16, 2016 at 11:56
  • \$\begingroup\$ Check the value of the DDRD register to check that PD7 is configured as an output. You could also check this and the physical connection quickly in one fell swoop by swapping PD6 and PD7 in your code. \$\endgroup\$ Commented Jun 16, 2016 at 12:05
  • \$\begingroup\$ Wires and DDRD is fine, also changing to ">" is not helping \$\endgroup\$ Commented Jun 16, 2016 at 12:09
  • \$\begingroup\$ What about the LED resistor value? Maybe you accidentally selected a higher resistance than you intended. Did you try swapping PD6 and PD7 in the code? \$\endgroup\$ Commented Jun 16, 2016 at 12:24

2 Answers 2

3
\$\begingroup\$

Folk on avrfreaks.net answered to me

Blockquote Yup, thought so, you enable COMPA, COMPB and OVF interrupts but only provide ISR() for COMPA. As soon as the other two conditions occur they'll jump to _bad_interrupt and from there "JMP 0" so the AVR keeps "resetting".

I didnt't provide interrupt handler for interrupts I had enabled. AVR compiler's default action to this situation is reset.

Setup code, where TIMSK2 is responsible for enabling interrupts:

void setup() {
 DDRD = 0xff;
 TCCR2A = (1 << WGM12); 
 TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20); 
 TIMSK2 = 0x07; // <<<<< Enabling 3 Interrupts vectors
 TCNT2 = 0x00; 
 OCR2A = 250; 
}

Enabling 3 Interrupts vectors, but providing only one handler. That caused AVR to reset.

More about AVR interrputs here

answered Jun 16, 2016 at 13:38
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thanks for updating readers with the fix for the problem. For the benefit of other members here who may want to read it, this is the link to your parallel question on AVR Freaks, where you got that answer and explanation about the bug in your code (although there was no bug in the part of the code which you supplied in your original question here on EE.SE). \$\endgroup\$ Commented Jun 17, 2016 at 11:10
0
\$\begingroup\$

So, if variable used only inside of ISR, I don't have to declare it as volatile, right?

Volatile is used if a variable may change with out the knowledge of the compiler. For instance, if you read a register twice the compiler may decide the second read is useless and optimize it out. Declaring a variable used to read a register volatile will cause the compiler to do what you coded. It is also used for variables that have no apparent purpose. For instance, a variable setup to only count the number of times through a section of code can be used in debugging through inspection using the IDE (not with the Arduino IDE but with others). Since the variable appears to the compiler as unused, the compiler may optimize it out.

answered Jun 16, 2016 at 11:58
\$\endgroup\$
1
  • 1
    \$\begingroup\$ This explains what volatile does. Doesn't answer his question though. \$\endgroup\$ Commented Jun 16, 2016 at 12:20

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.