# Can't modify global variables in interrupt, despite having declared them volatile

I can't seem to get my global variables (low, high) to change inside my interrupt, despite having declared them volatile. Below is my code.

I find it strange that I can modify my global variable 'change' but modifications to 'low' and 'high' don't seem to work. I know for sure that my interrupt is being completed, since the text is reprinting to the LCD display, just that the numbers aren't being modified.

I marked out the most relevant locations with "HERE" where I think that the problem is most likely at. I also tested whether it's just because the variable turn is always 0 by adding code at the end of the ISR to see whether the global variables change or not. They don't.

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "lcd.h"
int state;
volatile int low; //HERE
volatile int high;
char scount[5];
char snum[5];
char mode;
volatile char change=0;//HERE
int main()
{
char b_high;
char b_low;
DDRD=0xf0;
DDRB=0b00000011;
PORTD |= 0b00001000;
PORTC |= (1 << PC1);
PORTC |= (1 << PC2);
PORTB |= 0b00100000;
PCICR=0b00000010;
PCMSK1=0b00000110;
sei();
init_lcd();
writecommand(0x01);
moveto(0x80);
stringout("Low:    ");
stringout("High:    ");
moveto(0xc0);
stringout("Change:high");
int low=70;
int high=85;
moveto(0x84);
itoa(low, scount, 10);
stringout(scount);
moveto(0x8d);
itoa(high, scount, 10);
stringout(scount);
while(1){
b_high = PIND & 0b00001000;
b_low = PINB & 0b00100000;
if(!b_high)
{
moveto(0xc7);
stringout("high");
mode=0;
}
if(!b_low)
{
moveto(0xc7);
stringout("low ");
mode=1;
}
if(change)//HERE
{
if(mode)
{
//low+=turn;
itoa(low, snum, 10);//HERE
moveto(0x84);
stringout("   ");
moveto(0x84);
stringout(snum);
}
else
{
//high+=turn;
itoa(high, snum, 10);//HERE
moveto(0x8d);
stringout("   ");
moveto(0x8d);
stringout(snum);
}
change=0;
}
}
return 1;
}
ISR(PCINT1_vect)
{
int turn=0;
int pstate=state;
int bitA = PINC & 0b00000010;
int bitB = PINC & 0b00000100;
bitA=bitA>>1;
bitB=bitB>>1;
state=bitA+bitB;
if((pstate==0&&state==1)||(pstate==1&&state==3)||(pstate==3&&state==2)||(pstate==2&&state==0))
{
turn=1;
}
if((state==0&&pstate==1)||(state==1&&pstate==3)||(state==3&&pstate==2)||(state==2&&pstate==0))
{
turn =-1;
}
if(mode)
{
low+=turn;//HERE
}
else
{
high+=turn;//HERE
}
high++;//test code, high is still not modified in the main()
change=1;//HERE
}

• Are you sure those if statements ever set the value of turn? Maybe put turn=1 right before the if(mode) and see what happens. – PeterJ Dec 5 '14 at 2:34
• I thought of that earlier, edited my original post. Thanks! – Noidontknow Dec 5 '14 at 2:36
• One other thing I spotted with your string buffers they probably should be larger and you might be overwriting those variables. Try changing the sizes from 5 to 7. – PeterJ Dec 5 '14 at 2:44
• The ints low and high are usually only two digits, three digits at max. – Noidontknow Dec 5 '14 at 2:49