Interrupt can't set global variables

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I am running an Atmega8535, with the following code ( snippet ):

int NUMBER = 0;

ISR(TIMER0_COMP_vect)
{
// Place your code here
NUMBER++;
}

int main(void)
{
TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 ) | ( 1 << WGM01 ); //Timer clock = system clock / 1024, stop on OCR0
TIFR = ( 1 << TOV0 ) | ( 1 << OCF0 ); //Clear TOV0 / clear pending interrupts
TIMSK = ( 1 << OCIE0 ); //Enable Timer0
OCR0 = 0xF0;

USART_Init();

ADCSRA = (1 << ADEN);
ADMUX = ADREFSEL;

// Global enable interrupts
sei();

for(;;)
{
if( 0 != NUMBER )
{
USART_Transmit( 'x' );
NUMBER = 0;
}
}

USART code works fine, but NUMBER is never found != 0 so 'x' char will never be transmitted. If I issue USART_Transmit from ISR(TIMER0_COMP_vect), the char is transmitted. Are there any problems with accessing global variables from ISR? I am using windows xp, WinAVR-20100110.

Thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is a problem until you put the keyword VOLATILE in front of your int NUMBER; declaration.

Have a look at VOLATILE in your compiler documentation...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try

volatile int number=0;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is due to the compiler. You have to declare the NUMBER variable as volatile:
http://www.nongnu.org/avr-libc/u...

Also you have to deal with non-atomic operations correctly:
http://www.nongnu.org/avr-libc/u...

(I think there's a better guide on avrfreaks somewhere...)

/Jakob Selbing

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Suggest you read the article I wrote called "Optimization and the importance of volatile in GCC" in the Tutorial Forum.