No interrupt method works on ATMEGA328P

I am currently using Arduino Uno a smy developement board which has ATmega328P microcontroler on it with 16 MHz oscillator.
When I try to use any of interrupt methods the microcontroler restarts for no good reason (this even happen in simulation - I am currently running Atmel studio 7.0).

This is my code:

#define F_CPU 16000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <util/delay.h>

uint32_t time_ms;

ISR(TIMER0_COMPA_vect){
static uint32_t time_old = 0;
static uint8_t count = 0;
if(time_ms - time_old > 750){
time_old = time_ms;
count++;
}
if(count > 100){
count -= 100;
PORTB ^= PORTB;
}
time_ms++;
}

int main(void)
{
time_ms = 0;

DDRB = 0xFF; //set PORTB as output
PORTB = 0xFF; //turn all leds on PORTB on

TCCR0A = 1<<WGM01;
TCCR0B = (1<<CS00); // set timer to CTC mode and prescaler to 1 (no prescaler)
TCNT0 = 0; //reset timer
OCR0A = 160; //set TOP value for timer
// TIMSK0 = (1<<OCIE0A); //enable interrupt when timer reaches TOP value

sei(); //enable interrupts

   while (1)
   {
PORTB ^= 0b01010101; //toggle some leds on PORTB
_delay_ms(500);
PORTB ^= 0b10101010; //toggle some leds on PORTB
_delay_ms(500);
}
}

My question is. Why doesn’t interrupt work if I uncomment TIMSK0? Before I uncomment it, everything works as predicted, but when I when I do uncomment it, not even a while loop works. (This is both for simulation and when I program the chip)

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

jernejperko:
I am currently running Atmel studio 7.0).

This is a Forum for Arduino programming with the Arduini IDE.

What is your program supposed to do? Don’t expect people to see stuff like TCCR0A = 1<<WGM01; and know what it is for without referring to the Atmega 328 datasheet.

Is there any reason why you can’t achieve the results you want with the Arduino system?

Is there a Forum for Atmel Studio users?

…R

   TCCR0A = 1<<WGM01;
   TCCR0B = (1<<CS00);   // set timer to CTC mode and prescaler to 1 (no prescaler)
   TCNT0 = 0;   //reset timer
   OCR0A = 160;   //set TOP value for timer

Why are you setting TCNT0 and OCR0A after starting the timer?

I guess also you should use TCCR0A |= 1<<WGM01 instead of TCCR0A = 1<<WGM01 etc. unless you are really sure you are not going to overwrite something.

My question is. Why doesn’t interrupt work if I uncomment TIMSK0? Before I uncomment it, everything works as predicted, but when I when I do uncomment it, not even a while loop works.

I can not confirm your findings.

I ran your code, with no changes, on a UNO. I have an external led on pin 12 and the internal led on pin 13.

The led’s are blinking with the interrupt commented in or out. The pattern of blinks is not the same because of the additional toggling of the port within the interrupt. PORTB ^= PORTB

The blinks still alternate on the two leds, but the rhythm is different when the interrupt is enabled or not.

What are you expecting?

Thank you very much for your quick replies.

You just helped me a lot by stating what you did and that make think to further research where I get the problem from.

It might just be problem with my IDE so I will definitely try the same thing with arduino IDE.

Volatile?

uint32_t time_ms;

Riva: Volatile?

Not necessary. main accesses it before the timer is started and the access is redundant (it is already zero). Only data accessed by both an ISR and main (setup / loop) has to be volatile.

Making it static would be good.

Surely any global variable is accessed from the main program, it is initialized to zero. Thus it needs to be volatile or the initialization can be optimized away, leaving it undefined (crashing the ISR)?

Also if a variable is both read and written by an ISR you need to declare it volatile, so you have to anyway.

MarkT: Also if a variable is both read and written by an ISR you need to declare it volatile, so you have to anyway.

Only if the ISR is reentered, sharing the data with its second instance.

No, you forget that ISRs break the dataflow optimization of the compiler, so the compiler can gaily assume the ISR is never called (although declaring an ISR prevents it being optimized away completely).

When compiling the body of the ISR is can assume the ISR is never called again, and optimize away any DEFs that would be USEd by itself later.

volatile prevents any dataflow optimization of duplicate DEFs and unDEF'd USEs.

MarkT: Surely any global variable is accessed from the main program, it is initialized to zero. Thus it needs to be volatile or the initialization can be optimized away, leaving it undefined (crashing the ISR)?

I don't understand that or any of the rest of what you wrote.

In any case, there may be a single potential race condition that is easily eliminated by removing the explicit unnecessary initialization...

int main(void)
{
  // time_ms = 0;

  DDRB = 0xFF; //set PORTB as output