ATMEGA64 TIMSK issue

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

Dear all,

I found some problem on ATMEGA64, first I'm using only timer0 in output compare mode to make a system basetime every thing work perfectly.

// Base timer using timer0
TCCR0 = (1<<WGM01)|(1<<CS02);                                 	
OCR0  = BASETIME;
TIFR  = (1<<OCF0);         			
TIMSK = (1<<OCIE0);

Next step I'm trying to use Timer1 in input capture mode and add code below.

// Base timer using timer0
TCCR0 = (1<<WGM01)|(1<<CS02);                                 	
OCR0  = BASETIME;
TIFR  = (1<<OCF0);         			
TIMSK = (1<<OCIE0);

// Timer1 input capture 
TCCR1B |= (1<<ICNC1);			
TCNT1  = 0;				
OCR1A  = MAX_DATA_LENGHT;                    
TCCR1B |= (1<<CS10);			
TIMSK  |= ((1<<TICIE1)|(1<<TOIE1)|(1<<OCIE1A));  

My system not work after add above code. So, I'm trying to find the cause of this issue.

//TIMSK  |= ((1<<TICIE1)|(1<<TOIE1)|(1<<OCIE1A));

After I cut above line from my code, my system is work perfectly again.

Has anyone ever found like this issue ? How to solve ?

For more in formation my system are use INT0, SPI, USART0, Watchdog module.

Regards,

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

See the current ATmega64 version 2490N-AVR-05/08 data sheet page 4 section: ATmega103 and ATmega64 Compatibility. Next see page 5 ATmega103 Compatibility Mode. Then page 291 Table 117 Extended Fuse Byte. Your ATmega64 acts like an ATmega103 unless you unprogram the M103C fuse.

The M103C fuse is factory programmed. Did you unprogram the M103C fuse?

Also see page 306 SPI Serial Programming Pin Mapping. The MOSI and MISO pins are mapped to PDI and PDO.

You didn't say which C compiler you are using. Did you create the interrupt service vectors for the timer/counter1 ICP, timer/counter1 overflow and timer/counter1 output compare A? If not your program will crash if these interrupt vectors are executed after you enable them. Did you clear the TIFR register ICF1, OCF1A or TOV1 interrupt flags before enabling these interrupts (in case they might have been previously set). The ICF1 is the most likely to have already have its interrupt flag set before the enable.

See this thread for some input capture with overflow enabled information:
https://www.avrfreaks.net/index.p...

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

Mike B,

Thank you for your help. I'm just found the cause of this issue. This problem come from no ISRs add in my code. It work perfectly after I add the related ISRs. I'm using GCC. Is this a bug of GCC ?

Regards,

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

When the AVR hardware has an enabled interrupt triggered, it automatically jumps to the interrupt vector program location. If you do not put the jump address of the actual interrupt response code in the interrupt vector table, then the interrupt causes the AVR to execute garbage instead of valid program code.

In GCC, it automatically fills in any interrupt vector that you do not use with the jump address of an interrupt handler called BADISR_vect. The GCC documentation tells you what this does. So, its not a bug at all. Its a problem with your program telling the AVR to something it shouldn't do, but GCC puts in backup code to prevent random crash behavior ad controls the crash instead. If you use JTAGICE or debugWire you may insert:

ISR (BADISR_vect) {
    // your code goes here
}

in your program and breakpoint on the BADISR_vect. You never should execute the BADISR_vect and if a breakpoint finds you have then you have a bug to track down. Your program bug might be an unused interrupt that was accidentally enabled, a corrupted stack, a bad IJMP/ICALL Z register pair pointer value, etc. or anything that might crash your program.

For quick vector names reference there is an on line resource:
http://www.nongnu.org/avr-libc/u...

There are probably/possibly more up to date references elsewhere.