ATMega1281 Timer3 Compare Match ISR - doesn't work

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

I've got an ATMega1281V, running at 4 mhz off the internal RC clock. I'm using 16 bit timers 1 and 3, both set identically to give a compare match A interrupt at 1000 hz. Both run correctly in the simulator. timer1's compare match interrupt fires properly on actual hardware, timer3's does not, however, I can verify that timer3 is actually running, just not interrupt. I can also verify the actual register settings are correct.

Anybody experienced anything like this? I would suspect a bug in the silicon, but I'm hoping it isn't.

Before anyone asks, I did do a forum search, and everyone else's timer3's seem to work after they got their registers set correctly.

Thanks in advance!

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

Some confusion - is failure to work in a real processor or in the simulator?

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

double checked that the interrupt enable and interrupt flag bits are set properly? (simulator should simulate this properly but worth checking again)

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

Quote:
I would suspect a bug in the silicon

So you suspect that, in the 2 1/2 years that this chip has been on the market that no one else has tried timer 3 in CTC mode? We hear this all the time - "there is a problem in the silicon" or "there is a problem in the compiler". All but the rarest of times the problem is with the code or external hardware.

Regards,
Steve A.

The Board helps those that help themselves.

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

Both set identically huh? Post the code. We'll check if the settings are identical.

Imagecraft compiler user

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

I'd say post your code, sometimes you won't see an error in your code even after pouring over it again and again. But someone else will spot it right away...just one of those peculiarities of programming.

- Rob

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

I use timer 3 in my ATmega2560 in this mode all the time - no problem.

Post your setup code.

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Believe me, I sympathize with the skepticism, and no, I don't *really* think its a bug in the silicon. At this point I'm starting to suspect damage to my chip, but I just ran the test on two identical boards with the same results.

Also to clarify, everything works fine in the simulator, the actual hardware is where I have the problem. I ran my tests on the simulator and hardware just before posting this.

Setup code for timer1:

void init_timer_1( void ){
	// compare match timing:
	// 4,000,000 / 8 = 500,000
	// 500,000 / 500 = 1000 hz.
	OCR1A = 499;
	
	TCCR1A = 0b00000000;
	TCCR1B = 0b00001010; // clear timer on compare match, prescaler / 8
	TCCR1C = 0;
	
	TIMSK1 = 0b00000010; // compare match A interrupt enabled
}

setup code for timer3:


void init_timer_3( void ){
	// compare match timing:
	// 4,000,000 / 8 = 500,000
	// 500,000 / 500 = 1000 hz.
	OCR3A = 499;
	
	TCCR3A = 0b00000000;
	TCCR3B = 0b00001010; // clear timer on compare match, prescaler / 8
	TCCR3C = 0;
	
	TIMSK3 = 0b00000010; // compare match A interrupt enabled
}

Yes, the timer3 code was written by copying and pasting the timer1 code.

Again, I can tell that timer3 is actually running by polling the TCNT3 register, but no interrupt is fired. I check the interrupts by having them send a character out the uart when they fire.

Also, timer4 and timer5 also exhibit the same problem.

If worse comes to worse, I can get by just using timer1, it was just more convenient to have several.

Thanks!
bluefire211

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

I would test each timer separately, with least amount of code needed, like-

#include 
#include 
#include 
ISR(TIMER3_COMPA_vect){
    PINE|=(1<<PE1); //toggle
}
int main( void ){
    MCUSR=0;
    wdt_disable();
    PORTE=(1<<PE1); //txd0
    OCR3AL=207; //2400 baud
    TCCR3B = (1<<WGM32)|(2<<CS30); //ctc, div8  
    TIMSK3 = (1<<OCIE3A); //compa irq
    sei();
    while(1);
}

you can leave usart connection hooked up, should get 'U' spitting out at 2400 baud (I think).

If it works, time to look at your original code. If it doesn't work, then more investigating needed.

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

Check the TIFR3 register OCF3A interrupt flag. If this flag gets set and there is still no interrupt, then look at the SREG register I bit to make sure global interrupts are still enabled. You can disable the TIMSK3 register OCIE3A bit to isolate the OCF3A interrupt flag and prevent an interrupt response from clearing OCF3A (just for verifying if OCF3A is being set or not). If global interrupts are set and there is still no interrupt, then look at the generated assembly output for TIMER3 COMPA interrupt vector (vector 33 decimal 0x0040). Maybe there is a compiler error with this interrupt name or something strange. Look for any errors in the actual interrupt code that might hide that it is running, in case the interrupt is really running and you are just not aware of it.